.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14 .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "PERLFORM 1" .TH PERLFORM 7 "2003-11-25" "perl v5.8.3" "Perl Programmers Reference Guide" .SH "NAME" perlform \- Perl 格式 .SH "DESCRIPTION 描述" .IX Header "DESCRIPTION" Perl的一些內部機制、可以幫助我們產生一份簡單的格式化圖表。經過perl的處理,你列印的格式可以接近於你所見的外貌。它可以記錄如你現在正處在哪個頁面,每個頁面的行數與何時列印出頁面的標題。關鍵字,format() 格式函式與write()執行函式是直接引自FORTRAN語法。詳情可參閱 perlfunc。幸運的是列印的格式可讀性又有所提高。幾乎類似BASIC 的PRINT USING。可以把它想象為簡單的 \fInroff\fR\|(1). .PP 有如子程式與包一樣,格式只是語句的宣告,而不是執行呼叫。故它可以放在程式的任何位置(一般最好是把它們集中在一塊)。與perl的其它變數名字型別不同, 格式命名有別於一般的獨自的定義。也就是說,你有一個名為Foo的函式,它與另一個格式名稱為Foo的東西是完全不同。但是預設的格式名稱與有關連的檔案控制代碼可用相同的名字。所以預設的輸出格式名稱STDOUT,它的檔案控制代碼名稱就是STDOUT。而對預設格式名稱TEMP,它的檔案控制代碼名稱也可以是TEMP。雖然名稱一樣但兩者並不相同。 .PP 輸出格式的語法如下: .PP .Vb 3 \& format NAME = \& FORMLIST \& . .Ve .PP 如省略格式名稱,格式名稱將以標準輸出STDOUT命名。而格式專案將包括了好幾個連續橫行。每一行屬於下列叄種型態之一: .IP "1." 4 註釋(comment), 以符號“#”置於每行的開頭。 .IP "2." 4 圖案行(picture line),規定了單一行的格式化外觀。 .IP "3." 4 引數行, 提供一些數值以對應前面的圖案行。 .PP 圖案行的輸出效果就與我們看到的一樣,除了某些值域欄位會給相對應數值取代外,每個輸入欄位都以一個@或 ^ 控制符開頭。這些單行內的控制符不能做任何竄改取代(勿與陣列變數@混淆)。@欄位是屬於正常形態的欄位,而^欄位則用來表示可以輸入多行文字。至於該欄位則由< > 或 | 符號跟隨其後指定向左、右、或居中對齊。並同時跟據該符號的數目,輸入指定資料的長度。如變數內容超過限定長度、格式列印時會自動刪除多餘的部份。 .PP 另一種指定向右對齊方式,是使用#符號來指定一個數字欄位。如此可方便小數點定位。如果輸入值裡還包含一個換行字元(\n),則僅列印出該換行字元前的資料。最後圖案行出現的@*這個特別符號標記,可以用來列印多行並且不被截掉的數值。 .PP 接下來的一行、是跟據圖案行裡的值域欄位輸入相應的數值。如果是利用運算式提供數值的話、必須以逗號分隔。因為所有的表示法都會被當成一個串連內容再行處理。所以一個單一的串列表示法也可產生多個串列資料。如果表示法是利用括號圍起,可能會展開好幾行。若想如是安排,第一行的第一個單字必須是以左括號開始。如果運算式內有小數點的數字型別須要處理、同時圖案行的相關符號也指出小數位須列印出來(除了圖案行內的包含小數點"."的數字控制符號#外)。小數點列印出的外貌, 以當地的執行版本決定(LC_NUMERIC locale)。也就是說、在德文地區使用小數格示輸出時、小數點的顯示將是","而非"."。相關資料請參考 perllocale 與 "警告" .PP 圖案行裡的欄位如果以^控制符開頭、格式將會作特殊化處理。如果該欄位是註解欄位又沒定義其值、欄位將以空白取代。若是其它型態、則視為一種填補資料的狀態。 在此、我們不能隨便填入任意表示法進去。相反、必須以相關的變數輸入字串內容。perl會盡量將文字放入該欄位、然後把字串的前面部份刪去。當你下次使用該字串變數時、可以使用後面的字串部份(換句話說、在執行write函式時、字串變數的內容是會改變的)。正常情況下、你必須使用一類似垂直狀的堆塊來放置要輸入的文字、以便整齊列印出一柱狀文字。如你列印的文字太長、想以"..."取代過長的文字時、你可以藉由更改 $: 變數值來取代分隔字元。也就是當你使用ENGLISH模組時的 $FORMAT_LINE_BREAK_CHARACTERS的意思。 .PP 使用^符號欄位可產生不定長度的記錄欄位。如果要列印的文字很短、你想壓縮掉文字後的空白、請在想壓縮掉的空白地方加上一個"~"控制符號。如果重複使用兩個"~"符號、則該行會被重複列印、直到該欄位的所有文字列印完畢為止 (如你同時使用"@"值域欄位的話、切記每次要輸入不同的數值)。 .PP 列印格示標題的預設處理方法、是將正使用的格式名稱後加上_TOP字樣既可。其內容將會列印至每頁的開頭部份。請參考 perlfunc/write 函式 .PP 例如: .PP .Vb 10 \& # 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 \& . .Ve .PP .Vb 29 \& # 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 \& . .Ve .PP 我們也有可能在同一個輸出管道同時使用print 與 write函式。但使用時、必須修改$-的特殊內建變數值(使用English模組的話、則是使用$FORMAT_LINES-LEFT變數)。 .Sh "Format Variables 格式變數" .IX Subsection "Format Variables" 當前的格式名稱一向都是存放於$~這個特殊變數內($FORMAT_NAME),而每頁的開頭格式則存放在$^($FORMAT-TOP_NAME),輸出頁為$%($FORMAT_PAGE_NUMBER),每頁行數是$= ($FORMAT_LINE_PER_PAGE),自動輸出格式是放在$|($OUTPUT_AUTOFLUSH)、要輸出到每頁開頭部份的字串存放在$^L ($FORMAT-FORMFEED)。這些變數的有效範圍,都是以某一個檔案控制代碼為單元。因此、你必須呼叫select()函式來呼叫適當的檔案控制代碼來改變變數內容。 .PP .Vb 4 \& select((select(OUTF), \& $~ = "My_Other_Format", \& $^ = "My_Top_Format" \& )[0]); .Ve .PP 難看吧!這就是一般用法。如此一來、你至少可用臨是變數來存放前一個檔案控制代碼。事實上、這已是較好的作法,除了可讀性提高外、也提供你一個位置暫停程式的執行,方變你一次到位除錯。 .PP .Vb 4 \& $ofh = select(OUTF); \& $~ = "My_Other_Format"; \& $^ = "My_Top_Format"; \& select($ofh); .Ve .PP 如果你使用English模組,你甚至可以輸入英文變數名稱 .PP .Vb 5 \& use English '-no_match_vars'; \& $ofh = select(OUTF); \& $FORMAT_NAME = "My_Other_Format"; \& $FORMAT_TOP_NAME = "My_Top_Format"; \& select($ofh); .Ve .PP 但你還是要呼叫select()函式。因此我們建議你用FileHandle模組。現在你可用小寫英文字母的格式名稱來處理這些特殊變數。 .PP .Vb 3 \& use FileHandle; \& format_name OUTF "My_Other_Format"; \& format_top_name OUTF "My_Top_Format"; .Ve .PP 好多了吧! .SH "NOTES" .IX Header "NOTES 附註" 因為數值行的內容可能保括任何的表示法 (我們指的是 @ 欄位而非 ^ 欄位)。因此你可使用其它函式、建立更加複雜的處理方法。好像使用 printf 函式、或自己定義的函式。列如: .PP .Vb 4 \& format Ident = \& @<<<<<<<<<<<<<<< \& &commify($n) \& . .Ve .PP 在欄位輸入真正的@ 或^符號: .PP .Vb 4 \& format Ident = \& I have an @ here. \& "@" \& . .Ve .PP 將整行字置中對齊: .PP .Vb 4 \& format Ident = \& @||||||||||||||||||||||||||||||||||||||||||||||| \& "Some text line" \& . .Ve .PP 我們並無任何內建的方法讓你指定如、某個欄位要對齊該頁面最右等諸如此類事項。但你仍然能列印出你想要的格式。跟據目前頁面直行數目,呼叫eval()函式來處理它: .PP .Vb 9 \& $format = "format STDOUT = \en" \& . '^' . '<' x $cols . "\en" \& . '$entry' . "\en" \& . "\et^" . "<" x ($cols-8) . "~~\en" \& . '$entry' . "\en" \& . ".\en"; \& print $format if $Debugging; \& eval $format; \& die $@ if $@; .Ve .PP 它可能列印出下列格式外貌: .PP .Vb 6 \& format STDOUT = \& ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< \& $entry \& ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~ \& $entry \& . .Ve .PP 下面是一個有點類似fmt(1)的小程式: .PP .Vb 3 \& format = \& ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ \& $_ .Ve .PP .Vb 1 \& . .Ve .PP .Vb 5 \& $/ = ''; \& while (<>) { \& s/\es*\en\es*/ /g; \& write; \& } .Ve .Sh "Footers 頁尾" .IX Subsection "Footers" 雖然我們有$FORMAT_TOP_NAME來記錄每頁開頭部份的格式,卻沒有一個相對應的方法來自動指定每頁的底部格式。問題是、我們並不知到某個格式資料可能會多大,除非你真的去執行它。這是我們將來要處理的重點之一。 .PP 這是一個暫時的應用方案 如果你有一個固定大小的頁尾、你可在每次呼叫write函式前檢查變數$FORMAT_LINES_LEFT,然後自行印出該資料。 .PP 還有一個方法,就是開啟一個管道。呼叫open(MYSELF,”|-”) (參考 perlfunc/open() 函式)。並呼叫write函式把資料輸往MYSELF、而不是標準輸出STDOUT。然後利用子串列的標準輸入、來重新處理每頁開頭或結尾所要附加的資料部份。這雖不方便,但還是可辦到的。 .Sh "Accessing Formatting Internals 格式處理的核心" .IX Subsection "Accessing Formatting Internals" 至於低階格式的機制,你可呼叫formlin()函式直接處理$^A變數($ACCUMUNATOR)。 .PP 例如: .PP .Vb 3 \& $str = formline <<'END', 1,2,3; \& @<<< @||| @>>> \& END .Ve .PP .Vb 1 \& print "Wow, I just stored `$^A' in the accumulator!\en"; .Ve .PP 或是設計一個子程式swrite()。它對於 write 的腳色相當於sprint 對於 print。 .PP .Vb 8 \& use Carp; \& sub swrite { \& croak "usage: swrite PICTURE ARGS" unless @_; \& my $format = shift; \& $^A = ""; \& formline($format,@_); \& return $^A; \& } .Ve .PP .Vb 5 \& $string = swrite(<<'END', 1, 2, 3); \& Check me out \& @<<< @||| @>>> \& END \& print $string; .Ve .SH "WARNINGS 警告" .IX Header "WARNINGS" 不當處理顯示結束格示內容的點運算子號、有時也會同時影響你的網路的電郵功能(跟據過往經驗、錯誤是必然而不能避免)。如果使用電郵輸出格式內容、你應先處理好結束格式點運算子位置。切勿放置於左邊界、以免被SMTP截去。 .PP 區域性變數(引用”my”定義變數)、在呼叫格式化輸出時不會被察覺。除非在使用區域性變數的串程內另行定義(5.001版本前並沒有區域性變數一詞)。 .PP 格式輸出是 perl 語言裡維一受制於程式設計使用地區的部分。如果當前的使用地區使用LC_NUMERIC,那小數點符號的格式化輸出必以當地方式顯示。perl 不會理會當地的所須格式,除非你呼叫了 use locale。但格式列印又不受控於use locale。因為locale 它只在使用的塊內有效。同時跟據歷史原因、格式的作用域不僅包括在塊內。進一步詳情參閱 perllocale 本地化文件。 .PP 格式輸出時、程式串內的空白符號\n,\t,\t相當於一個空白單元。所以你可以想像格式列印相當於先處理變數: .PP .Vb 1 \& $value =~ tr/\en\et\ef/ /; .Ve .PP 除非圖案行已定義、餘下的空白符號\r 將強制性另印新行。 .SH "中文版維護人" .B 小高  .SH "中文版最新更新" .B 2001年12月9日星期日 .SH 中文手冊頁翻譯計劃 .B http://cmpp.linuxforum.net .Sh "跋" .br 本頁面中文版由中文 man 手冊頁計劃提供。 .br 中文 man 手冊頁計劃:\fBhttps://github.com/man-pages-zh/manpages-zh\fR