[译]Perl启蒙教程 第一部分
时间:2008-01-04 来源:yunyuaner
Perl启蒙教程
(第一部分)
by Doug Sheppard
October 16, 2000
欢迎进入Perl的世界
Perl犹如脚本语言中的瑞士军刀,富有威力而适应力强。它首先由工作于NASA的一位名叫Larry Wall的系统管理员发明,目的在于使报告处理更为便捷。从那以后,Perl被注入了很多新的角色:自动化系统管理,扮演不同系统间的粘合剂;以及,勿庸置疑,最流行的CGI网络编程语言。
当互联网时代到来,为什么Perl变得如此受欢迎呢?原因有二:其一,web应用中涉及到最多的是文本,Perl在当时,比起相应的替代品要略好。C语言既复杂又有可能制造安全方面的问题(尤其是在处理一些可信度低的数据时),Tcl可能会很笨拙而Python在那时还尚未有立足之地。
将Perl称之为一门友好的语言并不过分。它可以与你个人的编程风格配合的很好。Perl所倡导的是“解决某问题的方式并不单一”,这使得它在处理大小问题上异曲同工。
在本序列的第一部分中,你将学习一些有关Perl的基础知识,同时看到一个小型的示例程序。
一句话关于操作系统
在本序列中,我将假设你正使用Unix操作系统,你的Perl解释器安放在/usr/local/bin/perl路径下。当然,你正使用windows也无大碍;绝大多数Perl代码是与系统无关的。
你的首个Perl程序
将下面的代码编辑为first.pl文件并保存
#!/usr/local/bin/perl
print "Hi there!\n";
(按照惯例,第一个程序一般被假设为Hello Word程序,但我并非那种循规蹈矩的人)
现在,利用你的Perl解释器运行它。跳转到first.pl所在目录,接着键入perl first.pl。你应该会得到如下输出:
Hi there!
\n符号表示一个新行;没有它,Perl并不会自行跳转到下一行。
函数和声明
Perl拥有强大的函数库。它们是Perl语言中的动词,Perl解释器借以执行的命令。你可以在Perlfunc手册页看到所有Perl内建函数的列表。几乎所有的函数都会有一个由逗号分割开的参数列表。
print函数是使用频率最高的Perl函数之一。你可以使用它在屏幕上输出信息或者将信息保存至文件(后者是我们将在第二部分讨论的话题)。待输出的信息被作为函数传递给print函数。
print "This is a single statement.";
print "Look, ", "a ", "list!";
一个Perl程序由声明组成,每一个声明以一个分号结束。各声明不需要占据单独的行;一行多个声明和单个声明占据多行都是允许的。
print "This is "; print "two statements.\n"; print "But this ",
"is only one statement.\n";
数字、字符串和引号
Perl语言中有两种基本的数据类型:数字和字符串
数字很容易被理解,我们总是与它们打交到。你唯一需要记住的是,绝不要在数字之间插入逗号或者空格。你可以写10000,但千万不要写成10,000或者10 000。
字符串较之数字要复杂一些。一个字符串是用单引号或者双引号括起来的字符的集合:
'This is a test.'
"Hi there!\n"
单引号和双引号字符串的区别在于,单引号字符串的内容就是引号中的字面内容而双引号中的内容会被解释。例如,转意字符\n在双引号字符串中被视为一个新行,而它在单引号字符串中就是一个反斜线和n。
print "This string\nshows up on two lines.";
print 'This string \n shows up on only one.';
(其它两个常用的转意字符是\t和\\,前者代表一个制表符,后者用于在双引号字符串中插入一个反斜线。)
变量
如果说函数是Perl语言中的动词,那么变量就是名词。Perl语言中有三种类型的变量:标量、数组和散列。你可以把他们想象为“一般物体”、“列表”和“字典”。在Perl中,所有的变量名都是由一个标点符号紧跟字母或下划线开头的标识符。
标量指代单一实物,例如一个数字或字符串。标量名称以美元符号$开头,例如$i或者$abacus。你可以向标量变量赋值,例如:
$i = 5;
$pie_flavor = 'apple';
$constitution1776 = "We the People, etc.";
你无需指明标量变量到底是数字还是字符串,这并不重要。因为在Perl语言可以视情况而定,这种转换是自动的。(这点可能与别的编程语言不同,有的语言将数字和字符串视为不同类型)
如果你在双引号字符串中插入某标量变量,Perl会将其展开。
$apple_count = 5;
$count_report = "There are $apple_count apples.";
print "The report is: $count_report\n";
最终输出的字符串是:The report is: There are 5 apples.
数字在Perl中可以被施加各种数学操作,如加、减法、乘、除。(顺便指出的是,乘法和除法分别用*和/符号指代)
$a = 5;
$b = $a + 10; # $b is now equal to 15.
$c = $b * 10; # $c is now equal to 150.
$a = $a - 1; # $a is now 4, and algebra teachers are cringing.
你同样可以使用像++.--,+=,-=,/=和*=这样特殊的操作符。它们可以在等式中操作标量数值而不使用两个操作数。
$a = 5;
$a++; # $a is now 6; we added 1 to it.
$a += 10; # Now it's 16; we added 10.
$a /= 2; # And divided it by 2, so it's 8.
$a = "8"; # Note the quotes. $a is a string.
$b = $a + "1"; # "1" is a string too.
$c = $a . "1"; # But $b and $c have different values!
字符串在Perl中没有太多的灵活性可言,除了最基本的合并操作外。当然,合并和相加是两个不同的概念。切记,Perl会在需要时将字符串透明的转换成数字,所以,为了得到$b的值,Perl解释器会将“8”和“1”转换成数字并相加,最后得到9。与此相对应的是,$c使用连接操作,因此它的值是“81”
记住,加号用于把数字相加而点号用于拼接字符串。
数组是一系列标量组成的列表,它的名称由@开头。你可以用圆括号括起来,由逗号分隔开的内容定义一个数组。
@lotto_numbers = (1, 2, 3, 4, 5, 6); # Hey, it could happen.
@months = ("July", "August", "September");
数组中的内容从0开始索引。(为什么不是1呢?因为这是计算机的哲学)。为了获取字符串中的元素,你可以用$符号替代@符号,然后加上你要引用元素的索引号。(之所以用$符号是因为这时候你所引用的是标量值)。你同样可以修改它,如同修改其他标量变量一样。
@months = ("July", "August", "September");
print $months[0]; # This prints "July".
$months[2] = "Smarch"; # We just renamed September!
如果某个数组并不存在呢?在你对他赋值前,它会被自动的创建。
$winter_months[0] = "December"; # This implicitly creates @winter_months.
数组始终保持着各元素之间的次序;如果你要从头到尾遍历数组@months,无论多少次,你总会得到July, August和September这样的顺序。你可以使用$#array_name获取数组的长度,但它仅仅是数组最后一个元素的索引值,即数组元素个数减1。如果数组并不存在,$#array_name自然就是-1了。如果你想改变数组的长度,那改变$#array_name的值就可以了。
@months = ("July", "August", "September");
print $#months; # This prints 2.
$a1 = $#autumn_months; # We don't have an @autumn_months, so this is -1.
$#months = 0; # Now @months only contains "July".
散列在许多其他的编程语言中被称之为字典。它通常由条款和定义的二元组,或者更确切的讲,键值对组成。每一个键有着唯一确定的值与之对应。散列的名字由一个百分号开头,如%parents。你可以用逗号隔开的键值对定义散列,例如:
%days_in_month = ( "July" => 31, "August" => 31, "September" => 30 );
你可以通过诸如$hashname{key}的方式从散列中获取key对应的值,或者如同修改标量变量一样修改它的。
print $days_in_month{"September"}; # 30, of course.
$days_in_month{"February"} = 29; # It's a leap year.
如果你想知道散列中都包含了哪些键,你可以使用内建的keys函数,同时把要查看散列的名字作为参数传递给该函数。Keys函数返回一个由当前散列中所有键所构成的列表,在这个列表中,键的顺序可能与当初创建散列时的顺序不同。也就是说,当我们可以预期@months数组将始终返回July, August, September这样的顺序的同时,keys %days_in_summer可能不会保持那样的顺序。
@month_list = keys %days_in_summer;
# @month_list is now ('July', 'September', 'August') !
值得一提的是,上面提到的三类变量拥有相互独立的名字空间。也就是说,$abacus和@abacus是两个不同的变量,而$abacus[0](@abacus数组的第一个元素)和$abacus{0}(键0在散列%abacus中对应的值)是截然不同的。
注释
注意到在前几节的程序中,我使用了注释。它们有助于说明某段特殊的代码干了些什么,同时它对于某段你计划将要修改、增强、维护或者再浏览一遍的程序来说也是至关重要的。(简而言之,注释对于程序来说意义非常)
任何跟在#符号后的字符都被视为注释(当然,毋庸赘述,除非#符号出现在字符串中)
print "Hello world!\n"; # That's more like it.
# This entire line is a comment.
循环
几乎你每次编写程序时都会用到循环。循环允许你重复的执行某段代码。这部分在程序设计概念中被称之为流程控制。
Perl拥有几种不同的用于流程控制的函数(译注:原文将for视为function),其中最基本的是for。当你使用for函数时,你通常会指定一个列表变量和一个用于标识列表索引的标量变量,同时放置任何你需要循环执行的代码于循环结构的大括号以内。
for $i (1, 2, 3, 4, 5) {
print "$i\n";
}
上述代码打印1到5的数字,每个数字占一行。
一个用于指定某范围内连续的数字的便捷方法是使用..符号。你可以把(1, 2, 3, 4, 5)简写为(1..5)。数组变量和标量变量均可以用于循环列表。尝试以下代码,看看会发生什么:
@one_to_ten = (1 .. 10);
$top_limit = 25;
for $i (@one_to_ten, 15, 20 .. $top_limit) {
print "$i\n";
}
循环列表中的项并非仅局限于数字,使用字符串也是允许的。如果散列%month_has包含每个月的天数,你可以使用keys函数来遍历它。
for $i (keys %month_has) {
print "$i has $month_has{$i} days.\n";
}
for $marx ('Groucho', 'Harpo', 'Zeppo', 'Karl') {
print "$marx is my favorite Marx brother.\n";
}