第一章 Perl 哲学

Perl语言非常灵活,语法上相对宽容(有的语言则非常严苛)。程序员可以使用Perl干任何事--从单行程序、一次性的自动化测试到为期数年、多人协作的大工程,Perl均能胜任。
只要你确定了解决问题的方法,Perl就会无条件按照你的意思去做。Perl是实用的,但效果取决于你自己。

在接下来的时间里,你将学习Perl相关的知识,你会明白Perl语言是如何工作的以及为什么会这样工作,这些知识将足以支撑你编写出实用的Perl程序。Modern Perl不仅包含了这些知识点,并且还集合了全球Perl社区的经验来帮助你写出实用、可维护的Perl代码。

首先,你需要知道的就是如何学习。

Perldoc

Perl历来有着良好的文档传统,自带了数千页的文档。perldoc是Perl自带的一个专门用来查看Perl文档的命令行工具,可以用它来查看已安装模块的文档--无论是核心模块还是来自于CPAN的模块。

使用perldoc查看文档的例子:

$ perldoc List::Util
$ perldoc perltoc
$ perldoc Moose::Manual

第一个例子会显示 List::Util 模块的文档;
第二个例子会显示核心模块perldoc的文档;
第三个例子将显示Moose模块(来自CPAN的模块)的文档。
perldoc并不区分模块是自带的(核心模块)还是来自CPAN,据说这种一致性将会促进外部模块的文档质量向核心(系统)文档靠拢。

标准的模块文档将包含:模块介绍,使用示例,模块/接口的细节说明。虽然文档的篇幅和数量会因模块而不同,但文档的组成结构都是一致的。

如何阅读文档
Perl文档众多,从哪开始呢?

perldoc perlfaq 查看关于Perl的经常被问到的问题及答案
perldoc perlop 查看Perl的操作符及优先级
perldoc perlsyn 查看Perl的的语法结构
perldoc perldiag 查看警告和错误相关的内容
perldoc perlvar 查看与变量相关的内容

浏览这些文档将帮助你对Perl语言有个大致的了解,在遇到Perl问题时也更容易找到原因及解决方法。

perldoc还有些功能选项(详见 perldoc perldoc)。

比如使用 -q 选项可以进行关键字搜索,如 perldoc -q sort 将可能搜到:
How do I sort an array by (anything)?
How do I sort ahash (optionally by value instead of key)?
How can I always keep my hash sorted?

一些选项说明:
-f 选项将用于内置函数,如 perldoc -f sort 将显示sort操作符的说明
-v 选项用于内置变量, 如 perldoc -v $PID 将显示变量$PID的说明
-l 选项用于查看文档的位置(而不是内容),如 perldoc -l perldoc 将显示perldoc文件的位置
-m 选项显示模块的所有内容,包括代码(无特别格式),如,perldoc -m strict 显示strict模块的所有内容

表现力

Larry Wall 是研究语言学和人类语言的。他所发明的Perl跟其他编程语言有很大的不同:其他编程语言都是围绕数学概念设计的,而Perl的设计模拟了人与人之间的交流。这样设计带来的优势是:你可以更自由的表达你的想法。
你可以使用多种方法来解决问题,所以你可以选择写出最有效率的,或者是最具可读性的,或者是最省事的,或者是最有趣的程序。Its up to you!

比如需要将一组数字变成原来的3倍。有可能是这么写的:

     my @tripled;
     for my $num (@numbers)
     {
          push @tripled, $num * 3;
     }

还有可能:

     my @tripled;
     for (my $i = 0; $i < scalar @numbers; $i++)
     {
          $tripled[$i] = $numbers[$i] * 3;
     }

也能这么写:

my @tripled = map { $_ * 3 } @numbers;

做同样的事情,不同的方式。

学习Perl有点类似学习一门口语。你只需要学习少量的词汇,就能享受交流(编程)的乐趣,勤加练习(读、写代码)就能彻底掌握。你可以不必要理解Perl的每一个细节就能变得高效而多产。本章会介绍一些原则性的内容,这些内容对你成长为一个Perl程序员是至关重要的。

Perl里的某些句法结构对于新手来说可能有点难度,容易感到迷糊。但是Perl的原则是:做事的方法不只一种,所以只要我们愿意就能避开这些,待熟悉Perl之后再来看看,或许这时那些些“怪异的结构”在你手里能够发挥出神奇的作用。

Perl强悍的表现力可以为大师所用创造出令人惊叹的程序,但也容易让新手犯错。经验和品位将引导你如何设计代码,你可以尽情地表现你自己。

作为另一个设计目标,Perl能理解你的想法。比如,2个变量相加($first_num + $second_num),因为你使用了数值操作符”+“号,表达出来的意思就是将它们看成数值来相加,所以不管$first_num 和 $second_num的内容是什么,Perl都会将它们看成数值,再相加。(这通常就是你想要的)

随着经验的丰富,你会发现更多专注的是做什么而不是怎么去做。

语境

口头语言中,一个词语或者句子表达的真实意思需要通过语境来确定。Perl也有语境的概念,比如有些Perl的操作符在不同的语境下将展现截然不同的行为。所以当你读、写Perl代码时,得结合上下文语境才能正确的理解和表达。

空语境,标量语境,列表语境

当你调用一个函数,并且不使用它的返回值时,你就使用了空语境。例如调用一个叫“find_chores()" 的函数:

find_chores();

如果将返回值赋值给一个标量,这就指定了标量语境,函数将表现为标量语境下的行为:

my $single_result = find_chores();

如果将函数的返回值赋值给一个数组、列表,或者在列表中使用,那么函数就处在列表语境中:

my @all_results = find_chores();
my ($single_element, @rest) = find_chores();

单一元素的列表,还是列表,所以也是列表语境:

my ($single_element) = find_chores();

函数在不同的语境下可能产生不同的行为,如果语境不对,结果可能与预期的不一致:

my %results =(
     cheap_operation => $cheap_results,
     expensive_operation => find_chores(),  # 列表语境下的行为,可能不是你所期望的
);

这时可以使用关键词明确指定为标量语境:

my %results =
(
     cheap_operation => $cheap_results,
     expensive_operation => scalar find_chores(),
);

数值语境,字符串语境,布尔语境

操作符也会提供相应的语境,在前面的例子中我们看到,使用“+”号时,Perl会变量解析为数值,其实就是加号操作符提供了数值语境。

使用字符串操作符时,就会提供字符串语境。如操作符“eq”:

say "Catastrophic crypto fail!" if $alice eq $bob;

注意和下面这个的区别,数值操作“==”提供的是数值语境:

say "Catastrophic crypto fail!" if $alice == 'Bob';

布尔语境,出现在条件语句里面。比如上面的 if语句后面的表达式就是布尔语境。

在某些罕见的情况下,可能需要更为明确的指明语境:

my $numeric_x = 0 + $x; # forces numeric context
my $stringy_x = '' . $x; # forces string context
my $boolean_x = !!$x; # forces boolean context

如果知道了什么操作符提供什么语境,就能少犯错误。

默认行为

Perl代码起初看起来似乎有点罗嗦,但这里面是有捷径的。有经验的程序员可以充分使用这些捷径来精简代码。 捷径之一是语境,另一个就是默认变量。

默认标量变量

默认标量标量: $_ , 是最著名的默认变量。很多Perl的内置操作符在不提供操作变量时,默认操作对象就是$_。
当然你可以显式指定它,但更常见的情况是被省略了。
下面2行意思是一样的:

chomp $_;
chomp;

像这样默认操作$_的操作符有:
打印类 print,say;
标量操作类 chr,ord,lc,length,reverse, 正则等等。

print; #打印 $_到当前句柄,也就是输出$_的内容
say; # 打印 $_ \n到当前句柄,也就是输出$_的内容,再加一个换行符

$_ = 'My name is Paquito';
say if /My name is/;#默认使用$_匹配,正则类

s/Paquito/Paquita/; #默认使用$_替换,正则类

foreach (1 .. 10) #默认使用$_变量
{
say "#$_";
}

while (<STDIN>)#默认使用$_变量
{
chomp;#默认使用$_变量
say scalar reverse;#默认使用$_变量
}

my @squares = map { $_ * $_ } 1 .. 10;#默认使用$_变量

say 'Brunch time!'  if grep { /pancake mix/ } @pantry;#默认使用$_变量

当然你也可以使用其他变量:

while (my $line = <STDIN>)
{
...
}

默认数组变量

Perl还提供了2个默认的数组变量。
在调用函数时,传递的参数就存在默认数组变量 @_ 里面。在函数内部,数组操作符默认就是操作这个数组变量。下面2段代码是等价的:

sub foo
{
my $arg = shift;
...
}

sub foo_explicit_args
{
my $arg = shift @_;
...
}

如果$_对应的意思是“那个”,那么@_对应的意思就是“那些”。
数组变量@_是每个函数内部私有的,不同函数之间互不影响。
如果在所有函数的外面,默认的数组变量就是@ARGV,里面包含了该程序的命令行参数。

@ARGV有自己的个性。如果你是使用钻石操作符(<>)读取空的文件句柄,Perl就会自动以@ARGV里面的元素为名字,读取对应的文件,如果@ARGV为空,Perl就从标准输入STDIN里读取。我们可以利用这个特性写个短小精悍的程序,如将输入的字符串逆序输出:

while (<>)
{
chomp;
say scalar reverse;
}

为什么要加上scalar呢?这个问题容易把人带偏,还多亏了perlchina群里同学的讨论。根本原因就是:如果在列表语境下,reverse并不默认操作$_ 。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容

  • Perl 哲学 Perl 是一种能“干实事”的语言。它灵活、宽容、可塑。在一名编程能者的手中,它可以 完成几乎所有...
    firefive阅读 1,375评论 1 11
  • 2010 第二天:用main函数控制命令行交互 2010 年 Perl6 圣诞月历(二)用 main 函数控制命令...
    焉知非鱼阅读 472评论 0 0
  • Perl 6 from Ruby - Nutshell 基本语法 语句结束分号 Ruby 使用换行(有几个例外)来...
    焉知非鱼阅读 758评论 0 1
  • 2016-10-20 号更新。 源文件可以在 github 或 perl6.org上找到. General Rak...
    焉知非鱼阅读 977评论 0 0
  • 披散的长发,淡蓝的衣裳,纤瘦的身躯,轻盈的步伐,她和朋友一起,跑着,跳着,笑着,银铃般的笑声,穿过了整个时空。 那...
    小样儿blue阅读 188评论 2 3