Provided by: manpages-zh_1.5.2-1.1_all bug

NAME

       perlform - Perl 格式

DESCRIPTION 描述

       Perl的一些內部機制、可以幫助我們產生一份簡單的格式化圖表。經過perl的處理,你列印的格式可以
       接近於你所見的外貌。它可以記錄如你現在正處在哪個頁面,每個頁面的行數與何時列印出頁面的標
       題。關鍵字,format() 格式函數與write()執行函數是直接引自FORTRAN語法。詳情可參閱
       perlfunc。幸運的是列印的格式可讀性又有所提高。幾乎類似BASIC 的PRINT USING。可以把它想像為
       簡單的 nroff(1).

       有如子程式與包一樣,格式只是語句的聲明,而不是執行調用。故它可以放在程式的任何位置(一般最
       好是把它們集中在一塊)。與perl的其它變量名字類型不同, 格式命名有別於一般的獨自的定義。也
       就是說,你有一個名為Foo的函數,它與另一個格式名稱為Foo的東西是完全不同。但是預設的格式名稱
       與有關連的檔案句柄可用相同的名字。所以預設的輸出格式名稱STDOUT,它的檔案句柄名稱就
       是STDOUT。而對預設格式名稱TEMP,它的檔案句柄名稱也可以是TEMP。雖然名稱一樣但兩者並不相同。

       輸出格式的語法如下:

           format NAME =
           FORMLIST
           .

       如省略格式名稱,格式名稱將以標準輸出STDOUT命名。而格式項目將包括了好幾個連續橫行。每一行屬
       於下列三種型態之一:

       1.  注釋(comment), 以符號「#」置於每行的開頭。

       2.  圖案行(picture line),規定了單一行的格式化外觀。

       3.  參數行, 提供一些數值以對應前面的圖案行。

       圖案行的輸出效果就與我們看到的一樣,除了某些值域欄位會給相對應數值取代外,每個輸入欄位都以
       一個@或 ^ 控制符開頭。這些單行內的控制符不能做任何竄改取代(勿與數組變量@混淆)。@欄位是屬於
       正常形態的欄位,而^欄位則用來表示可以輸入多行文字。至於該欄位則由<  > 或 ⎪ 符號跟隨其後指
       定向左、右、或居中對齊。並同時跟據該符號的數目,輸入指定資料的長度。如變量內容超過限定長
       度、格式列印時會自動刪除多餘的部份。

       另一種指定向右對齊方式,是使用#符號來指定一個數字欄位。如此可方便小數點定位。如果輸入值裏
       還包含一個換行字元(0,則僅列印出該換行字元前的資料。最後圖案行出現的@*這個特別符號標記,可
       以用來列印多行並且不被截掉的數值。

       接下來的一行、是跟據圖案行裏的值域欄位輸入相應的數值。如果是利用運算式提供數值的話、必須以
       逗號分隔。因為所有的表示法都會被當成一個串連內容再行處理。所以一個單一的串列表示法也可產生
       多個串列資料。如果表示法是利用括號圍起,可能會展開好幾行。若想如是安排,第一行的第一個單字
       必須是以左括號開始。如果運算式內有小數點的數字類型須要處理、同時圖案行的相關符號也指出小數
       位須列印出來(除了圖案行內的包含小數點"."的數字控制符號#外)。小數點列印出的外貌, 以當地的運
       行版本決定(LC_NUMERIC locale)。也就是說、在德文地區使用小數格示輸出時、小數點的顯示將
       是","而非"."。相關資料請參考 perllocale 與 "警告"

       圖案行裏的欄位如果以^控制符開頭、格式將會作特殊化處理。如果該欄位是注解欄位又沒定義其
       值、欄位將以空白取代。若是其它型態、則視為一種填補資料的狀態。 在此、我們不能隨便填入任意
       表示法進去。相反、必須以相關的變量輸入字串內容。perl會盡量將文字放入該欄位、然後把字串的前
       面部份刪去。當你下次使用該字串變量時、可以使用後面的字串部份(換句話說、在執行write函數
       時、字串變量的內容是會改變的)。正常情況下、你必須使用一類似垂直狀的堆塊來放置要輸入的文
       字、以便整齊列印出一柱狀文字。如你列印的文字太長、想以"..."取代過長的文字時、你可以藉由更
       改 $: 變量值來取代分隔字元。也就是當你使用ENGLISH模塊時的 $FORMAT_LINE_BREAK_CHARACTERS的
       意思。

       使用^符號欄位可產生不定長度的記錄欄位。如果要列印的文字很短、你想壓縮掉文字後的空白、請在
       想壓縮掉的空白地方加上一個"~"控制符號。如果重復使用兩個"~"符號、則該行會被重復列印、直到該
       欄位的所有文字列印完畢為止 (如你同時使用"@"值域欄位的話、切記每次要輸入不同的數值)。

       列印格示標題的預設處理方法、是將正使用的格式名稱後加上_TOP字樣既可。其內容將會列印至每頁的
       開頭部份。請參考 perlfunc/write 函數

       例如:

        # a report on the /etc/passwd file
        format STDOUT_TOP =
                                Passwd File
        Name                Login    Office   Uid   Gid Home
        ------------------------------------------------------------------
        .
        format STDOUT =
        @<<<<<<<<<<<<<<<<<< @⎪⎪⎪⎪⎪⎪⎪ @<<<<<<@>>>> @>>>> @<<<<<<<<<<<<<<<<<
        $name,              $login,  $office,$uid,$gid, $home
        .

        # a report from a bug report form
        format STDOUT_TOP =
                                Bug Reports
        @<<<<<<<<<<<<<<<<<<<<<<<     @⎪⎪⎪         @>>>>>>>>>>>>>>>>>>>>>>>
        $system,                      $%,         $date
        ------------------------------------------------------------------
        .
        format STDOUT =
        Subject: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                 $subject
        Index: @<<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
               $index,                       $description
        Priority: @<<<<<<<<<< Date: @<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                  $priority,        $date,   $description
        From: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
              $from,                         $description
        Assigned to: @<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                     $programmer,            $description
        ~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                             $description
        ~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                             $description
        ~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                             $description
        ~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                             $description
        ~                                    ^<<<<<<<<<<<<<<<<<<<<<<<...
                                             $description
        .

       我們也有可能在同一個輸出管道同時使用print 與 write函數。但使用時、必須修改$-的特殊內置變量
       值(使用English模塊的話、則是使用$FORMAT_LINES-LEFT變量)。

       Format Variables 格式變量

       當前的格式名稱一向都是存放於$~這個特殊變量內($FORMAT_NAME),而每頁的開頭格式則存放
       在$^($FORMAT-TOP_NAME),輸出頁為$%($FORMAT_PAGE_NUMBER),每頁行數是$=
       ($FORMAT_LINE_PER_PAGE),自動輸出格式是放在$⎪($OUTPUT_AUTOFLUSH)、要輸出到每頁開頭部份的字
       串存放在$^L ($FORMAT-FORMFEED)。這些變量的有效范圍,都是以某一個檔案句柄為單元。因此、你必
       須調用select()函數來調用適當的檔案句柄來改變變量內容。

           select((select(OUTF),
                   $~ = "My_Other_Format",
                   $^ = "My_Top_Format"
                  )[0]);

       難看吧!這就是一般用法。如此一來、你至少可用臨是變量來存放前一個檔案句柄。事實上、這已是較
       好的作法,除了可讀性提高外、也提供你一個位置暫停程式的執行,方變你一次到位除錯。

           $ofh = select(OUTF);
           $~ = "My_Other_Format";
           $^ = "My_Top_Format";
           select($ofh);

       如果你使用English模塊,你甚至可以輸入英文變量名稱

           use English '-no_match_vars';
           $ofh = select(OUTF);
           $FORMAT_NAME     = "My_Other_Format";
           $FORMAT_TOP_NAME = "My_Top_Format";
           select($ofh);

       但你還是要調用select()函數。因此我們建議你用FileHandle模塊。現在你可用小寫英文字母的格式名
       稱來處理這些特殊變量。

           use FileHandle;
           format_name     OUTF "My_Other_Format";
           format_top_name OUTF "My_Top_Format";

       好多了吧!

NOTES

       因為數值行的內容可能保括任何的表示法 (我們指的是 @ 欄位而非 ^ 欄位)。因此你可使用其它函
       數、建立更加復雜的處理方法。好像使用 printf 函數、或自己定義的函數。列如:

           format Ident =
               @<<<<<<<<<<<<<<<
               &commify($n)
           .

       在欄位輸入真正的@ 或^符號:

           format Ident =
           I have an @ here.
                   "@"
           .

       將整行字置中對齊:

           format Ident =
           @⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪
                   "Some text line"
           .

       我們並無任何內建的方法讓你指定如、某個欄位要對齊該頁面最右等諸如此類事項。但你仍然能列印出
       你想要的格式。跟據目前頁面直行數目,調用eval()函數來處理它:

           $format  = "format STDOUT = \n"
                    . '^' . '<' x $cols . "\n"
                    . '$entry' . "\n"
                    . "\t^" . "<" x ($cols-8) . "~~\n"
                    . '$entry' . "\n"
                    . ".\n";
           print $format if $Debugging;
           eval $format;
           die $@ if $@;

       它可能列印出下列格式外貌:

        format STDOUT =
        ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        $entry
                ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
        $entry
        .

       下面是一個有點類似fmt(1)的小程式:

        format =
        ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
        $_

        .

        $/ = '';
        while (<>) {
            s/\s*\n\s*/ /g;
            write;
        }

       Footers 頁腳

       雖然我們有$FORMAT_TOP_NAME來記錄每頁開頭部份的格式,卻沒有一個相對應的方法來自動指定每頁的
       底部格式。問題是、我們並不知到某個格式資料可能會多大,除非你真的去執行它。這是我們將來要處
       理的重點之一。

       這是一個暫時的應用方案 如果你有一個固定大小的頁腳、你可在每次調用write函數前檢查變
       量$FORMAT_LINES_LEFT,然後自行印出該資料。

       還有一個方法,就是開啟一個管道。調用open(MYSELF,」⎪-」) (參考 perlfunc/open() 函數)。並調
       用write函數把資料輸往MYSELF、而不是標準輸出STDOUT。然後利用子串列的標準輸入、來重新處理每
       頁開頭或結尾所要附加的資料部份。這雖不方便,但還是可辦到的。

       Accessing Formatting Internals 格式處理的核心

       至於低階格式的機制,你可調用formlin()函數直接處理$^A變量($ACCUMUNATOR)。

       例如:

           $str = formline <<'END', 1,2,3;
           @<<<  @⎪⎪⎪  @>>>
           END

           print "Wow, I just stored `$^A' in the accumulator!\n";

       或是設計一個子程式swrite()。它對於 write 的腳色相當於sprint 對於 print。

           use Carp;
           sub swrite {
               croak "usage: swrite PICTURE ARGS" unless @_;
               my $format = shift;
               $^A = "";
               formline($format,@_);
               return $^A;
           }

           $string = swrite(<<'END', 1, 2, 3);
        Check me out
        @<<<  @⎪⎪⎪  @>>>
        END
           print $string;

WARNINGS 警告

       不當處理顯示結束格示內容的點操作符號、有時也會同時影響你的網路的電郵功能(跟據過往經驗、錯
       誤是必然而不能避免)。如果使用電郵輸出格式內容、你應先處理好結束格式點操作符位置。切勿放置
       於左邊界、以免被SMTP截去。

       局部變量(引用」my」定義變量)、在調用格式化輸出時不會被察覺。除非在使用局部變量的串程內另行
       定義(5.001版本前並沒有局部變量一詞)。

       格式輸出是 perl 語言裏維一受制於編程使用地區的部分。如果當前的使用地區使用LC_NUMERIC,那小
       數點符號的格式化輸出必以當地方式顯示。perl 不會理會當地的所須格式,除非你調用了 use
       locale。但格式列印又不受控於use locale。因為locale 它只在使用的塊內有效。同時跟據歷史原
       因、格式的作用域不僅包括在塊內。進一步詳情參閱 perllocale 本地化文件。

       格式輸出時、程式串內的空白符號0,相當於一個空白單元。所以你可以想像格式列印相當於先處理變
       量:

        $value =~ tr/\n\t\f/ /;
                                        將強制性另印新行。
       除非圖案行已定義、餘下的空白符號

中文版維護人

       小高 <you@email.com>

中文版最新更新

       2001年12月9日星期日

中文手冊頁翻譯計劃

       http://cmpp.linuxforum.net