.\" 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