⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch11.htm

📁 prrl 5 programs codes in the book
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<BLOCKQUOTE>

<B>Listing 11.6&nbsp;&nbsp;11LIST05.PL-Using a FuNCtion with a

Value Line<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

format =

  @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;  @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;  $@##.##

  dotize(17, $album), dotize(16, $artist), $price

.



format STDOUT_TOP =

  @||||||||||||||||||||||||||||||||||||  Pg @&lt;

  &quot;CD Collection of David Medinets&quot;,        $%



  Album              Artist            Price

  -----------------  ----------------  -------

.



sub dotize {

    my($width, $string) = @_;



    if (length($string) &gt; $width) {

        return(substr($string, 0, $width - 3) . &quot;...&quot;);

    }

    else {

        return($string);

    }

}



open(FILE, &quot;&lt;format.dat&quot;);

@lines = &lt;FILE&gt;;

close(FILE);



foreach (@lines) {

    chop();

    ($album, $artist, $price) = (split(/!/));

    $album  = &quot;&quot; if !defined($album);

    $artist = &quot;&quot; if !defined($artist);

    $price  = 0 if !defined($price);

    write();

}

</PRE>

</BLOCKQUOTE>

<HR>

<P>

This program displays the following:

<BLOCKQUOTE>

<PRE>

      CD Collection of David Medinets     Pg 1



  Album              Artist            Price

  -----------------  ----------------  -------

  The Lion King                        $  0.00

  Tumbleweed Con...  Elton John        $123.32

  Photographs &amp; ...  Jim Croce         $  4.95

  Heads &amp; Tales      Harry Chapin      $ 12.50

</PRE>

</BLOCKQUOTE>

<P>

The second and third detail lines have benefited from the dotize()

fuNCtion. You can use a similar technique to invoke any fuNCtion

in the value line. You also can use expressions directly in the

value line, but it might be harder to maintain because the intent

of the expression might not be clear.

<H3><A NAME="ExampleChangingFormats">

Example: Changing Formats</A></H3>

<P>

So far, you've seen only how to use a single format statement

per report. If Perl could handle only one format per report, it

wouldn't have much utility as a reporting tool. Fortunately, by

using the <TT>$~</TT> special variable,

you can control which format is used for any given <TT>write()</TT>

fuNCtion call. Listing 11.7 shows a program that tracks the price

of the CDs in the collection and displays the total using an alternate

<TT>format</TT> statement.

<P>

<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>

<BLOCKQUOTE>

<I>Declare a format for the </I><TT><I>STDOUT</I></TT><I>

file handle.<BR>

Declare a format for the total price information.<BR>

Declare a heading format for the </I><TT><I>STDOUT</I></TT><I>

file handle.<BR>

Declare the </I><TT><I>dotize()</I></TT><I>

fuNCtion.<BR>

Initialize local variables called </I><TT><I>$width</I></TT><I>

and </I><TT><I>$string</I></TT><I>.

<BR>

If the width of </I><TT><I>$string</I></TT><I>

is greater than </I><TT><I>$width</I></TT><I>,

return a value that consists of </I><TT><I>$string</I></TT><I>

shortened to </I><TT><I>$width-3</I></TT><I>

with </I><TT><I>...</I></TT><I> appended

to the end; otherwise, return </I><TT><I>$string</I></TT><I>.

<BR>

Open the </I><TT><I>FORMAT.DAT</I></TT><I>

file, read all the lines into </I><TT><I>@lines</I></TT><I>,

and then close the file.<BR>

Initialize the </I><TT><I>$total</I></TT><I>

variable to zero.<BR>

Iterate over the </I><TT><I>@lines</I></TT><I>

array.<BR>

Remove the linefeed character.<BR>

Split the string into three fields.<BR>

Provide a default value for any empty variables.<BR>

Invoke the </I><TT><I>format</I></TT><I>

statement by using the </I><TT><I>write()</I></TT><I>

fuNCtion.<BR>

Change the current format by assigning a value to the </I><TT><I>$~</I></TT><I>

special variable.<BR>

Invoke the </I><TT><I>format</I></TT><I>

statement by using the </I><TT><I>write()</I></TT><I>

fuNCtion.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 11.7&nbsp;&nbsp;11LST07.PL-Using an Alternative <I>format</I>

Statement<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

format =

  @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;  @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;  $@###.##

  dotize(17, $album), dotize(16, $artist), $price

.



format STDOUT_TOTAL =

  ---------------------------------------------

                                       $@###.##

                                        $total

.



format STDOUT_TOP =

  @||||||||||||||||||||||||||||||||||||  Pg @&lt;

  &quot;CD Collection of David Medinets&quot;,        $%



  Album              Artist            Price

  -----------------  ----------------  --------

.



sub dotize {

    my($width, $string) = @_;



    if (length($string) &gt; $width) {

        return(substr($string, 0, $width - 3) . &quot;...&quot;);

    }

    else {

        return($string);

    }

}



open(FILE, &quot;&lt;format.dat&quot;);

@lines = &lt;FILE&gt;;

close(FILE);



$total = 0;

foreach (@lines) {

    chop();

    ($album, $artist, $price) = (split(/!/));

    $album  = &quot;&quot; if !defined($album);

    $artist = &quot;&quot; if !defined($artist);

    $price  = 0 if !defined($price);

    write();

    $total += $price;

}



$~ = &quot;STDOUT_TOTAL&quot;;

write();

</PRE>

</BLOCKQUOTE>

<HR>

<P>

This program displays the following:

<BLOCKQUOTE>

<PRE>

    CD Collection of David Medinets     Pg 1



  Album              Artist            Price

  -----------------  ----------------  --------

  The Lion King                        $   0.00

  Tumbleweed Con...  Elton John        $ 123.32

  Photographs &amp; ...  Jim Croce         $   4.95

  Heads &amp; Tales      Harry Chapin      $  12.50

  ---------------------------------------------

                                       $ 140.77

</PRE>

</BLOCKQUOTE>

<P>

This example shows you how to keep a running total and how to

switch to an alternative detail line format. If you need to switch

to an alternative heading format, assign the new header format

name to the <TT>$^</TT> special variable.

<H3><A NAME="ExampleUsingLongPiecesofTextinReports">

Example: Using Long Pieces of Text in Reports</A></H3>

<P>

By using the <TT>^</TT>, <TT>~</TT>,

and <TT>~~</TT> formatting characters

in your <TT>format</TT> statements,

you can use long pieces of text in a report: for example, the

first paragraph of a paper's abstract or some notes associated

with a database record. Listing 11.8 shows a program that prints

the definition of a word. The definition is too long to fit in

one column, so the <TT>^</TT> formatting

character is used to split the text onto multiple lines.

<P>

<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>

<BLOCKQUOTE>

<I>Declare a format for the </I><TT><I>STDOUT</I></TT><I>

file handle. The field and value lines are repeated enough times

to print the entire length of the expected output.<BR>

Initialize the </I><TT><I>$word</I></TT><I>

and </I><TT><I>$definition</I></TT><I>

variables. The </I><TT><I>$definition</I></TT><I>

variable is initialized by using coNCatenated strings to avoid

line breaks caused by the book printing process.<BR>

A line of asterisks is printed.<BR>

The format is invoked.<BR>

Another line of asterisks is printed.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 11.8&nbsp;&nbsp;11LST08.PL-Using the <I>^</I> Formatting

Character to Print Long Text Values<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

format =

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

  $word,    $definition

.



$word = &quot;outlier&quot;;



$definition = &quot;1. someone sleeping outdoors. &quot; .

    &quot;2. someone whose office is not at home. &quot; .

    &quot;3. an animal who strays from the fold. &quot; .

    &quot;4. something that has been separated from the main body.&quot;;



print(&quot;****************\n&quot;);

write();

print(&quot;****************\n&quot;);

</PRE>

</BLOCKQUOTE>

<HR>

<P>

This program displays the following:

<BLOCKQUOTE>

<PRE>

****************

  outlier   1. someone sleeping outdoors. 2.

            someone whose office is not at

            home. 3. an animal who strays from

            the fold. 4. something that has

            been separated from the main body.



****************

</PRE>

</BLOCKQUOTE>

<P>

The <TT>^</TT> formatting character

causes Perl to do word-wrapping on the specified variable. <I>Word-wrapping</I>

means that Perl will accumulate words into a temporary buffer,

stopping when the next word will cause the length of the accumulated

string to exceed the length of the field. The accumulated string

is iNCorporated into the report, and the accumulated words are

removed from the variable. Therefore, the next time Perl looks

at the variable, it can start accumulating words that have not

been used yet.<BR>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD><B>Note</B></TD></TR>

<TR><TD>

<BLOCKQUOTE>

Any linefeed characters in the variable are ignored when the <TT>^</TT> formatting character is used in the <TT>format</TT> statement.

</BLOCKQUOTE>



</TD></TR>

</TABLE>

</CENTER>

<P>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD><B>Caution</B></TD></TR>

<TR><TD>

<BLOCKQUOTE>

Because the value of the variable used in the value line changes when word-wrapping is being used, make sure to use only copies of variables in the <TT>format</TT> statement. By using copies of the variables, you'll still have the original value available 
for further processing.

</BLOCKQUOTE>



</TD></TR>

</TABLE>

</CENTER>

<P>

<P>

The asterisks in the preceding example were printed to show that

a blank line was printed by the format. This was caused because

the <TT>$definition</TT> variable

ran out of words before the format ran out of space. Extra blank

lines can be eliminated by placing the ~ character somewhere-usually

at the beginning or end-of the field line. The format statement

then would look like this:

<BLOCKQUOTE>

<PRE>

format =

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ~

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ~

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ~

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ~

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ~

  $word,    $definition

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ~

  $word,    $definition

.

</PRE>

</BLOCKQUOTE>

<P>

The new report would not have a blank line.

<BLOCKQUOTE>

<PRE>

****************

  outlier   1. someone sleeping outdoors. 2.

            someone whose office is not at

            home. 3. an animal who strays from

            the fold. 4. something that has

            been separated from the main body.

****************

</PRE>

</BLOCKQUOTE>

<P>

It is rather wasteful to have to repeat the field lines often

enough to account for the longest possible length of <TT>$definition</TT>.

In fact, if you are reading the definitions from a file, you might

not know how long the definitions could be ahead of time. Perl

provides the ~~ character sequeNCe to handle situations like this.

By placing ~~ on the field line, Perl will repeat the field line

as often as needed until a blank line would be printed. Using

this technique would change the <TT>format</TT>

statement to this:

<BLOCKQUOTE>

<PRE>

format =

  ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ~~

  $word,    $definition

</PRE>

</BLOCKQUOTE>

<P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -