Perl format Primer (2/2) | WebReference

Perl format Primer (2/2)

current pageTo page 2
[previous]

Perl format Primer

Internal Variables

The previous discussion of format focused almost entirely on the use of user-defined variables and values within template definitions, but Perl also provides several internal variables that can be used either directly within your templates or for the manipulation of the format assignments themselves. Key internal variables to be used in conjunction with format include the following (long form versions of the variable names are those that can be utilized when you are using the English module):

VariableLong FormDefinition
$%$FORMAT_PAGE_NUMBERCurrent page number
$=$FORMAT_LINES_PER_PAGELines per page
$-$FORMAT_LINES_LEFTLines remaining on the current page
$:$FORMAT_LINE_BREAK_CHARACTERSFormat line break characters
$^L$FORMAT_FORMFEEDThe form feed character
$~$FORMAT_NAMEFormat name
$^$FORMAT_TOP_NAMEPage header

The attentive among you may have already noticed that we snuck in one of these variables when we defined a page header earlier:

format MYFILE_TOP = 
Employee Names and Salaries                      Page: @>>>>>>>>>>
                                                       $%
------------------------------------------------------------------
.

By using the $% internal variable, we'll automatically get page numbers printed in our page headers.

The other internal variables are available to allow you to manipulate the results when you output your format templates. Lines per page, for example, can be set, allowing you to reduce the number of lines printed on each page of output:

$==24; # set currently selected file to 24 lines PP

The format name ($FORMAT_NAME) and page header name ($FORMAT_TOP_NAME) can also be directly set, allowing you to define formats with names differing from the file handle name and/or define multiple format definitions for a single file. Each filehandle that is defined within your program has its own set of $%, $=, $-, $~, $^, etc. variables; which begs the question: When you assign something to one of these variables directly, which filehandle is affected? The answer is the default output filehandle, which is STDOUT by default, but can be changed at any time via the select function:

# open up MYFILE for writing
open(MYFILE,">myfile.txt") or die "Can't open up myfile: $!\n";
my ($name,$salary);
format MYFORMAT = 
Name: @>>>>>>>>>>>>>>>>>>>>>>>>>>>>        Salary: @###########.##
      $name,                                       $salary
.
# select MYFILE and then set its default form name
select(MYFILE);
$~="MYFORMAT";

Now the MYFORMAT form is the default format for MYFILE. If you wish to define multiple formats to be assigned to the same filehandle (if you'll need to cycle through two or more different formats in the same output file, for example), it will be necessary to directly assign the appropriate form names before each write. A cleaner way to perform these assignments, however, is to use the FileHandle module:

use FileHandle;
my ($name,$salary);
format MYFORMAT = 
Name: @>>>>>>>>>>>>>>>>>>>>>>>>>>>>        Salary: @###########.##
      $name,                                       $salary
.
MYFILE->format_name("MYFORMAT");

Using FileHandle, you can assign each of the per-filehandle variables described above to a specific filehandle without having to directly select it first. As in the above example, you use the lowercase version of the long form of the variable names to do this, using either of these formats:

use FileHandle;
my ($name,$salary);
format MYFORMAT = 
Name: @>>>>>>>>>>>>>>>>>>>>>>>>>>>>        Salary: @###########.##
      $name,                                       $salary
.
# each of these will work:
MYFILE->format_name("MYFORMAT");
format_name MYFILE "MYFORMAT";

The same process holds true for the setting (or inquiring) of format_page_number, format_lines_per_page, format_top_name, etc.

write

We've alluded to the process of actually outputting the formatted data to the output file, but have not yet fully explained it. To output formatted data, you use the function write, which is reserved specifically for the outputting of formats and should therefore not be confused with print, or even syswrite, for that matter. write takes a single, optional parameter: the name of the filehandle to be written to. If the filehandle parameter is not included, then Perl assumes it should write to the currently selected default output file.

As you use the write statement, Perl automatically tracks the number of lines actually written to each output file (in $-) and, if one is specified, applies the page header form--along with the default page formfeed character (which is in $^L)--to the output file each time the number of lines per page (in $=) is exceeded. Thus, the resulting output should print gracefully (assuming you've properly set each of the mentioned variables to match the output medium you intend to display/print the report on) with a page header at the top of each new page. In the following example, assume we've earlier created a hash of employee salaries (%emp_salaries) that is keyed by employee name:

use FileHandle;
# open up MYFILE for writing (could also use FileHandle for this)
open(MYFILE,">myfile.txt") or die "Can't open up myfile: $!\n";
my ($name,$salary);
# now this line format will automatically apply to MYFILE
format MYFILE = 
Name: @>>>>>>>>>>>>>>>>>>>>>>>>>>>>        Salary: @###########.##
      $name,                                       $salary
.
# and this page header format will automatically apply to MYFILE
format MYFILE_TOP = 
Employee Names and Salaries                      Page: @>>>>>>>>>>
                                                       $%
------------------------------------------------------------------
.
MYFILE->format_lines_per_page(40); # 40 lines per page for MYFILE
foreach my $key (sort(keys(%emp_salaries))) {
   $name=$key;
   $salary=$emp_salaries{$key};
   write MYFILE;
}

And that's that! As is the case with many things Perl, having properly setup your data and reporting formats the actual reporting magic is as simple as executing a single statement.

For Further Study

The above tutorial does a respectable job of covering the Perl format and write functions in Perl, but as is often the case with beginning tutorials, some pieces of information were left out in order to keep the concepts as clear as possible. In no particular order, here are some format related subjects that you may wish to play around with on your own:

Literal values in picture lines

You can place a literal value that the interpreter would otherwise assume was a field definition into a format picture line as follows:

format MYFILE = 
@>>>>>>>>>>>>>>>>>>>>>>> @Work: @<<<<<<<<<<<<<<<<<<<<<<
$name,                  "@",    $work_phone
.

Or, in other words, since expressions can be used to supply values for picture lines, then the expression can also be a literal value itself.

Direct access to formatted strings

You can access directly the formatted output that would be sent to the output file on write by using the Perl formline function. formline allows you to specify both the picture and the values to be used within the picture within the same statement:

formline PICTURE, VALUES

where the VALUES parameter is a Perl LIST value. After formline executes, you can access the resulting formatted output in the internal variable $^A.

Conclusion

Whether they be basic printed reports or the production of aggregated, fixed record length data files, the Perl format facilities can simplify your data output needs. Using the information presented in this brief tutorial you can create report line and header templates, and write out formatted data to one or multiple file handles, each with differing layouts and characteristics. Good luck in your own formatting endeavors!


current pageTo page 2
[previous]

Created: December 1, 2005
Revised: December 9, 2005

URL: http://webreference.com/programming/perl/format/2.html