Chinaunix

标题: 2个半小时学会Perl [摘要] [打印本页]

作者: shijiang1130    时间: 2013-03-03 23:52
标题: 2个半小时学会Perl [摘要]
本帖最后由 shijiang1130 于 2013-03-07 23:04 编辑
  1. 学习Perl用约2小时30分钟

  2. --- 考虑到自己的水平问题,写翻译实在是对不起大众,就改成摘要了,省略了面向对象那一章和其它自认为是翻不出来的内容,要是你有兴趣还是去看原版英文吧,http://qntm.org/files/perl/perl.html。 --

  3. 在两个小时30分钟内了解 Perl

  4. 作者 Sam Hughes

  5. Perl语言是一门高级解释型动态语言,它的许多数据类型是运行时才决定的,并且经常和PHP和Python相提并论。Perl 从古老的Shell脚本语言中借鉴了许多语法特性,因为被过度使用的各种奇怪符号而声名狼藉,而且大部分代码借助Google的搜索功能都不能明白。Perl语言因其来自Shell的语言特性使之成为一门好用的胶水语言: 将其他语言和各种脚本连接在一起共同工作。  

  6. Perl 语言非常适合处理文本,并生成更多的文本。Perl语言应用广泛,流行,可移植性极佳,而且有良好的社区支持。Perl 语言的设计哲学是:"每个问题都有许多解决方式"(TMTOWTDI)( 与之相反,Python 的设计哲学是:每个问题应该只有一种,而且只有一种明确的,最好的解决方式)。

  7. Perl 有令人沮丧的地方,但同时也有许多奇妙的特性。从这一点来看,它同其他任何一种曾经有过的编程语言一样。

  8. 这篇文章只是提供一些知识,并不是什么宣传广告,目标读者只是针对像我这样的人: 厌恶 http://perl.org 上面学术性的文档,那些东西只会长篇累牍的讲述一些永远用不到的边缘问题。我只想通过一些通用规则和实例快速了解那些从Larry Wall的角度永远都不关心的基础编程问题,并学些能帮我找到一份工作的基础知识。

  9. 这篇文档的目的是用短的不能再短的形式来讲:


  10. 研究初探

  11. 以下声明针对整个文档:“这并不是绝对的,实际情况要复杂的多”。你如果发现一个严重错误,请告诉我。但我保留对孩子们说错话的权利。

  12. 在本文档中,我在实例中打印状态,输出数据,但没有明确的追加换行符。这样做是为了避免我发狂,让我能集中精力在实例中字符串的输出,我相信这是更重要的。在许多例子中,实际的输出可能是 "alotofwordsallsmusheduptogetherononeline". 请不要在意。

  13. Hello world

  14. 一个 Perl 脚本就是一个后缀为 .pl 的文本文件。

  15. 这就是 helloworld.pl 的全文:

  16.   use strict;
  17.   use warnings;

  18.   print "Hello world";

  19. Perl 脚本被 Perl 的解释器来解释运行:

  20.   perl helloworld.pl [arg0 [arg1 [arg2 ...]]]

  21. 说实话,Perl 的语法非常宽容,他可以替你预测一些模糊的不知所云的代码的行为,我实在不想讲这些东西,因为你们应当竭力避免这么做。

  22. 避免这么做的方法就是将 'use strict; use warnings' 放置在每一个脚本或模块的最前面。'use foo' 这样的语句是编译提示,编译提示是给 Perl.exe 的信号,在程序运行前,对解释器初始化语法验证规则施加影响。在代码运行的时候,解释器将忽略这些东西。

  23. '#' 符号是一个注释的开始。注释的结束是到行的末尾。Perl 没有针对块的注释语法。

  24. 变量

  25. Perl 的变量有三种类型:标量,数组和散列。每种类型都有自己的前置符号:$, @ 和 % 分别代表这三种类型。变量使用 my 来声明,有效范围在闭合块范围内或到文件的末尾。

  26. 标量变量

  27. 一个标量变量可以包含:

  28. undef (相当于 Python 中的 None, PHP 中的 null)

  29. 一个数字( Perl 并不区分一个整型数字和浮点数字)

  30. 一个字符串

  31. 一个指向别的变量的引用

  32.   my $undef = undef;
  33.   print $undef; # prints the empty string "" and raises a warning

  34.   # implicit undef:
  35.   my $undef2;
  36.   print $undef2; # prints "" and raises exactly the same warning
  37.   my $num = 4040.5;
  38.   print $num; # "4040.5"
  39.   my $string = "world";
  40.   print $string; # "world"

  41. (稍后介绍引用)

  42. 字符串使用 '.' 进行连接(和PHP一样)

  43.   print "Hello ".$string; # "Hello world"

  44. 布尔值

  45. Perl 没有布尔数据类型。只有如下几种值才能在 if 判断语句中返回 'false' :
  46. undef

  47. 数字 0

  48. 字符串 ""

  49. 字符串 "0"

  50. Perl 文档中经常提到函数在某些情况下会返回 'true' 或 'false'. 实际上,函数通常用 'return 1' 来返回真,用返回空字符串 '' 来表示返回假。

  51. 弱类型

  52. 它是不可能确定一个标量包含一个“数字”或“字符串”。更准确地说,它不应该有必要这样做。一个标量是否像一个数字或者字符串取决于操作者的使用它。当作为一个字符串、一个标量会表现得像一个字符串。当作为一个数字,一个标量会表现得像一个号码(增加一个警告如果这是不可能的):

  53. my $str1 = "4G";
  54. my $str2 = "4H";
  55. print $str1 . $str2; # "4G4H"
  56. print $str1 + $str2; # "8" with two warnings
  57. print $str1 eq $str2; # "" (empty string, i.e. false)
  58. print $str1 == $str2; # "1" with two warnings
  59. # The classic error

  60. #经典的错误

  61. print "yes" == "no"; # "1" with two warnings; both values evaluate to 0 when used as numbers

  62. 两个值用作数字评估为0

  63. 这个教训是总是使用正确的操作符来比较标量数字和标量字符串比较:
  64. #数值运算符:<、>、< =、> =、= =、!=、< = >,+,*
  65. #字符串运算符: lt, gt, le, ge, eq, ne, cmp, . , x

  66. 数组变量
  67. 一个数组变量是一个标量的列表索引从0开始的整数。在Python中这被称为一个列表,在PHP这被称为数组。一个数组声明使用parenthesised标量的列表:

  68. my @array = (
  69. "print",
  70. "these",
  71. "strings",
  72. "out",
  73. "for",
  74. "me", # trailing comma is okay
  75. );

  76. 你必须使用美元符号来访问一个值从一个数组,因为要取得的值不是一个数组但标量:

  77. print $array[0]; # "print"
  78. print $array[1]; # "these"
  79. print $array[2]; # "strings"
  80. print $array[3]; # "out"
  81. print $array[4]; # "for"
  82. print $array[5]; # "me"
  83. print $array[6]; # returns undef, prints "" and raises a warning


  84. 您可以使用负索引检索条目从结局开始和向后的工作:

  85. print $array[-1]; # "me"
  86. print $array[-2]; # "for"
  87. print $array[-3]; # "out"
  88. print $array[-4]; # "strings"
  89. print $array[-5]; # "these"
  90. print $array[-6]; # "print"
  91. print $array[-7]; # returns undef, prints "" and raises a warning

  92. 标量$ var和包含一个标量条目$ var[0] 的@var数组。有可能被读者困惑,所以避免这个。

  93. 获取一个数组的长度:
  94. print "This array has ". (scalar @array). "elements"; # "This array has 6 elements"

  95. 最后的下标是5”
  96. print "The last populated index is ". $#array; # "The last populated index is 5"

  97. The arguments with which the original Perl script was invoked are stored in the built-in array variable @ARGV.
  98. Perl脚本原来的参数调用存储在内置数组@ argv里面。
  99. 变量可以插入到字符串:
  100. print "Hello $string"; # "Hello world"
  101. print "@array"; # "print these strings out for me"

  102. 谨慎。有一天你会把某人的电子邮件地址在一个字符串,“[email]jeff@gmail.com[/email]”。这将导致Perl寻找一个数组变量称为@gmail来插入到字符串,并没有发现它,这会导致运行时错误。插值可以避免在两个方面:通过反斜杠转义特殊符号,或者用单引号代替双引号。
  103. print "Hello \$string"; # "Hello $string"
  104. print 'Hello $string'; # "Hello $string"
  105. print "\@array"; # "@array"
  106. print '@array'; # "@array"

  107. 散列变量
  108. 一个散列变量是一个字符串索引列表的标量。在Python中这被称为一个字典,在PHP中,这被称为一个数组。
  109. my %scientists = (
  110. "Newton" => "Isaac",
  111. "Einstein" => "Albert",
  112. "Darwin" => "Charles",
  113. );

  114. 注意这是一个类似声明数组声明。事实上,双箭头符号= >被称为“胖逗号“,因为它只是一个逗号分隔的同义词。一个散列声明使用列表与偶数个元素,偶数编号的元素(0、2、……)都作为字符串。
  115. 你必须使用美元符号来访问一个值从一个散列,因为要取得的值不是一个散列但标量:
  116. print $scientists{"Newton"}; # "Isaac"
  117. print $scientists{"Einstein"}; # "Albert"
  118. print $scientists{"Darwin"}; # "Charles"
  119. print $scientists{"Dyson"}; # returns undef, prints "" and raises a warning
  120. 注意:$ var和包含一个标量条目$ var {“foo”}的散列 % var与上面的数组包含标量。

  121. 你可以直接转换一个散列与两倍条目的数组,交替键和值(和反向同样是容易的):
  122. my @scientists = %scientists;
  123. 然而,不像一个数组,将返回任意顺序。这个在编程的时候有注意!
  124. 回顾一下,你必须使用方括号来检索一个值从一个数组,但是你必须使用括号来检索一个值从一个散列。方括号实际上是一个数值算子和括号都有效的字符串操作符。

  125. my $data = "orange";
  126. my @data = ("purple");
  127. my %data = ( "0" => "blue");
  128. print $data; # "orange"
  129. print $data[0]; # "purple"
  130. print $data["0"]; # "purple"
  131. print $data{0}; # "blue"
  132. print $data{"0"}; # "blue"

复制代码

作者: 7looki    时间: 2013-03-04 02:41
学习Perl用约2小时30分钟

光这几个字, 唉, 我就不想看翻译的了(虽然我的英语很差很差, 差到看不懂).
作者: Perlvim    时间: 2013-03-04 08:06
本帖最后由 Perlvim 于 2013-03-04 08:56 编辑

支持此计划,建议尝试用并行开发思路解决。

将此任务拆分成几个部分,允许别人认领,然后合并结果。

太多在名字上引人侧目的华而不实的文章,使类似速成,几天,几小时掌握什么的名字,让人厌烦。
同时也让许多精辟短小的好文章被人遗忘。

这篇是带领人入门的好文章,不能说掌握,只能是了解。建议中文名字起一个平实的名字。大家可以各抒已见。
作者: shijiang1130    时间: 2013-03-04 23:13
列表
一个列表在Perl是一种不同的东西再从要么数组或散列。你刚刚看到几个列表:
  1. (
  2. "print",
  3. "these",
  4. "strings",
  5. "out",
  6. "for",
  7. "me",
  8. )
  9. (
  10. "Newton" => "Isaac",
  11. "Einstein" => "Albert",
  12. "Darwin" => "Charles",
  13. )
复制代码
一个列表不是一个变量。列表是一个短暂的价值,可分配给一个数组或散列变量。这就是为什么语法来声明数组和散列变量是相同的。在许多情况下,术语“列表”和“数组”可以互换使用,但有同样很多,列表和数组显示略有不同和极其混乱的行为。

好吧。记住,= >只是在伪装,然后看这个例子:
  1. ("one", 1, "three", 3, "five", 5)
  2. ("one" => 1, "three" => 3, "five" => 5)
复制代码
使用= >暗示这些列表是一个数组声明和其他是一个散列声明。但在他们自己的,他们两个都不是声明的任何东西。他们只是列表。相同的列表。
()
这里甚至没有暗示。这个列表可以用来声明一个空数组或一个空哈希和perl解释器显然没有告诉无论哪种方式。一旦你理解了这个奇怪的方面的Perl,你也会明白为什么以下事实必须真实:列表值不能嵌套。试一试:
  1. my @array = (
  2. "apples",
  3. "bananas",
  4. (
  5. "inner",
  6. "list",
  7. "several",
  8. "entries",
  9. ),
  10. "cherries",
  11. );
复制代码
Perl无法知道是否("inner", "list", "several", "entries")被认为是一种内在的数组或一种内在的散列。因此,Perl假定它既不是和平滑的列表一个长长的名单:
  1. print $array[0]; # "apples"
  2. print $array[1]; # "bananas"
  3. print $array[2]; # "inner"
  4. print $array[3]; # "list"
  5. print $array[4]; # "several"
  6. print $array[5]; # "entries"
  7. print $array[6]; # "cherries"

  8. 相同的是真正的是否使用=>
  9. my %hash = (
  10. "beer" => "good",
  11. "bananas" => (
  12. "green" => "wait",
  13. "yellow" => "eat",
  14. ),
  15. );

  16. #以上提出了一个警告,因为散列被宣布使用7元素列表
  17. print $hash{"beer"}; # "good"
  18. print $hash{"bananas"}; # "green"
  19. print $hash{"wait"}; # "yellow";
  20. print $hash{"eat"}; # undef, so prints "" and raises a warning
复制代码
当然,这确实使它容易连接多个数组在一起:
  1. my @bones = ("humerus", ("jaw", "skull"), "tibia");
  2. my @fingers = ("thumb", "index", "middle", "ring", "little");
  3. my @parts = (@bones, @fingers, ("foot", "toes"), "eyeball", "knuckle");
  4. print @parts;
复制代码

作者: shijiang1130    时间: 2013-03-04 23:29
  1. 上下文
  2. Perl最鲜明的特征是,它的代码是上下文敏感的。每个表达式在Perl是评估无论是在标量上下文语境或列表,根据是否将产生一个标量或列表。许多Perl表达式和内置函数显示截然不同的行为取决于上下文的评估。
  3. 一个标量作业如$scalar =评估它的表达式在标量上下文。在这种情况下,该表达式是"Mendeleev"和返回的值是相同的标量值"Mendeleev":
  4. my $scalar = "Mendeleev";
  5. 一个数组或散列赋值如@array =或%hash =评估其表达上下文列表。一个列表值列表上下文中计算得到的返回列表
  6. my @array = ("Alpha", "Beta", "Gamma", "Pie");
  7. my %hash = ("Alpha" => "Beta", "Gamma" => "Pie");

  8. 到目前为止没有惊喜。
  9. 一个标量表达式列表上下文中计算得到的变成一个单元素列表:
  10. my @array = "Mendeleev"; # same as 'my @array = ("Mendeleev");'

  11. 表达式列表评估在标量上下文返回最终的标量在列表中:
  12. my $scalar = ("Alpha", "Beta", "Gamma", "Pie"); # Value of $scalar is now "Pie"
  13. 一个数组表达式(数组是不同的从一个列表,还记得吗?)评估在标量上下文返回数组的长度:
  14. my @array = ("Alpha", "Beta", "Gamma", "Pie");
  15. my $scalar = @array; # Value of $scalar is now 4
  16. 打印内置函数评估它的所有参数在上下文列表。事实上,打印接受无限的参数列表,并打印每个一个接一个,这意味着它可以用来直接打印数组:
  17. my @array = ("Alpha", "Beta", "Goo");
  18. my $scalar = "-X-";
  19. print @array; # "AlphaBetaGoo";
  20. print $scalar, @array, 98; # "-X-AlphaBetaGoo98";
  21. 你可以迫使任何表达式计算在标量上下文使用标量内置函数。事实上,这就是为什么我们使用标量来检索一个数组的长度。
  22. 你没有语法来返回标量值在标量上下文,也没有返回值在列表上下文。如上所述,Perl是完全有能力为你捏造结果。
复制代码

作者: shijiang1130    时间: 2013-03-04 23:44
  1. 引用和嵌套的数据结构
  2. 以同样的方式列出不能包含列表元素,数组和散列不能包含其他元素数组和散列。他们只能包含标量。看看会发生什么:
  3. my @outer = ("Sun", "Mercury", "Venus", undef, "Mars");
  4. my @inner = ("Earth", "Moon");
  5. $outer[3] = @inner;
  6. print $outer[3]; # "2"
  7. $@outer是一个标量,所以它需要一个标量值。当你试图分配一个数组值像@inner,@inner评估在标量上下文。这是一样的标量@inner分配,这是@inner数组的长度,这是2。
  8. 然而,一个标量变量可能包含一个引用到任何变量,包括一个数组变量或一个散列变量。这是在PERL中创建更复杂的数据结构。
  9. 创建一个引用是使用一个反斜杠。
  10. my $colour = "Indigo";
  11. my $scalarRef = \$colour;
  12. 任何时间你将使用一个变量的名字,您可以只放一些括号,括号内,将一个引用变量来代替。
  13. print $colour; # "Indigo"
  14. print $scalarRef; # e.g. "SCALAR(0x182c180)"
  15. print ${ $scalarRef }; # "Indigo"

  16. 只要结果是不模糊,你可以省略括号:
  17. print $$scalarRef; # "Indigo"
  18. If your reference is a reference to an array or hash variable, you can get data out of it using braces or using the more popular arrow operator, ->:
  19. 如果你的引用是引用一个数组或散列变量,您可以用括号或使用更受欢迎的箭头操作符 - >得到数据
  20. my @colours = ("Red", "Orange", "Yellow", "Green", "Blue");
  21. my $arrayRef = \@colours;
  22. print $colours[0]; # direct array access
  23. print ${ $arrayRef }[0]; # use the reference to get to the array
  24. print $arrayRef->[0]; # exactly the same thing
  25. my %atomicWeights = ("Hydrogen" => 1.008, "Helium" => 4.003, "Manganese" => 54.94);
  26. my $hashRef = \%atomicWeights;
  27. print $atomicWeights{"Helium"}; # direct hash access
  28. print ${ $hashRef }{"Helium"}; # use a reference to get to the hash
  29. print $hashRef->{"Helium"}; # exactly the same thing - this is very common

  30. 声明一个数据结构
  31. 这里有四个例子,但在实践中最后一个是最有益的。
  32. my %owner1 = (
  33. "name" => "Santa Claus",
  34. "DOB" => "1882-12-25",
  35. );
  36. my $owner1Ref = \%owner1;
  37. my %owner2 = (
  38. "name" => "Mickey Mouse",
  39. "DOB" => "1928-11-18",
  40. );
  41. my $owner2Ref = \%owner2;
  42. my @owners = ( $owner1Ref, $owner2Ref );
  43. my $ownersRef = \@owners;
  44. my %account = (
  45. "number" => "12345678",
  46. "opened" => "2000-01-01",
  47. "owners" => $ownersRef,
  48. );

  49. 这显然是不必要的辛苦,因为你可以简化成:
  50. my %owner1 = (
  51. "name" => "Santa Claus",
  52. "DOB" => "1882-12-25",
  53. );
  54. my %owner2 = (
  55. "name" => "Mickey Mouse",
  56. "DOB" => "1928-11-18",
  57. );
  58. my @owners = ( \%owner1, \%owner2 );
  59. my %account = (
  60. "number" => "12345678",
  61. "opened" => "2000-01-01",
  62. "owners" => \@owners,
  63. );
  64. 也可以使用不同的符号声明匿名数组和散列。使用方括号为一个匿名数组和括号为匿名散列。返回的值在每个案例是一个参考的匿名数据结构问题。仔细看:
  65. #括号表示一个匿名散列
  66. my $owner1Ref = {
  67. "name" => "Santa Claus",
  68. "DOB" => "1882-12-25",
  69. };
  70. my $owner2Ref = {
  71. "name" => "Mickey Mouse",
  72. "DOB" => "1928-11-18",
  73. };

  74. #方括号表示一个匿名数组
  75. my $ownersRef = [ $owner1Ref, $owner2Ref ];
  76. my %account = (
  77. "number" => "12345678",
  78. "opened" => "2000-01-01",
  79. "owners" => $ownersRef,
  80. );

  81. 或者, (你应该实际使用复杂数据结构时声明内联):
  82. my %account = (
  83. "number" => "31415926",
  84. "opened" => "3000-01-01",
  85. "owners" => [
  86. {
  87. "name" => "Philip Fry",
  88. "DOB" => "1974-08-06",
  89. },
  90. {
  91. "name" => "Hubert Farnsworth",
  92. "DOB" => "2841-04-09",
  93. },
  94. ],
  95. );
复制代码

作者: Perlvim    时间: 2013-03-05 17:04
本帖最后由 Perlvim 于 2013-03-06 12:55 编辑

大家看看有什么地方翻译的有问题,请随时提出,我会继续翻译直到翻译完成:

=encoding utf8

en: =head1 Learn Perl in about 2 hours 30 minutes
cn: =head1 在两个小时30分钟内了解 Perl

en: =head2 By Sam Hughes
cn: =head2 作者 Sam Hughes

en: Perl is a dynamic, dynamically-typed, high-level, scripting (interpreted) language most comparable with PHP and Python. Perl's syntax owes a lot to ancient shell scripting tools, and it is famed for its overuse of confusing symbols, the majority of which are impossible to Google for. Perl's shell scripting heritage makes it great for writing glue code: scripts which link together other scripts and programs.
cn: Perl语言是一门高级解释型动态语言,它的许多数据类型是运行时才决定的,并且经常和PHP和Python相提并论。Perl 从古老的Shell脚本语言中借鉴了许多语法特性,因为被过度使用的各种奇怪符号而声名狼藉,而且大部分代码借助Google的搜索功能都不能明白。Perl语言因其来自Shell的语言特性使之成为一门好用的胶水语言: 将其他语言和各种脚本连接在一起共同工作。  

en: Perl is ideally suited for processing text data and producing more text data. Perl is widespread, popular, highly portable and well-supported. Perl was designed with the philosophy "There's More Than One Way To Do It" (TMTOWTDI) (contrast with Python, where "there should be one - and preferably only one - obvious way to do it").
cn: Perl 语言非常适合处理文本,并生成更多的文本。Perl语言应用广泛,流行,可移植性极佳,而且有良好的社区支持。Perl 语言的设计哲学是:"每个问题都有许多解决方式"(TMTOWTDI)( 与之相反,Python 的设计哲学是:每个问题应该只有一种,而且只有一种明确的,最好的解决方式)。

en: Perl has horrors, but it also has some great redeeming features. In this respect it is like every other programming language ever created.
cn: Perl 有令人沮丧的地方,但同时也有许多奇妙的特性。从这一点来看,它同其他任何一种曾经有过的编程语言一样。

en: This document is intended to be informative, not evangelical. It is aimed at people who, like me: dislike the official Perl documentation at http://perl.org/ for being intensely technical and giving far too much space to very unusual edge cases learn new programming languages most quickly by "axiom and example" wish Larry Wall would get to the point already know how to program in general terms don't care about Perl beyond what's necessary to get the job done.
cn: 这篇文章只是提供一些知识,并不是什么宣传广告,目标读者只是针对像我这样的人: 厌恶 http://perl.org 上面学术性的文档,那些东西只会长篇累牍的讲述一些永远用不到的边缘问题。我只想通过一些通用规则和实例快速了解那些从Larry Wall的角度永远都不关心的基础编程问题,并学些能帮我找到一份工作的基础知识。

en: This document is intended to be as short as possible, but no shorter.
cn: 这篇文档的目的是用短的不能再短的形式来讲:

en: =head2 Preliminary notes
cn: =head2 研究初探

en: The following can be said of almost every declarative statement in this document: "that's not, strictly speaking, true; the situation is actually a lot more complicated". If you see a serious lie, point it out, but I reserve the right to preserve certain critical lies-to-children.
cn: 以下声明针对整个文档:“这并不是绝对的,实际情况要复杂的多”。你如果发现一个严重错误,请告诉我。但我保留对孩子们说错话的权利。

en: Throughout this document I'm using example print statements to output data but not explicitly appending line breaks. This is done to prevent me from going crazy and to give greater attention to the actual string being printed in each case, which is invariably more important. In many examples, this results in alotofwordsallsmusheduptogetherononeline if the code is run in reality. Try to ignore this.
cn: 在本文档中,我在实例中打印状态,输出数据,但没有明确的追加换行符。这样做是为了避免我发狂,让我能集中精力在实例中字符串的输出,我相信这是更重要的。在许多例子中,实际的输出可能是 "alotofwordsallsmusheduptogetherononeline". 请不要在意。

en: =head2 Hello world
cn: =head2 Hello world

en: A Perl script is a text file with the extension .pl.
cn: 一个 Perl 脚本就是一个后缀为 .pl 的文本文件。

en: Here's the full text of helloworld.pl:
cn: 这就是 helloworld.pl 的全文:

  use strict;
  use warnings;

  print "Hello world";

en: Perl scripts are interpreted by the Perl interpreter, perl or perl.exe:
cn: Perl 脚本被 Perl 的解释器来解释运行:

  perl helloworld.pl [arg0 [arg1 [arg2 ...]]]

en: A few immediate notes. Perl's syntax is highly permissive and it will allow you to do things which result in ambiguous-looking statements with unpredictable behaviour. There's no point in me explaining what these behaviours are, because you want to avoid them.
cn: 说实话,Perl 的语法非常宽容,他可以替你预测一些模糊的不知所云的代码的行为,我实在不想讲这些东西,因为你们应当竭力避免这么做。

en: The way to avoid them is to put use strict; use warnings; at the very top of every Perl script or module that you create. Statements of the form use foo; are pragmas. A pragma is a signal to perl.exe, which takes effect when initial syntactic validation is being performed, before the program starts running. These lines have no effect when the interpreter encounters them at run time.
cn: 避免这么做的方法就是将 'use strict; use warnings' 放置在每一个脚本或模块的最前面。'use foo' 这样的语句是编译提示,编译提示是给 Perl.exe 的信号,在程序运行前,对解释器初始化语法验证规则施加影响。在代码运行的时候,解释器将忽略这些东西。

en: The symbol # begins a comment. A comment lasts until the end of the line. Perl has no block comment syntax.
cn: '#' 符号是一个注释的开始。注释的结束是到行的末尾。Perl 没有针对块的注释语法。

en: =head2 Variables
cn: =head2 变量

en: Perl variables come in three types: scalars, arrays and hashes. Each type has its own sigil: $, @ and % respectively. Variables are declared using my, and remain in scope until the end of the enclosing block or file.
cn: Perl 的变量有三种类型:标量,数组和散列。每种类型都有自己的前置符号:$, @ 和 % 分别代表这三种类型。变量使用 my 来声明,有效范围在闭合块范围内或到文件的末尾。

en: =head3 Scalar variables
cn: 标量变量

en: A scalar variable can contain:
cn: 一个标量变量可以包含:

=over 4

en: =item * undef (corresponds to None in Python, null in PHP)
cn: =item * undef (相当于 Python 中的 None, PHP 中的 null)

en: =item * a number (Perl does not distinguish between an integer and a float)
cn: =item * 一个数字( Perl 并不区分一个整型数字和浮点数字)

en: =item * a string
cn: =item * 一个字符串

en: =item * a reference to any other variable.
cn: =item * 一个指向别的变量的引用

=back

  my $undef = undef;
  print $undef; # prints the empty string "" and raises a warning

  # implicit undef:
  my $undef2;
  print $undef2; # prints "" and raises exactly the same warning
  my $num = 4040.5;
  print $num; # "4040.5"
  my $string = "world";
  print $string; # "world"

en: (References are coming up shortly.)
cn: (稍后介绍引用)

en: String concatenation using the . operator (same as PHP):
cn: 字符串使用 '.' 进行连接(和PHP一样)

  print "Hello ".$string; # "Hello world"

en: =head3 Booleans
cn: =head3 布尔值

en: Perl has no boolean data type. A scalar in an if statement evaluates to boolean "false" if and only if it is one of the following:
cn: Perl 没有布尔数据类型。只有如下几种值才能在 if 判断语句中返回 'false' :

=over 4

en: =item * undef
cn: =item * undef

en: =item * number 0
cn: =item * 数字 0

en: =item * string ""
cn: =item * 字符串 ""

en: =item * string "0"
cn: =item * 字符串 "0"

=back

en: The Perl documentation repeatedly claims that functions return "true" or "false" values in certain situations. In practice, when a function is claimed to return "true" it usually returns 1, and when it is claimed to return false it usually returns the empty string, "".
cn: Perl 文档中经常提到函数在某些情况下会返回 'true' 或 'false'. 实际上,函数通常用 'return 1' 来返回真,用返回空字符串 '' 来表示返回假。

en: =head3 Weak typing
cn: =head3 弱类型
作者: shijiang1130    时间: 2013-03-05 23:21
Perlvim 发表于 2013-03-05 17:04
翻得准确多了。我继续往下啊。
作者: shijiang1130    时间: 2013-03-05 23:37
  1. 获取信息的数据结构
  2. 这里有四个例子,其中最后一个是最有用的:
  3. 1.
  4. my $ownersRef = $account{"owners"};
  5. my @owners = @{ $ownersRef };
  6. my $owner1Ref = $owners[0];
  7. my %owner1 = %{ $owner1Ref };
  8. my $owner2Ref = $owners[1];
  9. my %owner2 = %{ $owner2Ref };
  10. print "Account #", $account{"number"}, "\n";
  11. print "Opened on ", $account{"opened"}, "\n";
  12. print "Joint owners:\n";
  13. print "\t", $owner1{"name"}, " (born ", $owner1{"DOB"}, ")\n";
  14. print "\t", $owner2{"name"}, " (born ", $owner2{"DOB"}, ")\n";

  15. 2.
  16. my @owners = @{ $account{"owners"} };
  17. my %owner1 = %{ $owners[0] };
  18. my %owner2 = %{ $owners[1] };
  19. print "Account #", $account{"number"}, "\n";
  20. print "Opened on ", $account{"opened"}, "\n";
  21. print "Joint owners:\n";
  22. print "\t", $owner1{"name"}, " (born ", $owner1{"DOB"}, ")\n";
  23. print "\t", $owner2{"name"}, " (born ", $owner2{"DOB"}, ")\n";

  24. 3.
  25. my $ownersRef = $account{"owners"};
  26. my $owner1Ref = $ownersRef->[0];
  27. my $owner2Ref = $ownersRef->[1];
  28. print "Account #", $account{"number"}, "\n";
  29. print "Opened on ", $account{"opened"}, "\n";
  30. print "Joint owners:\n";
  31. print "\t", $owner1Ref->{"name"}, " (born ", $owner1Ref->{"DOB"}, ")\n";
  32. print "\t", $owner2Ref->{"name"}, " (born ", $owner2Ref->{"DOB"}, ")\n";

  33. 4.
  34. print "Account #", $account{"number"}, "\n";
  35. print "Opened on ", $account{"opened"}, "\n";
  36. print "Joint owners:\n";
  37. print "\t", $account{"owners"}->[0]->{"name"}, " (born ", $account{"owners"}->[0]->{"DOB"}, ")\n";
  38. print "\t", $account{"owners"}->[1]->{"name"}, " (born ", $account{"owners"}->[1]->{"DOB"}, ")\n";

  39. 数组与数组引用
  40. 这个数组有五个要素:
  41. my @array1 = (1, 2, 3, 4, 5);
  42. print @array1; # "12345"

  43. 这个数组,有一个元素(是一个匿名引):
  44. my @array2 = [1, 2, 3, 4, 5];
  45. print @array2; # e.g. "ARRAY(0x182c180)"

  46. 这个标量是一个匿名引用:
  47. my $array3Ref = [1, 2, 3, 4, 5];
  48. print $array3Ref; # e.g. "ARRAY(0x22710c0)"
  49. print @{ $array3Ref }; # "12345"
  50. print @$array3Ref; # "12345"
复制代码

作者: shijiang1130    时间: 2013-03-06 00:09
  1. 条件
  2. if ... elsif ... else ...
  3. 在这里没有惊喜,除了拼写elsif:
  4. my $word = "antidisestablishmentarianism";
  5. my $strlen = length $word;
  6. if($strlen >= 15) {
  7. print "'", $word, "' is a very long word";
  8. } elsif(10 <= $strlen && $strlen < 15) {
  9. print "'", $word, "' is a medium-length word";
  10. } else {
  11. print "'", $word, "' is a a short word";
  12. }

  13. Perl提供了一个较短的语法,这是高度推荐的:
  14. print "'", $word, "' is actually enormous" if $strlen >= 20;

  15. unless ... else ...
  16. my $temperature = 20;
  17. unless($temperature > 30) {
  18. print $temperature, " degrees Celsius is not very hot";
  19. } else {
  20. print $temperature, " degrees Celsius is actually pretty hot";
  21. }

  22. unless通常最好避免使用,因为它们使程序难读懂。“unless[…else]“块可以重构到一个“if[…else]”块。幸运的是,没有elsunless关键字。

  23. 这个,相比之下,强烈推荐,因为它是如此容易阅读:
  24. print "Oh no it's too cold" unless $temperature > 15;

  25. 三元操作符
  26. The ternary operator ? : allows simple if statements to be embedded in a statement. The canonical use for this is singular/plural forms:
  27. 三目操作符?:允许简单的if语句嵌入在一个声明中。
  28. my $gain = 48;
  29. print "You gained ", $gain, " ", ($gain == 1 ? "experience point" : "experience points"), "!";

  30. 三元操作符可以嵌套:
  31. my $eggs = 5;
  32. print "You have ", $eggs == 0 ? "no eggs" :
  33. $eggs == 1 ? "an egg" :
  34. "some eggs";


  35. 循环
  36. 不止有一种方法来做。
  37. Perl有传统的while循环:
  38. my $i = 0;
  39. while($i < scalar @array) {
  40. print $i, ": ", $array[$i];
  41. $i++;
  42. }
  43. Perl还提供了until关键字:
  44. my $i = 0;
  45. until($i >= scalar @array) {
  46. print $i, ": ", $array[$i];
  47. $i++;
  48. }

  49. These do loops are almost equivalent to the above (a warning would be raised if @array were empty):
  50. do循环几乎相当于上述的例子(如果@array是空的将会有一个警告):
  51. my $i = 0;
  52. do {
  53. print $i, ": ", $array[$i];
  54. $i++;
  55. } while ($i < scalar @array);


  56. my $i = 0;
  57. do {
  58. print $i, ": ", $array[$i];
  59. $i++;
  60. } until ($i >= scalar @array);
  61. 基本的c风格的for循环也是可以的。
  62. for(my $i = 0; $i < scalar @array; $i++) {
  63. print $i, ": ", $array[$i];
  64. }

  65. 这种循环被认为是老式的,应该尽量避免这样使用。迭代列表是好得多。
  66. foreach my $string ( @array ) {
  67. print $string;
  68. }

  69. 操作符. .创建一个匿名的整数列表:
  70. foreach my $i ( 0 .. $#array ) {
  71. print $i, ": ", $array[$i];
  72. }

  73. 你不能遍历一个散列。然而,你可以遍历它的键值。使用键内置函数来检索一个数组包含所有键的一个散列。然后使用foreach方法,我们用于数组:
  74. foreach my $key (keys %scientists) {
  75. print $key, ": ", $scientists{$key};
  76. }

  77. Since a hash has no underlying order, the keys may be returned in any order. Use the sort built-in function to sort the array of keys alphabetically beforehand:
  78. 因为一个散列并没有顺序,键值可能在按任何顺序返回。使用排序内置函数事先按字母顺序排序数组的键:
  79. foreach my $key (sort keys %scientists) {
  80. print $key, ": ", $scientists{$key};
  81. }

  82. 如果你不提供显式迭代器,Perl使用一个默认的迭代器,$ _。$ _内置变量:
  83. foreach ( @array ) {
  84. print $_;
  85. }

  86. 如果使用默认的迭代器,你只希望把单个语句内部循环,您可以使用超短循环语法:
  87. print $_ foreach @array;

  88. 循环控制
  89. next and last can be used to control the progress of a loop. In most programming languages these are known as continue and break respectively. We can also optionally provide a label for any loop. By convention, labels are written in ALLCAPITALS. Having labelled the loop, next and last may target that label. This example finds primes below 100:
  90. next和last可用于控制循环的进展。在大多数编程语言这些被称为continue和break。我们还可以为任何循环提供一个label。按照惯例,lable所有字母都大写:
  91. CANDIDATE: for my $candidate ( 2 .. 100 ) {
  92. for my $divisor ( 2 .. sqrt $candidate ) {
  93. next CANDIDATE if $candidate % $divisor == 0;
  94. }

  95. print $candidate. " is prime\n";
  96. }
复制代码

作者: shijiang1130    时间: 2013-03-06 00:11
本帖最后由 shijiang1130 于 2013-03-07 23:06 编辑

2个小时的时间我觉得是很不够的,至少也得要8个小时
作者: xo1980    时间: 2013-03-06 09:18
))))))
作者: Perlvim    时间: 2013-03-06 13:01
本帖最后由 Perlvim 于 2013-03-06 23:13 编辑

未翻译的部分还有很多,大家谁有兴趣,可以一起翻译:

作者: Perlvim    时间: 2013-03-06 13:02
本帖最后由 Perlvim 于 2013-03-06 23:14 编辑

楼主是用 Google 翻译的吧,还是看英文明白点。
作者: Perlvim    时间: 2013-03-06 13:03
本帖最后由 Perlvim 于 2013-03-06 23:16 编辑

还是另外开一个帖子放置最后翻译的结果吧。
作者: Perlvim    时间: 2013-03-06 13:03
本帖最后由 Perlvim 于 2013-03-06 23:17 编辑

此帖已被删除
作者: shijiang1130    时间: 2013-03-06 23:43

  1. 数组函数
  2. 我们将使用数组@stack来演示:
  3. my @stack = ("Fred", "Eileen", "Denise", "Charlie");
  4. print @stack; # "FredEileenDeniseCharlie"
  5. pop提取和返回数组的最后一个元素。这可以被认为是堆栈的顶部:
  6. print pop @stack; # "Charlie"
  7. print @stack; # "FredEileenDenise"
  8. push附加额外的元素到数组的末尾:
  9. push @stack, "Bob", "Alice";
  10. print @stack; # "FredEileenDeniseBobAlice"

  11. shift提取并返回数组的第一个元素:
  12. print shift @stack; # "Fred"
  13. print @stack; # "EileenDeniseBobAlice"

  14. unshift在数组的开始插入新元素:
  15. unshift @stack, "Hank", "Grace";
  16. print @stack; # "HankGraceEileenDeniseBobAlice"
  17. pop,push,shift和unshift都特殊情况的拼接。splice移除并返回一个数组切片,取而代之的是一个不同的数组切片:
  18. print splice(@stack, 1, 4, "<<<", ">>>"); # "GraceEileenDeniseBob"
  19. print @stack; # "Hank<<<>>>Alice"

  20. 从旧的数组创建新的数组
  21. Perl提供了以下功能,作用于数组创建其他数组。
  22. join连接函数连接许多字符串为一个:
  23. my @elements = ("Antimony", "Arsenic", "Aluminum", "Selenium");
  24. print @elements; # "AntimonyArsenicAluminumSelenium"
  25. print "@elements"; # "Antimony Arsenic Aluminum Selenium"
  26. print join(", ", @elements); # "Antimony, Arsenic, Aluminum, Selenium"

  27. 在列表中上下文中,reverse函数以相反的顺序返回一个列表。在标量上下文,反向连接整个列表放在一起,然后反转它作为一个单独的词。
  28. print reverse("Hello", "World"); # "WorldHello"
  29. print reverse("HelloWorld"); # "HelloWorld"
  30. print scalar reverse("HelloWorld"); # "dlroWolleH"
  31. print scalar reverse("Hello", "World"); # "dlroWolleH"

  32. map函数将一个数组作为输入,并在这个数组对每一个标量$ _实行操作。然后构造一个新的数组。在一个表达式括号内提供操作执行的形式:
  33. my @capitals = ("Baton Rouge", "Indianapolis", "Columbus", "Montgomery", "Helena", "Denver", "Boise");
  34. print join ", ", map { uc $_ } @capitals;
  35. # "BATON ROUGE, INDIANAPOLIS, COLUMBUS, MONTGOMERY, HELENA, DENVER, BOISE"
  36. grep函数将一个数组作为输入,并返回一个过滤数组作为输出。其语法类似于map。这一次,第二个参数是评估每个标量$ _在输入数组。如果一个布尔真值返回,标量放入输出数组。
  37. print join ", ", grep { length $_ == 6 } @capitals;
  38. # "Helena, Denver"

  39. 显然,结果数组的长度是成功匹配的数量,这意味着您可以使用grep来快速检查是否包含一个元素的数组:
  40. print scalar grep { $_ eq "Columbus" } @capitals; # "1"

  41. grep and map may be combined to form list comprehensions, an exceptionally powerful feature conspicuously absent from many other programming languages.
  42. grep和map可以组合成列表理解, 其他一些编程语言缺少一个这样的特性。

  43. 默认情况下,sort函数返回按词法(字母)的顺序的输入数组,:
  44. my @elevations = (19, 1, 2, 100, 3, 98, 100, 1056);
  45. print join ", ", sort @elevations;
  46. # "1, 100, 100, 1056, 19, 2, 3, 98"
  47. 然而,类似于grep和map,你可以提供你自己的一些代码。排序总是比较两个元素。你收到$a和$b作为输入, 如果$a是<$ b,应该返回-1,$a=$b应该返回0,$a>$b, 应该返回1。

  48. 如果两个字符串比较就用cmp:
  49. print join ", ", sort { $a cmp $b } @elevations;
  50. # "1, 100, 100, 1056, 19, 2, 3, 98"
  51. 对数字就用 < = >:
  52. print join ", ", sort { $a <=> $b } @elevations;
  53. # "1, 2, 3, 19, 98, 100, 100, 1056"
  54. $a and $b are always scalars, but they can be references to quite complex objects which are difficult to compare. If you need more space for the comparison, you can create a separate subroutine and provide its name instead:
  55. $ a和$b总是标量,他们可以采用引用, 但相当复杂,很难比较。如果你需要更多的空间来比较,您可以创建一个单独的子程序,并提供它的名字来代替:
  56. sub comparator {
  57. # return -1, 0 or 1
  58. }
  59. print join ", ", sort comparator @elevations;

  60. 对于map和grep函数,你不能这样做,。
  61. Notice how the subroutine and block are never explicitly provided with $a and $b. Like $_, $a and $b are, in fact, global variables which are populated with a pair of values to be compared each time.
  62. 注意,子程序和块是从来没有明确地提供$a和$b。就像变量$ _, $ a和$b事实上是全局变量。
复制代码

作者: shijiang1130    时间: 2013-03-07 00:12
  1. 内置函数
  2. By now you have seen at least a dozen built-in functions: print, sort, map, grep, keys, scalar and so on. Built-in functions are one of Perl's greatest strengths. They
  3. 现在你已经看到至少一打内置功能:print、sort、map、grep、keys、scalar等等。内置函数是Perl的最大优点。他们•众多•非常有用•广泛记录
  4. •在语法差异很大,所以请核对文档
  5. •有时接受正则表达式作为参数
  6. •有时接受整个代码块作为参数
  7. •有时不需要逗号分隔参数之间
  8. •有时会使用任意数量的逗号分隔参数,有时不会
  9. •如果太少的参数,有时会用缺省的
  10. •一般不需要括号除了模棱两可的情况下

  11. 关于内置函数最好的建议是知道他们的存在。将来好进行文档备查。如果你正在进行一项任务,感觉这是很基础和常见,而且以前做很多次,很可能是它。

  12. 用户定义的子程序
  13. 子例程使用sub关键字。相比之下,与内置函数,用户定义的子程序总是接受相同的输入:标量的列表。这个列表可能当然有一个单一的元素,或者是空的。一个标量是作为一个列表,一个元素。一个散列与N个元素作为一个列表2 N个元素。
  14. 尽管括号是可选的,总是应该调用子程序使用方括号,即使称不带参数。这表明正在发生的子程序调用。
  15. 一旦你在子程序内部,参数可以使用内置数组变量@ _。示例:
  16. sub hyphenate {
  17. # Extract the first argument from the array, ignore everything else
  18. my $word = shift @_;
  19. $word = join "-", map { substr $word, $_, 1 } (0 .. (length $word) - 1);
  20. return $word;
  21. }

  22. print hyphenate("exterminate"); # "e-x-t-e-r-m-i-n-a-t-e"

  23. 解开传入的参数
  24. 有不止一种解压参数@ _的途径,但有些方法是优于其他方法的。
  25. 通常调用如下:
  26. print left_pad("hello", 10, "+"); # "+++++hello"

  27. 1。有些人不解压的,这是不鼓励的:
  28. sub left_pad {
  29. my $newString = ($_[2] x ($_[1] - length $_[0])) . $_[0];
  30. return $newString;
  31. }
  32. 第二种方式,仅解开参数
  33. sub left_pad {
  34. my $oldString = $_[0];
  35. my $width = $_[1];
  36. my $padChar = $_[2];
  37. my $newString = ($padChar x ($width - length $oldString)) . $oldString;
  38. return $newString;
  39. }
  40. 3。通过删除数据取出@ _,推荐使用转变为最多4个参数:
  41. sub left_pad {
  42. my $oldString = shift @_;
  43. my $width = shift @_;
  44. my $padChar = shift @_;
  45. my $newString = ($padChar x ($width - length $oldString)) . $oldString;
  46. return $newString;
  47. }

  48. If no array is provided to the shift function, then it operates on @_ implicitly. This approach is seen very commonly:
  49. 如果没有数组提供给shift函数,那么@_作为隐式的提供。这种方法被认为非常普遍:
  50. sub left_pad {
  51. my $oldString = shift;
  52. my $width = shift;
  53. my $padChar = shift;
  54. my $newString = ($padChar x ($width - length $oldString)) . $oldString;
  55. return $newString;
  56. }
复制代码

作者: shijiang1130    时间: 2013-03-07 13:31
  1. 超出4个参数难以追踪哪些正被分配的地方。
  2. 你可以解压的@ _去使用多个同时标量赋值。这是允许最多4个参数:
  3. sub left_pad {
  4. my ($oldString, $width, $padChar) = @_;
  5. my $newString = ($padChar x ($width - length $oldString)) . $oldString;
  6. return $newString;
  7. }

  8. 5. For subroutines with large numbers of arguments or where some arguments are optional or cannot be used in combination with others, best practice is to require the user to provide a hash of arguments when calling the subroutine, and then unpack @_ back into that hash of arguments. For this approach, our subroutine call would look a little different:
  9. 5。大量的参数或一些参数是可选的或不能用在与其它相结合的子程序,最佳实践是要求用户提供一个散列的参数调用子程序时,然后解压@ _回到散列的参数。对于这种方法,我们的子程序调用会看起来有点不同:
  10. print left_pad("oldString" => "pod", "width" => 10, "padChar" => "+");
  11. 子程序本身看起来像这样:
  12. sub left_pad {
  13. my %args = @_;
  14. my $newString = ($args{"padChar"} x ($args{"width"} - length $args{"oldString"})) . $args{"oldString"};
  15. return $newString;
  16. }

  17. 返回值
  18. 像其他Perl表达式、子程序调用与上下文的行为相关。您可以使用wantarray函数(这应该叫做wantlist但是没关系)来检测什么上下文子程序,并返回一个合适结果:
  19. sub contextualSubroutine {
  20. # Caller wants a list. Return a list
  21. return ("Everest", "K2", "Etna") if wantarray;
  22. # Caller wants a scalar. Return a scalar
  23. return 3;
  24. }

  25. my @array = contextualSubroutine();
  26. print @array; # "EverestK2Etna"
  27. my $scalar = contextualSubroutine();
  28. print $scalar; # "3"


  29. 系统调用
  30. 我重复你已经知道的以下非perl相关事实。每次一个过程完成后在Windows或Linux系统(我认为,在大多数其他系统),它包括了一个16位的状态字。最高的8位构成一个返回代码0和255之间的包容性,0代表不合格的成功,而其他值代表不同程度的失败。其他8位不经常检查——他们“反映模式的失败,如信号死亡和核心转储信息”。
  31. 你可以带返回码(从0到255)退出一个Perl脚本。
  32. Perl提供超过一个办法——在一个call - spawn子进程,暂停当前的脚本,直到子进程结束,然后恢复解释当前的脚本。使用哪种方法,你会发现,紧接着,内置的标量变量$ ?已填充状态字,回来子过程的终止。你可以返回代码以最高的8的16位:$ ?> > 8。
  33. The system function can be used to invoke another program with the arguments listed. The value returned by system is the same value with which $? is populated:
  34. 系统功能可用于调用另一个程序的参数列。系统通过$ ?返回的:
  35. my $rc = system "perl", "anotherscript. pl", "foo", "bar", "baz";
  36. $rc >>= 8;
  37. print $rc; # "37"

  38. 或者,您可以使用反引号``来运行一个实际的命令,在命令行和捕获标准输出命令。在标量上下文返回整个输出作为一个单一的字符串。在列表背景下,整个输出返回一个字符串数组,每一个代表一行输出。
  39. my $text = `perl anotherscript. pl foo bar baz`;
  40. print $text; # "foobarbaz"

  41. This is the behaviour which would be seen if anotherscript. pl contained, for example:
  42. 这是行为将可见的如果包含anotherscript.pl,例如:
  43. use strict;
  44. use warnings;
  45. print @ARGV;
  46. exit 37;


  47. 文件和文件句柄
  48. 一个标量变量可能包含一个文件句柄,而不是一个数字/字符串/参考或undef。一个文件处理本质上是一个引用一个特定的位置在一个特定的文件。

  49. 使用open将标量变量变成一个文件句柄。必须提供一个open模式。这个模式<表明我们希望打开文件阅读它:
  50. my $f = "text.txt";
  51. my $result = open my $fh, "<", $f;
  52. if(!$result) {
  53. die "Couldn't open '".$f. "' for reading because: ".$!;
  54. }

  55. 如果成功,返回真值。否则,它将返回false和错误消息在变量$ !里面。如上所述,你应该总是检查打开操作成功完成。这个检查是很乏味的,一个常见的是:
  56. open(my $fh, "<", $f) || die "Couldn't open '".$f. "' for reading because: ".$!;

  57. 注意在调用的参数需要括号。
  58. 从一个文件句柄读一行文本,使用readline内置函数。返回一个完整的文本, 它的末端包括一个换行符(除了可能对文件的最后一行),或者如果你到了undef文件的末尾。
  59. while(1) {
  60. my $line = readline $fh;
  61. last unless defined $line;
  62. # process the line...
  63. }

  64. 截断后面的换行符,使用chomp:
  65. chomp $line;

  66. Note that chomp acts on $line in place. $line = chomp $line is probably not what you want.
  67. 注意,chomp的用法。$line= chomp $line不是你想要的结果。
  68. 您还可以使用eof检测是否已经达到文件的末尾:
  69. while(! eof $fh) {
  70. my $line = readline $fh;
  71. # process $line...
  72. }


  73. But beware of just using while(my $line = readline $fh), because if $line turns out to be "0", the loop will terminate early. If you want to write something like that, Perl provides the <> operator which wraps up readline in a fractionally safer way. This is very commonly-seen and perfectly safe:
  74. 但要注意使用 while(my $line= readline $fh),因为如果$line 变成了“0”,循环将提前终止合同。如果你想写这样的东西,Perl提供< >操作符, 在一个安全的方式结束。这是很常见的,而且非常安全:
  75. while(my $line = <$fh>) {
  76. # process $line...
  77. }
  78. 甚至:
  79. while(<$fh>) {
  80. # process $_...
  81. }

  82. 写入文件涉及不同的模式。这个模式>表明我们希望打开文件写它。(>如果它已经存在并有内容,将覆盖已经存在。使用模式> >只是附加到现有文件)。然后,只需提供文件句柄作为一个输出参数。
  83. open(my $fh2, ">", $f) || die "Couldn't open '".$f. "' for writing because: ".$!;
  84. print $fh2 "The eagles have left the nest";

  85. 注意中间没有一个逗号第一和第二个参数
  86. 文件句柄实际上关闭时自动退出范围:
  87. close $fh2;
  88. close $fh;

  89. 三个文件句柄作为全局常量:STDIN、STDOUT和STDERR存在。这些都是自动打开脚本时开始。读取一行用户输入:
  90. my $line = <STDIN>;
  91. 只是等待用户回车:
  92. <STDIN>;
复制代码

作者: 方兆国儿    时间: 2013-03-07 19:42
7looki 发表于 2013-03-04 02:41
学习Perl用约2小时30分钟

光这几个字, 唉, 我就不想看翻译的了(虽然我的英语很差很差, 差到看不懂).

嘿嘿   友情支持
作者: shijiang1130    时间: 2013-03-07 20:51
  1. 调用没有文件句柄的< >,会从STDIN中读取数据,或从任何文件中。
  2. As you may have gathered, print prints to STDOUT by default if no filehandle is named.
  3. 如果没有文件句柄被命名, 默认情况下打印到STDOUT。

  4. 文件测试
  5. 功能- e是一个测试指定的文件是否存在的内置函数。
  6. print "what" unless -e "/usr/bin/perl";

  7. 功能- d是一个测试指定的文件是否为一个目录的内置函数。
  8. 功能- f是一个测试是否在指定的文件是纯文本文件的内置功能,。
  9. 这些只是三个大型类的函数的形式- X,X是一些小写或大写字母。这些函数被称为文件测试。注意前置”-”。在谷歌查询,”-”表示排除结果包含该搜索词。搜索“perl文件测试”可得到结果。

  10. 正则表达式

  11. 正则表达式出现在许多语言和工具里。Perl的核心正则表达式语法和在其他地方一样基本上是相同的,但Perl的正则表达式功能完整复杂和难以理解。我给你的最好建议是只要有可能避免这种复杂性。
  12. 执行匹配操作使用= ~ m / /。在标量上下文,= ~ m / /成功执行,将返回true;如果失败将返回false。
  13. my $string = "Hello world";
  14. if($string =~ m/(\w+)\s+(\w+)/) {
  15. print "success";
  16. }

  17. 括号执行子匹配。成功后执行匹配操作匹配得到的值在的变量$ 1,$ 2,$ 3,…:
  18. print $1; # "Hello"
  19. print $2; # "world"

  20. 在列表上下文,= ~ m / /返回$ 1,$ 2,…作为一个列表。
  21. my $string = "colourless green ideas sleep furiously";
  22. my @matches = $string =~ m/(\w+)\s+((\w+)\s+(\w+))\s+(\w+)\s+(\w+)/;
  23. print join ", ", map { "'".$_. "'" } @matches;
  24. # prints "'colourless', 'green ideas', 'green', 'ideas', 'sleep', 'furiously'"

  25. 替换操作执行使用= ~ s / / /。
  26. my $string = "Good morning world";
  27. $string =~ s/world/Vietnam/;
  28. print $string; # "Good morning Vietnam"

  29. 注意,$ string的内容已经改变了。你必须对标量变量操作。如果是一个文字字符串,你会得到一个错误。
  30. / g标志表示”组匹配”。
  31. 在标量上下文, ~ m / / g执行全文查找,成功,返回true;如果执行失败将返回false。你可以访问$1得到内容。例如:
  32. my $string = "a tonne of feathers or a tonne of bricks";
  33. while($string =~ m/(\w+)/g) {
  34. print "'".$1."'\n";
  35. }

  36. 在列表中上下文中,一个= ~ m / / g在一次调用返回所有的内容。
  37. my @matches = $string =~ m/(\w+)/g;
  38. print join ", ", map { "'".$_. "'" } @matches;

  39. 一个= ~ s / / / g调用执行全文搜索/替换并返回匹配的数量。在这里,我们替换所有元音字母“r”。
  40. #试一试没有/ g。
  41. $string =~ s/[aeiou]/r/;
  42. print $string; # "r tonne of feathers or a tonne of bricks"

  43. $string =~ s/[aeiou]/r/;
  44. print $string; # "r trnne of feathers or a tonne of bricks"

  45. #和使用/ g
  46. $string =~ s/[aeiou]/r/g;
  47. print $string, "\n"; # "r trnnr rf frrthrrs rr r trnnr rf brrcks"

  48. /I 使匹配和替换不区分大小写的。
  49. / x标志允许您的正则表达式包含空格(例如。、换行符)和评论。
  50. "Hello world" =~ m/
  51. (\w+) # one or more word characters
  52. [ ] # single literal space, stored inside a character class
  53. world # literal "world"
  54. /x;
  55. #返回true
复制代码

作者: shijiang1130    时间: 2013-03-07 22:12
  1. 模块和包
  2. 在Perl中模块和包是不同的东西。

  3. 模块
  4. 一个模块是一个.pm文件,您可以包括在另一个Perl文件(脚本或模块)。语法和.pl Perl脚本完全相同。一个示例模块: C:\foo\bar\baz\Demo\StringUtils. pm 或 /foo/bar/baz/Demo/StringUtils. Pm :
  5. use strict;
  6. use warnings;
  7. sub zombify {
  8. my $word = shift @_;
  9. $word =~ s/[aeiou]/r/g;
  10. return $word;
  11. }

  12. return 1;

  13. 因为一个模块从上到下执行加载时,您需要返回真值最后表明它已经成功加载。
  14. 为了Perl解释器可以找到他们, Perl模块应该列入你的环境变量$ PERL5LIB:
  15. set PERL5LIB=C:\foo\bar\baz;%PERL5LIB%

  16. export PERL5LIB=/foo/bar/baz:$PERL5LIB

  17. Once the Perl module is created and perl knows where to look for it, you can use the require built-in function to search for and execute it during a Perl script. For example, calling require Demo::StringUtils causes the Perl interpreter to search each directory listed in PERL5LIB in turn, looking for a file called Demo/StringUtils.pm. After the module has been executed, the subroutines that were defined there suddenly become available to the main script. Our example script might be called main. pl and read as follows:
  18. 一旦Perl模块创建而且Perl知道在哪里寻找它,你可以使用 require内置函数搜索并执行它在。例如,调用 require Demo::StringUtils使Perl解释器来搜索列在PERL5LIB环境变量里的每个目录,寻找一个文件叫做Demo/ StringUtils.pm。如下:
  19. use strict;
  20. use warnings;
  21. require Demo::StringUtils;
  22. print zombify("i want brains"); # "r wrnt brrrns"

  23. 注意,使用双冒号::作为目录分隔符。

  24. 现在的问题是,:如果main.pl包含许多require调用,每个模块又包含更多的require调用,然后它难以追踪原始的zombify()子程序。这个问题的解决方案是使用包。


  25. A package is a namespace in which subroutines can be declared. Any subroutine you declare is implicitly declared within the current package. At the beginning of execution, you are in the main package, but you can switch package using the package built-in function:
  26. 一个包是一个子程序声明的名称空间。任何子程序隐式声明在当前的包。执行开始时,你在main包,但你可以用内置package函数切换包:
  27. use strict;
  28. use warnings;
  29. sub subroutine {
  30. print "universe";
  31. }

  32. package Food::Potatoes;
  33. # no collision:
  34. sub subroutine {
  35. print "kingedward";
  36. }

  37. 注意,使用双冒号::作为一个名称空间分隔符。
  38. 任何时间你调用子程序,默认在当前的包。或者,您可以显式地指定一个包名。看看会发生什么,如果我们继续上面的脚本:
  39. subroutine(); # "kingedward"
  40. main::subroutine(); # "universe"
  41. Food::Potatoes::subroutine(); # "kingedward"

  42. 所以逻辑解决上述问题是修改 C:\foo\bar\baz\Demo\StringUtils. pm or /foo/bar/baz/Demo/StringUtils. pm

  43. use strict;
  44. use warnings;
  45. package Demo::StringUtils;
  46. sub zombify {
  47. my $word = shift @_;
  48. $word =~ s/[aeiou]/r/g;
  49. return $word;
  50. }

  51. return 1;

  52. 和修改main.pl:
  53. use strict;
  54. use warnings;
  55. require Demo::StringUtils;
  56. print Demo::StringUtils::zombify("i want brains"); # "r wrnt brrrns"

  57. 现在仔细读一下。
  58. 包和模块是两个完全独立的和独特的特征的Perl编程语言。事实上,他们都使用相同的双冒号分隔符是让人觉得模棱两可。
  59. 分离这两个概念是最愚蠢的一个特性的Perl,并把它们当作单独的概念会不可避免地导致混乱,令人发狂的代码。对我们来说幸运的是,大多数的Perl程序员遵守以下两个定律:
  60. 1。一个Perl脚本(.pl文件)必须始终包含完全零包声明。
  61. 2。一个Perl模块(.pm文件)必须始终包含一个包声明,对应其名称和位置准确。如模块 Demo/ StringUtils。必须用 package Demo::StringUtils 作为第一行。
  62. 正因为如此,在实践中你会发现,大多数“包”和“模块”可以被认为和指互换。然而,重要的是,你不要把这是理所当然的,因为有一天你会遇到一个疯子的代码。
复制代码

作者: shijiang1130    时间: 2013-03-07 22:39


  1. 杂项笔记
  2. •核心模块Data::Dumper可以用来输出任意标量到屏幕上。这是一个基本的调试工具。
  3. •有另一个语法,qw { },为声明数组。这是经常出现在使用语句:
  4. use Account qw{create open close suspend delete};

  5. •In =~ m// and =~ s/// operations, you can use braces instead of slashes as the regex delimiters. This is quite useful if your regex contains a lot of slashes, which would otherwise need escaping with backslashes. For example, =~ m{///} matches three literal forward slashes, and =~ s{^https? ://}{} removes the protocol part of a URL.
  6. •在= ~ m / /和= ~ s / / /操作,您可以使用括号代替斜杠分隔符的正则表达式。这是非常有用的,如果你的正则表达式包含大量的斜杠,否则需要与反斜杠转义。例如,= ~ m { / / / }匹配三个字面斜杠,{ ^ = ~年代https吗?:/ / } { }解除协议的一部分,一个URL。
  7. •Perl does have CONSTANTS. These are discouraged now, but weren't always. Constants are actually just subroutine calls with omitted brackets.
  8. •Perl确实有常量。这些是气馁了,但不总是。常数实际上只是子程序调用与省略括号。
  9. •Sometimes people omit quotes around hash keys, writing $hash{key} instead of $hash{"key"}. They can get away with it because in this situation the bareword key occurs as the string "key", as opposed to a subroutine call key().
  10. •有时人们忽略引号散列键、写$hash{key}而不是$hash{“key”}。他们可以这样做,因为在这种情况下,bareword关键是字符串“key”,与子程序调用键()。
  11. •如果你看到一块非格式化代码包装在一个分隔符,像< < EOF、你就要用关键词“here-doc”来搜索答案。

  12. •警告!很多内置函数可以调用不带参数,使用变量$ _。希望这将有助于你理解:
  13. print foreach @array;
  14. and
  15. foreach ( @array ) {
  16. next unless defined;
  17. }

  18. 我不喜欢这种阵型,因为当重构它可以导致问题。

  19. ----      <全剧终>   -----
复制代码





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2