The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
  • Introduced $index as one of the variables specified in fields.XXX.data, imported into the main package and used as metadata inside the Data::Presenter object. This eliminates some hard-coding inside subroutines _init() and _extract_rows() inside Data::Presenter::[subclass] packages. It also necessitated a revision of _build_sort_formula(), a large part of which was extricated into the separate subroutine _formula_engine(). This for the first time permitted on index keys which were not entirely numerical. So now one can sort on, say, product serial numbers such as '24TY-789'.

  • Established a package global hash %reserved within Data::Presenter.pm and %reserved_partial within Data::Presenter::Combo::Intersect.pm and Data::Presenter::Combo::Union.pm. These are hashes of words such as 'fields', 'parameters', 'index' and 'options' which are reserved for current or future use as keys in the hash blessed into the Data::Presenter object. These keys generally have to be excluded when preparing Data::Presenter selection, sorting and output methods. The coding for this exclusion is must easier if one can write:

        unless $reserved{$i} {
        # do something
        }

    in contrast to the earlier:

        unless ($i eq 'fields' || $i eq 'parameters') {
        # do something
        }
  • _format_picture_line() and writeHTML() now format numerical columns flush-right.

  • A bug was fixed in _build_sort_formula() that was causing 'HERNANDEZ' to precede 'HERNAN' in alphabetical sorts. This was caused by the internal use of '|' as the delimiter between array entries. '|' has a higher ASCII position than any alphabetical or numerical character. Hence 'HERNANDEZ|' has a lower sorting value position than 'HERNAN|'. This has been corrected by substituting '!' as the delimiter, since '!' has a lower ASCII value than any alphabetical or numerical character. One side effect is that the character '!' may not appear in data being input into Data::Presenter objects.

  • Clarified error messages in _validate_fields() and _analyze_relation().

  • Up through v0.31, if the operator were to call writeformat(), writeformat_plus_header() or any combination thereof more than once in a particular Perl script and if in so doing the operator used any of the entries in @fields more than once as an element in @columns_selected, then a warning would have been printed to STDERR stating:

        Variable "[$some_variable]" is not imported at
        (eval 2 [or higher number]) line [some_line_number].

    To illustrate using the previously discussed examples:

        @columns_selected = ('lastname', 'firstname', 'datebirth', 'cno');
        $sorted_data = $dp1->sort_by_column(\@columns_selected);
        $outputfile = 'format01.txt';
        $dp1->writeformat($sorted_data, \@columns_selected, $outputfile);
    
        @columns_selected =
        ('lastname', 'firstname', 'dateadmission', 'cno');
        $sorted_data = $dp1->sort_by_column(\@columns_selected);
        $outputfile = 'format01.txt';
        $dp1->writeformat($sorted_data, \@columns_selected, $outputfile);

    would have generated warnings resembling these:

        Variable "$lastname" is not imported at (eval 2) line 10.
        Variable "$firstname" is not imported at (eval 2) line 10.
        Variable "$cno" is not imported at (eval 2) line 10.

    The author had run the program on live data many times and these warnings were never indicators of any incorrect output. This warning message is discussed in perldoc perldiag and on page 975 of Camel at 'Variable ''%s'' is not imported%s'. That discussion implies that this warning would not have appeared if use strict were not in effect. However, the author tested this by calling no strict before writeformat() and returning to use strict therefafter. The warnings continued to be thrown.

    The author then ventured to post the problematic code on comp.lang.perl.misc and had his hand properly slapped for improper use of symbolic references. In the course of the slapping, the slapper, Mark-Jason Dominus, suggested using the Perl formline function and format accumulator variable $^A -- which internally power Perl formats -- instead of formats per se. At the same time, MJD discovered a bug in Perl 5.6 which was enabling the author to get valid data out of writeformat() despite improper use of symbolic references. MJD subsequently reported to the author that the bug was patched, but since formline was working well and throwing no warning messages, he left well enough alone. This turned out to be providential, as the $^A was later to play a key role in the creation of writeformat_with_reprocessing().

  • In v0.33 two errors in the specification of %ne within _analyze_relation() were corrected.

  • Output method print_with_delimiter() was added in v0.34 to permit the operator to select the delimiter characters used when printing to file. This method is designed to be used in situations where the operator intends to further manipulate the data with a word processor function such as 'Convert text to tabs'.

  • Method get_keys() was added in v0.35 to permit operator to get an ASCII-betically sorted list of the indices of the data records currently stored in the Data::Presenter::[Package1] object.

  • In v0.36 code which was common to both print_to_screen() and print_to_file() was abstracted and placed in an internal subroutine called _print_engine.

  • writeformat_with_reprocessing() was introduced in v0.38. This format uses uses CPAN module List::Compare. In order to extend the applicability of _validate_args to cover writeformat_with_reprocessing(), it was modified so as to receive an additional argument, a reference to package variable %fp. As _format_argument_line() is no longer used within <writeformat()> or writeformat_plus_header(), it was deleted. The superfluous and potentially confusing <LINK> tag is removed from writeHTML().

  • Prior to v0.39 _format_picture_line() was being called with each iteration of the 'foreach' loop over the output records. As this was unnecessary, it was pulled out of that loop. The requirement that the title line in writeformat_plus_header() and writeHTML() be preceded by the words ''Selected fields from: '' has been dropped.

  • v0.40: In preparation for an eventual release to CPAN, the module was renamed Data::Presenter.

  • v0.41: Running Data::Presenter on Perl 5.8 for the first time, received warnings in full_report() and print_with_sep(). Fixed sigils.

  • v0.42: In many of the format-related subroutines, I was passing @args as an array. Changed this so that I was passing by reference, which meant that in certain cases I could eliminate @args as a variable inside a subroutine. (However, in other cases it was retained inside the subroutine for clarity.)

  • v0.43 (1/22/03): Corrected a typo in _analyze_relation() which was causing incorrect results when $relation = '='>.

  • v0.44 (2/9/03): Tightened up coding in get_data_count(), print_data_count() and _count_engine().

  • v0.45 thru v0.47 (2/19-21/03): Introduced and refined writeformat_deluxe() to permit both a format header and dynamic reprocessing of fields (columns). As this shared repeated code with writeformat_with_reprocessing(), extracted redundant code and placed it in _prepare_to_reprocess() and _prepare_substring_data_and_picline(). Also, spotted an error in writeformat_with_reprocessing(): $lc a 2nd time where I should have called $lc1.

  • v0.48 (2/22/03): Combined _prepare_to_reprocess() and _prepare_substring_data_and_picline() into _prepare_to_reprocess().

  • v0.49 (2/22/03): Used map {$_ => 1} LIST to populate hashes such as %reserved rather than assigning => 1 for each individual key.

  • v0.50 (2/23/03): Corrected writeHTML() to use _format_argument_line_top2 and _format_hyphen_line_2.

  • v0.51 (2/24/03): Made changes in writeformat_with_reprocessing(), writeformat_deluxe(), _prepare_to_reprocess(), Data::Presenter::_Assorted::_reprocessor() and Data::Presenter::_Assorted::reprocess_timeslot() to accommodate correct output of times for those groups that start later in the timeslot, e.g., a 10:45 start for certain Ward 10 and 11 groups in the second timeslot of the day.

  • v0.52 (3/3/03): Began working on subroutines which, like the writeformat...() family of subroutines, will dynamically output data from selected fields (columns) in the database, but with the fields separated by an operator-supplied delimiter. (The delimiter will frequently be \t to take advantage of word processing program features which convert tab-delimited copy to tables.) So far I have created writedelimited() and writedelimited_plus_header() and, for internal use within the latter, _format_argument_line_top3. Also, eliminated my $LR = $lc->is_LsubsetR; from _prepare_to_reprocess, as $LR is not used anywhere.

  • v0.53 & v0.54 (3/6/03): Continued work on the writedelimited...() family of subroutines, adding writedelimited_with_reprocessing() and other subroutines needed in the Data::Presenter::[package1]() invoking subclass. In a manner similar to writeformat_with_reprocessing(), writedelimited_with_reprocessing() enables the operator to do 'just-in-time' reprocessing of the data elements which will be joined by $delimiter in output.

  • v0.55 (3/6/03): Continued work on the writedelimited...() family of subroutines, adding writedelimited_deluxe(). In a manner similar to writeformat_deluxe(), writedelimited_deluxe() enables the operator to provide column headers and do 'just-in-time' reprocessing of the data elements which will be joined by <$delimiter> in output. Unlike writeformat_deluxe(), however, writedelimited_deluxe() is meant to provide input to a word processing program's 'convert text to table' feature, in which case a title line would be superfluous. Hence writedelimited_deluxe() does not take $title_raw as an argument.

  • v0.56 (3/7/03): Provided documentation for writedelimited...() family of subroutines.

  • v0.57 (3/15/03): Corrected error in header of writeHTML(). Included a carp warning in new() to warn the operator if, after initialization, the Data::Presenter::[package1] object contains zero elements (other than metadata). Similarly modified _count_engine() to return 0 in same situation.

  • v0.58 (3/26/03): Clarified the error message in _validate_args() to indicate which arguments passed to sort_by_column() are invalid.

  • v0.60 (4/6/03): Preparation for distribution to CPAN.

  • v0.61 (4/12/03): Corrected failure to list Data::Presenter::Combo in MANIFEST.

  • v0.63 (8/24/03): Created seen_one_column().

  • v0.64 (10/5/03): Created get_keys_seen().

  • v0.65 (6/2/04): Corrected 1 line of code in each of Intersect.pm and Union.pm which was generating error "Bizarre copy of array" when testing under Perl 5.8.4 on Darwin.

  • v0.66 (6/9/04): POD correction only: Corrected error in POD for Data::Presenter::Sample Medinsure which resulted in bad POD-to-HTML translation and bad display on search.cpan.org

  • v0.67 (10/23/04): Corrected substandard code at +322 Presenter.pm to avoid error "Bizarre copy of hash in leave" error when running tests under Devel::Cover

  • v0.68 (10/23/04): Corrected substandard code at +1005 Presenter.pm to avoid error "Bizarre copy of array" error when running tests under Devel::Cover

Possible future lines of development include:

  • writeHTML() could be rewritten or supplemented by a method which writes a true HTML table.

  • And if we were really au courant, we'd have a writeXML() method!

  • The hashes defined within _analyze_relation() which offer the operator flexibility in defining $relation could be expanded to include expressions in any human language using the ASCII character set.

  • Develop a Perl::TK GUI to make it easier for operators to build and run Data::Presenter scripts.

  • Add an additional, optional element to the arrays on the value side of %parameters: the name of a subroutine used by the administrator to massage the data entering through a given field. It is not clear yet how this would work with a Data::Presenter::Combo object.