这是 perlsyn 命令,可以使用我们的多个免费在线工作站之一在 OnWorks 免费托管服务提供商中运行,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器
程序:
您的姓名
perlsyn - Perl 语法
商品描述
Perl 程序由一系列声明和语句组成,这些声明和语句从
从上到下。 循环、子程序和其他控制结构允许您跳转
在代码中。
Perl 是一个 自由形式 语言:您可以随意格式化和缩进。 空白
主要用于分离令牌,不像 Python 之类的语言,它是一个重要的
语法的一部分,或者 Fortran 不重要的部分。
Perl 的许多语法元素是 可选. 而不是要求你把
每个函数调用周围的括号并声明每个变量,你可以经常离开
关闭这些明确的元素,Perl 会明白你的意思。 这被称为 Do
什么是 I 平均值,缩写 数据管理. 它允许程序员 懒惰 并以一种风格编码
他们感到舒服。
Perl的 借 句法 以及来自多种语言的概念:awk、sed、C、Bourne Shell、
Smalltalk、Lisp 甚至英语。 其他语言借鉴了 Perl 的语法,
特别是它的正则表达式扩展。 所以如果你在另一个
语言你会在 Perl 中看到熟悉的部分。 它们的工作方式通常相同,但请参阅 perltrap
有关它们如何不同的信息。
声明
您需要在 Perl 中声明的唯一内容是报告格式和子例程(以及
有时甚至不是子程序)。 标量变量保存未定义的值(“undef”)
直到它被分配了一个定义的值,这个值不是“undef”。 什么时候
用作数字时,“undef”被视为 0; 当用作字符串时,它被视为
空字符串,“”; 当用作未分配给的引用时,它被视为
作为错误。 如果您启用警告,您将收到未初始化值的通知
每当您将“undef”视为字符串或数字时。 嗯,通常。 布尔上下文,
的条件,如
如果 ($a) {}
免于警告(因为他们关心真相而不是定义)。
诸如“++”、“--”、“+=”、“-=”和“.=”等运算符,它们对未定义的变量进行操作
的条件,如
未定义 $a;
$a++;
也总是免于此类警告。
声明可以放置在语句可以放置的任何位置,但对语句的执行没有影响
语句的主要序列:声明都在编译时生效。 全部
声明通常放在脚本的开头或结尾。 然而,如果
您正在使用由“my()”、“state()”或
“our()”,您必须确保您的格式或子程序定义在相同的范围内
如果您希望能够访问这些私有变量,则块作用域为 my。
声明子例程允许将子例程名称用作列表运算符
从这一点开始,在程序中。 你可以声明一个子程序而不定义它
通过说“子名称”,因此:
子我的名字;
$me = myname $0 or die "can't get myname";
像这样的裸声明将函数声明为列表运算符,而不是一元
运算符,因此您必须小心使用括号(或“或”而不是“||”。)
“||” 运算符绑定太紧,无法在列表运算符之后使用; 它成为最后的一部分
元素。 您始终可以在列表运算符参数周围使用括号将
list 操作符回到更像函数调用的东西中。 或者,
您可以使用原型 "($)" 将子程序转换为一元运算符:
子我的名字($);
$me = 我的名字 $0 || 死“不能得到我的名字”;
现在按照您的预期进行解析,但您仍然应该养成使用的习惯
在这种情况下的括号。 有关原型的更多信息,请参阅 perlsub。
子程序声明也可以用“require”语句加载或两者都加载
并使用“use”语句导入到您的命名空间中。 有关这方面的详细信息,请参阅 perlmod。
一个语句序列可能包含词法范围变量的声明,但分开
从声明一个变量名开始,声明就像一个普通的语句,并且是
在语句序列中详细阐述,就好像它是一个普通语句一样。 那
意味着它实际上同时具有编译时和运行时效果。
留言
从“#”字符到行尾的文本是注释,将被忽略。
例外情况包括字符串或正则表达式中的“#”。
简易 声明
唯一一种简单的语句是对其副作用进行评估的表达式。 每一个
简单语句必须以分号结束,除非它是
一个块,在这种情况下分号是可选的。 但无论如何都要加上分号,如果
块占用不止一行,因为您最终可能会添加另一行。 注意
有像“eval {}”、“sub {}”和“do {}”这样的运算符 看 像化合物
语句,但不是——它们只是表达式中的术语——因此需要一个明确的
当用作语句中的最后一项时终止。
真相 和 谬误
数字 0、字符串 '0' 和 ""、空列表 "()" 和 "undef" 在一个
布尔上下文。 所有其他值都为真。 用“!”否定真值或不”
返回一个特殊的假值。 当作为字符串求值时,它被视为“”,但作为一个
数字,它被视为 0。大多数返回 true 或 false 的 Perl 运算符的行为都是这样
办法。
个人陈述 修饰符
任何简单的语句都可以选择后跟 单盒 修饰符,就在
终止分号(或块结尾)。 可能的修饰符是:
如果 EXPR
除非 EXPR
而 EXPR
直到 EXPR
列表
foreach 列表
当 EXPR
修饰符后面的“EXPR”称为“条件”。 它的真相或
错误决定了修饰符的行为方式。
“if”执行一次语句 if 并且仅当条件为真时。 “除非”是
相反,它执行语句 除非 条件为真(即,如果
条件为假)。
如果长度 $ear >= 10,则打印“巴吉度猎犬长耳朵”;
go_outside() 和 play() 除非 $is_raining;
"for(each)" 修饰符是一个迭代器:它对中的每个项目执行一次语句
LIST(依次为每个项目别名 $_)。
为 qw(世界多莉护士)打印“你好 $_!\n”;
“while”重复语句 而 条件为真。 “直到”做相反的事情,它
重复声明 直到 条件为真(或条件为假时):
# 这两个都从 0 到 10 计数。
打印 $i++ 而 $i <= 10;
打印 $j++ 直到 $j > 10;
“while”和“until”修饰符具有通常的“while”循环语义(条件
首先评估),除非应用于“do”-BLOCK(或应用于 Perl4“do”-SUBROUTINE
语句),在这种情况下,块在评估条件之前执行一次。
这样您就可以编写如下循环:
做 {
$行 = ;
...
} 直到 !defined($line) || $line eq ".\n"
参见 perlfunc 中的“做”。 还要注意,后面描述的循环控制语句将 不是
在这个结构中工作,因为修饰符不带循环标签。 对不起。 你总是可以
把另一个块放在它里面(“下一个”)或它周围(“最后一个”)来做那种
事物。 对于“下一个”,只需将大括号加倍:
做 {{
下一个如果 $x == $y;
# 在这里做点什么
}} 直到 $x++ > $z;
对于“最后”,您必须更加详细:
环形: {
做 {
最后如果 $x = $y**2;
# 在这里做点什么
} 而 $x++ <= $z;
}
注意: 用语句修饰符修改的“我的”、“状态”或“我们的”的行为
条件或循环结构(例如,“my $x if ...”)是 未定义。 的价值
“我的”变量可能是“undef”,任何先前分配的值,或者可能是任何东西
别的。 不要依赖它。 perl 的未来版本可能会做一些与
你试试看的 perl 版本。 这里是龙。
“when”修饰符是一项实验性功能,最早出现在 Perl 5.14 中。 使用
它,您应该包括“使用 v5.14”声明。 (从技术上讲,它只需要
“切换”功能,但它的这方面在 5.14 之前不可用。)仅可操作
在“foreach”循环或“给定”块中,只有当
智能匹配“$_ ~~ 表达式" 是真的。 如果语句执行,则后跟“下一步”
从内部“foreach”和“break”内部“给定”。
在当前的实现下,“foreach”循环可以在“when”中的任何地方
修饰符的动态范围,但必须在“给定”块的词法范围内。 这个
在未来的版本中可能会放宽限制。 请参阅下面的“开关语句”。
复合肥产线 声明
在 Perl 中,定义作用域的语句序列称为块。 有时一个
块由包含它的文件分隔(在需要文件的情况下,或者
程序作为一个整体),有时一个块由字符串的范围(在
评估的情况)。
但通常,块由大括号(也称为花括号)分隔。 我们会打电话
这个句法构造了一个 BLOCK。
以下复合语句可用于控制流程:
如果(EXPR)块
如果 (EXPR) BLOCK 否则 BLOCK
如果 (EXPR) 块 elsif (EXPR) 块 ...
如果 (EXPR) BLOCK elsif (EXPR) BLOCK ... 否则 BLOCK
除非(EXPR)块
除非(EXPR)块否则块
除非 (EXPR) BLOCK elsif (EXPR) BLOCK ...
除非 (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
给定(EXPR)块
LABEL while (EXPR) 块
LABEL while (EXPR) BLOCK 继续 BLOCK
标签直到(EXPR)块
标签直到(EXPR)块继续块
(EXPR; EXPR; EXPR) 块的标签
VAR(列表)块的标签
VAR (LIST) 块的标签继续块
标签 foreach (EXPR; EXPR; EXPR) 块
标签 foreach VAR (LIST) 块
LABEL foreach VAR (LIST) BLOCK 继续 BLOCK
标签块
标签块继续块
相块
实验性的“给定”陈述是 而不去 自动 启用; 请参阅“切换语句”
下面是如何做到这一点,以及随之而来的警告。
与 C 和 Pascal 不同,在 Perl 中,这些都是根据 BLOCK 而不是语句定义的。
这意味着大括号是 必须--不允许悬空语句。 如果你
想要编写没有大括号的条件,还有其他几种方法可以做到。
以下都做同样的事情:
if (!open(FOO)) { die "无法打开 $FOO: $!" }
die "无法打开 $FOO: $!" 除非打开(FOO);
打开(FOO) || die "无法打开 $FOO: $!";
打开(FOO)? () : die "无法打开 $FOO: $!";
#有点异国情调,最后一个
“if”语句很简单。 因为 BLOCK 总是以 curl 为界
括号中,关于“if”和“else”搭配哪个永远不会有任何歧义。 如果你使用
“除非”代替“如果”,测试的意义是相反的。 像“如果”,“除非”可以是
其次是“其他”。 “除非”甚至可以跟一个或多个“elsif”语句,
尽管在使用该特定语言结构之前您可能要三思而后行,因为
每个阅读您代码的人都必须至少三思而后行才能理解
这是怎么回事。
只要表达式为真,“while”语句就会执行块。 “直到”
只要表达式为假,语句就会执行块。 标签是可选的,
如果存在,则由一个标识符和一个冒号组成。 LABEL 标识
循环控制语句“next”、“last”和“redo”的循环。 如果省略 LABEL,
循环控制语句指的是最里面的封闭循环。 这可能包括
在运行时动态查看调用堆栈以找到 LABEL。 如此绝望
如果您使用“使用警告”pragma 或 -w 旗。
如果有一个“continue”BLOCK,它总是在条件发生之前执行
有待再次评估。 因此它可用于增加循环变量,即使
循环已通过“next”语句继续。
当块前面是编译阶段关键字,例如“BEGIN”、“END”、“INIT”时,
"CHECK" 或 "UNITCHECK",则该块将仅在
执行。 有关详细信息,请参阅 perlmod。
扩展模块也可以连接到 Perl 解析器来定义新的复合类型
声明。 这些是由扩展识别的关键字引入的,并且
关键字后面的语法完全由扩展定义。 如果你是一个
实现者,请参阅 perlapi 中的“PL_keyword_plugin”以了解该机制。 如果你正在使用这样的
一个模块,请参阅该模块的文档以了解其定义的语法的详细信息。
循环 通过积极争取让商标与其相匹配的域名优先注册来维护
“next”命令开始循环的下一次迭代:
线:虽然( ){
下一行 if /^#/; # 丢弃评论
...
}
“last”命令立即退出有问题的循环。 “继续”块,如果有的话,
未执行:
线:虽然( ){
最后一行 if /^$/; # 完成标题后退出
...
}
“重做”命令重新启动循环块而不再次评估条件。 这
“继续”块,如果有的话,是 而不去 执行。 此命令通常由以下程序使用
想对自己刚刚输入的内容撒谎。
例如,当处理像这样的文件时 /etc/termcap. 如果您的输入行可能以
反斜杠表示继续,您想跳过并获取下一条记录。
而 (<>) {
咀嚼;
如果 (s/\\$//) {
$_ .= <>;
重做除非 eof();
}
# 现在处理 $_
}
这是更明确编写的版本的 Perl 简写:
线:而(定义($线= )){
咀嚼($线);
如果($line =~ s/\\$//){
$行.= ;
重做 LINE 除非 eof(); # 不是 eof(ARGV)!
}
# 现在处理 $line
}
请注意,如果上面的代码中有一个“continue”块,它只会被执行
在正则表达式丢弃的行上(因为重做跳过继续块)。 一个继续块
常用于重置线路计数器或“m?pat?” 一次性比赛:
# 灵感来自:1,$g/fred/s//WILMA/
而 (<>) {
米?(弗雷德)? && s//WILMA $1 WILMA/;
米?(巴尼)? && s//贝蒂 $1 贝蒂/;
米?(本垒打)? && s//MARGE $1 MARGE/;
} 继续 {
打印 "$ARGV $.: $_";
如果 eof 则关闭 ARGV; # 重置 $.
如果 eof 则重置; # 重置 ?pat?
}
如果将“while”一词替换为“until”一词,则测试的含义相反,
但条件仍然在第一次迭代之前进行测试。
循环控制语句在“if”或“unless”中不起作用,因为它们不是循环。 你
不过,可以将大括号加倍以使它们如此。
如果(/模式/){{
最后如果 /fred/;
下一个如果 /barney/; # 和 "last" 一样的效果,
# 但也没有记录
# 在这里做点什么
}}
这是由于块本身充当执行一次的循环这一事实引起的,请参见
“基本块”。
Perl 4 中可用的“while/if BLOCK BLOCK”形式不再可用。 代替
“if (do BLOCK)”出现的任何“if BLOCK”。
对于
Perl 的 C 风格的“for”循环的工作原理类似于相应的“while”循环; 这意味着:
for ($i = 1; $i < 10; $i++) {
...
}
与此相同:
$ i = 1;
而 ($i < 10) {
...
} 继续 {
$ i ++;
}
有一个微小的区别:如果变量在初始化时用“my”声明
“for”的部分,这些变量的词法范围正是“for”循环(
循环体和控制部分)。
作为一种特殊情况,如果“for”循环(或相应的“while”循环)中的测试是
为空,则视为真。 也就是说,两者
为了 (;;) {
...
}
和
尽管 () {
...
}
被视为无限循环。
除了普通的数组索引循环之外,“for”还可以用于许多其他有趣的
应用程序。 如果您明确测试,这里有一个可以避免您遇到的问题
交互式文件描述符上的文件结尾导致您的程序似乎挂起。
$on_a_tty = -t STDIN && -t STDOUT;
子提示 { 打印 "yes? " if $on_a_tty }
对于(提示(); ; 迅速的() ) {
# 做点什么
}
使用“readline”(或操作符形式,“ ") 作为“for”循环的条件是
以下内容的简写。 此行为与“while”循环条件相同。
for ( prompt(); 已定义( $_ = ); 迅速的() ) {
# 做点什么
}
佛瑞奇
“foreach”循环迭代一个正常的列表值并将标量变量 VAR 设置为
依次成为列表的每个元素。 如果变量前面有关键字“my”,
那么它是词法范围的,因此仅在循环内可见。 除此以外,
该变量对于循环来说是隐式局部的,并在退出循环时重新获得它以前的值
环形。 如果变量之前是用“my”声明的,它会使用该变量而不是
全局的,但它仍然本地化到循环。 这种隐式定位发生
仅由 在“foreach”循环中。
“foreach”关键字实际上是“for”关键字的同义词,因此您可以使用两者之一。
如果省略 VAR,则将 $_ 设置为每个值。
如果 LIST 的任何元素是左值,您可以通过在循环内修改 VAR 来修改它。
相反,如果 LIST 的任何元素不是左值,则任何修改该元素的尝试
将失败。 换句话说,“foreach”循环索引变量是一个隐式别名
您正在循环的列表中的每个项目。
如果 LIST 的任何部分是一个数组,如果你添加或删除“foreach”会变得非常混乱
循环体内的元素,例如“拼接”。 所以不要那样做。
如果 VAR 是绑定变量或其他特殊变量,“foreach”可能不会按照您的预期执行。
也不要那样做。
从 Perl 5.22 开始,这个循环有一个实验变体,它接受一个变量
前面是 VAR 的反斜杠,在这种情况下,LIST 中的项目必须是引用。
反斜杠变量将成为 LIST 中每个引用项的别名,其中
必须是正确的类型。 在这种情况下,变量不必是标量,并且
反斜杠后面可以跟“我的”。 要使用此表单,您必须启用“重新别名”
功能通过“使用功能”。 (请参阅功能。另请参阅 perlref 中的“分配给引用”。)
例子:
对于 (@ary) { s/foo/bar/ }
对于我的 $elem (@elements) {
$元素 *= 2;
}
对于 $count (reverse(1..10), "BOOM") {
打印 $count, "\n";
睡觉(1);
}
for (1..15) { 打印“圣诞快乐\n”; }
foreach $item (split(/:[\\\n:]*/, $ENV{TERMCAP})) {
打印 "项目: $item\n";
}
使用功能“重新别名”;
没有警告“experimental::refaliasing”;
foreach \my %hash (@array_of_hash_references) {
# 做一些每个 %hash 的事情
}
下面是 C 程序员如何在 Perl 中编写特定算法的代码:
for (my $i = 0; $i < @ary1; $i++) {
for (my $j = 0; $j < @ary2; $j++) {
如果 ($ary1[$i] > $ary2[$j]) {
最后的; # 不能去外面 :-(
}
$ary1[$i] += $ary2[$j];
}
#这就是最后一个带我去的地方
}
而 Perl 程序员可能更喜欢这个习惯用法:
外部:对于我的 $wid (@ary1) {
内部:对于我的 $jet (@ary2) {
下一个外部如果 $wid > $jet;
$wid += $喷气机;
}
}
看看这有多容易? 它更清洁、更安全、更快。 它更干净,因为它是
噪音小。 它更安全,因为如果稍后在内部和外部循环之间添加代码
上,新代码不会被意外执行。 “下一个”显式迭代另一个
循环而不是仅仅终止内部循环。 它更快,因为 Perl 执行
“foreach”语句比等效的“for”循环更快。
敏锐的 Perl 黑客可能已经注意到“for”循环有一个返回值,并且
可以通过将循环包装在“do”块中来捕获该值。 对此的奖励
发现是这个警告性建议:“for”循环的返回值是未指定的,并且
可能会更改,恕不另行通知。 不要依赖它。
基础版 块
BLOCK 本身(标记或不标记)在语义上等同于执行的循环
一次。 因此,您可以使用其中的任何循环控制语句来退出或重新启动
堵塞。 (注意这是 不是 在“eval{}”、“sub{}”中为真,或与普遍看法相反
“do{}”块,它做 不是 算作循环。)“继续”块是可选的。
BLOCK 结构可用于模拟 case 结构。
转变: {
如果 (/^abc/) { $abc = 1; 最后一次切换; }
如果 (/^def/) { $def = 1; 最后一次切换; }
如果 (/^xyz/) { $xyz = 1; 最后一次切换; }
$无 = 1;
}
您还会发现用于创建主题化器和开关的“foreach”循环:
转变:
对于($var){
如果 (/^abc/) { $abc = 1; 最后一次切换; }
如果 (/^def/) { $def = 1; 最后一次切换; }
如果 (/^xyz/) { $xyz = 1; 最后一次切换; }
$无 = 1;
}
这样的结构经常使用,因为旧版本的 Perl 没有
官方的“switch”声明,也因为下面描述的新版本
仍然是实验性的,有时可能会令人困惑。
Switch 开关 声明
从 Perl 5.10.1 开始(好吧,5.10.0,但它没有正常工作),你可以说
使用功能“开关”;
启用实验性开关功能。 这松散地基于旧版本的
Perl 6 提议,但它不再类似于 Perl 6 构造。 您还可以获得
每当您声明您的代码更喜欢在 Perl 版本下运行时切换功能
即 5.10 或更高版本。 例如:
使用 v5.14;
在“switch”特性下,Perl获得了实验关键词“given”、“when”、
“默认”、“继续”和“中断”。 从 Perl 5.16 开始,可以在 switch 前缀
带有“CORE::”的关键字可以在没有“use feature”语句的情况下访问该功能。 这
关键字“given”和“when”类似于其他语言中的“switch”和“case”,所以
上一节的代码可以改写为
使用 v5.10.1;
对于($var){
当 (/^abc/) { $abc = 1 }
当 (/^def/) { $def = 1 }
当 (/^xyz/) { $xyz = 1 }
默认 { $nothing = 1 }
}
“foreach”是设置主题化器的非实验方式。 如果您想使用
高度实验性的“给定”,可以这样写:
使用 v5.10.1;
给定($var){
当 (/^abc/) { $abc = 1 }
当 (/^def/) { $def = 1 }
当 (/^xyz/) { $xyz = 1 }
默认 { $nothing = 1 }
}
从 5.14 开始,也可以这样写:
使用 v5.14;
对于($var){
$abc = 1 当 /^abc/;
$def = 1 当 /^def/;
$xyz = 1 当 /^xyz/;
默认 { $nothing = 1 }
}
或者,如果你不关心安全,像这样:
使用 v5.14;
给定($var){
$abc = 1 当 /^abc/;
$def = 1 当 /^def/;
$xyz = 1 当 /^xyz/;
默认 { $nothing = 1 }
}
“given”和“when”的参数在标量上下文中,“given”分配$_
变量其主题值。
究竟是什么 EXPR 很难准确描述“何时”确实存在的论点,但在
一般情况下,它会尝试猜测您想要做什么。 有时解释为“$_~~
表达式",有时不是。 当词法上被 a 包围时,它的行为也不同
“给定”块与由“foreach”循环动态封闭时相比。 规则是
太难理解了,无法在这里描述。 请参阅“给定的实验细节
以及何时”稍后。
由于在 Perl 5.10 和 5.16 之间如何实现“给定”的一个不幸的错误,在
由“给定”控制的 $_ 版本只是词法范围的那些实现
原件的副本,而不是原件的动态范围别名,如果它是
是“foreach”或在原始和当前 Perl 6 语言规范下。
此错误已在 Perl 5.18 中修复。 如果你真的想要一个词法 $_,请指定
明确地,但请注意,“我的 $_”现在已弃用,除非有警告,否则将发出警告
被禁用:
给定(我的 $_ = EXPR){ ... }
如果您的代码仍然需要在旧版本上运行,请坚持使用“foreach”作为您的主题化程序
你会少一些不开心。
转到
尽管不适合胆小的人,但 Perl 确实支持“goto”语句。 有
三种形式:“goto”-LABEL、“goto”-EXPR 和“goto”-&NAME。 循环的 LABEL 实际上不是
“goto”的有效目标; 这只是循环的名称。
“goto”-LABEL 形式找到标有 LABEL 的语句并在那里恢复执行。
它不能用于进入任何需要初始化的构造,例如
子程序或“foreach”循环。 它也不能用于进入一个构造
优化了。 它几乎可以用于动态范围内的任何其他地方,
包括子程序外,但通常最好使用其他一些结构,例如
“最后”或“死亡”。 Perl的作者从来没有觉得有必要使用这种形式的“goto”
(在 Perl 中,即--C 是另一回事)。
“goto”-EXPR 形式需要一个标签名称,其范围将被动态解析。 这个
允许按 FORTRAN 计算“goto”,但如果您是,则不一定推荐
可维护性优化:
goto(("FOO", "BAR", "GLARCH")[$i]);
"goto"-&NAME 形式非常神奇,它替代了对命名子程序的调用
对于当前运行的子程序。 这由希望的“AUTOLOAD()”子例程使用
加载另一个子程序,然后假装另一个子程序已被调用
第一个位置(除了当前子程序中对@_ 的任何修改都是
传播到另一个子程序。)在“goto”之后,甚至“caller()”都不能
告诉这个例程首先被调用。
在几乎所有这样的情况下,使用结构化
控制“next”、“last”或“redo”的流程机制,而不是诉诸“goto”。
对于某些应用程序,捕获和抛出对“eval{}”和 模具() 例外
处理也可以是一种谨慎的方法。
这个 省略 个人陈述
从 Perl 5.12 开始,Perl 接受省略号 ""..."" 作为代码的占位符
你还没有实施。 这种形式的省略号,即未实现的语句,应该
不要与二进制触发器“...”运算符混淆。 一个是声明和
其他运营商。 (Perl 通常不会混淆它们,因为通常 Perl 可以分辨
是否需要运算符或语句,但请参阅下面的例外情况。)
当 Perl 5.12 或更高版本遇到省略号语句时,它会正确解析,
但是如果你真的应该尝试执行它,Perl 会抛出一个异常
文本“未实现”:
使用 v5.12;
子未实现 { ... }
评估{未实现()};
if ($@ =~ /^未实现 /) {
说“我发现了一个省略号!”;
}
您只能使用省略号来代替完整的陈述。 这些
省略号如何工作的例子:
使用 v5.12;
{...}
子 foo { ... }
...;
评估 { ... };
子东西{
我的 $self = shift;
...;
}
$x = 做 {
我的 $n;
...;
说“万岁!”;
$n;
};
省略号不能代表属于更大范围的表达式
语句,因为“...”也是触发器运算符的三点版本(参见
perlop 中的“范围运算符”)。
这些尝试使用省略号的示例是语法错误:
使用 v5.12;
打印 ...;
open(my $fh, ">", "/dev/passwd") 或 ...;
if ($condition && ... ) { 说“你好”};
在某些情况下,Perl 无法立即区分
表达式和语句。 例如,块和匿名哈希的语法
引用构造函数看起来是一样的,除非大括号中有东西给 Perl 一个
暗示。 如果 Perl 没有猜测 "{ ... }" 是一个块,则省略号是一个语法错误。
在这种情况下,它不认为“...”是省略号,因为它期待一个
表达式而不是语句:
@transformed = map { ... } @input; # 语法错误
在您的块中,您可以使用“;” 在省略号之前表示“{ ... }”是一个
块而不是哈希引用构造函数。 现在省略号有效:
@transformed = 地图{; ... } @输入; # ';' 消除歧义
注意:有些人通俗地将这种标点符号称为“yada-yada”或
“三点”,但它的真名实际上是一个省略号。
POD: 嵌入式 文件记录
Perl 有一种将文档与源代码混合的机制。 在期待的同时
新语句的开始,如果编译器遇到以
等号和一个词,像这样
=head1 这里有豆荚!
然后该文本和所有剩余的文本一直到并包括以开头的行
“=cut”将被忽略。 perlpod 中描述了中间文本的格式。
这允许您自由地混合源代码和文档文本,如
=项目sazzle($)
snazzle() 函数将以最壮观的方式表现
你可以想象的形式,甚至不例外
控制论烟火。
= 回到编译器,这个 pod 的东西!
子snazzle($){
我的 $thingie = shift;
.........
}
请注意,pod 翻译器应该只查看以 pod 指令开头的段落
(它使解析更容易),而编译器实际上知道寻找 pod 转义
即使在一个段落的中间。 这意味着以下秘密内容将是
编译器和翻译器都忽略。
$a=3;
=秘密的东西
警告“既不是 POD 也不是 CODE!?”
=削减
打印“得到 $a\n”;
您可能不应该永远依赖“warn()”。 不是所有的豆荚
翻译者在这方面表现得很好,也许编译器会变得更加挑剔。
还可以使用 pod 指令快速注释掉一段代码。
朴素 老 留言 (不是!)
Perl 可以处理行指令,很像 C 预处理器。 使用这个,可以
在错误或警告消息(尤其是
对于使用“eval()”处理的字符串)。 这种机制的语法几乎是
与大多数 C 预处理器相同:它匹配正则表达式
# 示例:'#第 42 行“new_filename.plx”'
/^\#\s*
线 \s+ (\d+) \s*
(?:\s("?)([^"]+)\g2)? \s*
$/x
$1 是下一行的行号,$3 是可选文件名
(指定带或不带引号)。 请注意,“#”之前不能有空格,不像
现代 C 预处理器。
line 指令中包含一个相当明显的问题:调试器和分析器
将只显示出现在给定文件中特定行号的最后一行。
应注意不要在要调试的代码中造成行号冲突
后来。
以下是一些您应该能够在命令 shell 中键入的示例:
百分比
# 第 200 行“bzzzt”
# 上一行的“#”必须是该行的第一个字符
死'富';
__结尾__
foo 在 bzzzt 第 201 行。
百分比
# 第 200 行“bzzzt”
eval qq[\n#line 2001 ""\ndie 'foo']; 打印 $@;
__结尾__
foo at - 第 2001 行。
百分比
eval qq[\n#line 200 "foo bar"\ndie 'foo']; 打印 $@;
__结尾__
foo 在 foo bar 第 200 行。
百分比
# 第 345 行“goop”
评估 "\n#line " 。 __线__ 。 ' "' . __FILE__ ."\"\ndie 'foo'";
打印 $@;
__结尾__
foo 在第 345 行。
实验 信息 on 特定 和 ,尤其是
如前所述,“开关”功能被认为是高度实验性的; 这是
如有更改,恕不另行通知。 特别是,“when”有一些棘手的行为,
预计将来会改变变得不那么棘手。 不要依赖它的当前
(错误)实施。 在 Perl 5.18 之前,“given” 也有一些棘手的行为,你应该
仍然要注意您的代码是否必须在旧版本的 Perl 上运行。
这是一个更长的“给定”示例:
使用特征“:5.10”;
给定 ($foo) {
当(未定义){
说 '$foo 未定义';
}
当(“富”){
说 '$foo 是字符串“foo”';
}
当 ([1,3,5,7,9]) {
说 '$foo 是一个奇数';
继续; # 跌倒
}
当 ($_ < 100) {
说 '$foo 在数字上小于 100';
}
当 (\&complicated_check) {
说“对 $foo 的复杂检查是真的”;
}
默认 {
die q(我不知道怎么处理$foo);
}
}
在 Perl 5.18 之前,“given(EXPR)”赋值为 EXPR 只是一个词法范围
复制 (!) of $_,而不是像“foreach”那样的动态范围别名。 做到了
像
做 { 我的 $_ = EXPR; ... }
除了块被成功的“when”或
明确的“中断”。 因为它只是一个副本,而且因为它只有词法范围,
不是动态范围的,你不能用它来做你习惯的事情
“foreach”循环。 特别是,它不适用于任意函数调用,如果这些
函数可能会尝试访问 $_。 最好坚持“foreach”。
大部分功能来自有时可以应用的隐式智能匹配。 大多数
此时,“when(EXPR)”被视为$_的隐式智能匹配,即“$_ ~~ EXPR”。
(有关智能匹配的更多信息,请参阅 perlop 中的“智能匹配运算符”。)但是当
EXPR 是下面列出的 10 个例外情况(或类似情况)之一,它被使用
直接作为布尔值。
1. 用户定义的子程序调用或方法调用。
2.“/REGEX/”、“$foo =~ /REGEX/”或“$foo =~”形式的正则表达式匹配
EXPR”。另外,一个否定的正则表达式匹配形式为“!/REGEX/”,“$foo !~
/REGEX/" 或 "$foo !~ EXPR"。
3. 使用显式“~~”运算符的智能匹配,例如“EXPR ~~ EXPR”。
注意: 您经常必须使用 "$c ~~ $_" 因为默认情况下使用 "$_ ~~ $c" ,
这通常与您想要的相反。
4. 布尔比较运算符,例如“$_ < 10”或“$x eq "abc"”。 关系的
这适用于六个数字比较运算符(“<”、“>”、“<=”、“>=”、
“==”和“!=”),以及六个字符串比较(“lt”、“gt”、“le”、“ge”、“eq”和
“ne”)。
5. 至少三个内置函数“defined(...)”、“exists(...)”和“eof(...)”。
如果我们想到它们,我们可能有一天会添加更多这些。
6. 否定表达式,无论是“!(EXPR)”还是“not(EXPR)”,或者逻辑异或,
“(EXPR1)异或(EXPR2)”。 不包括按位版本(“~”和“^”)。
7. 一个文件测试操作符,只有 4 个例外:“-s”、“-M”、“-A”和“-C”,因为这些
返回数值,而不是布尔值。 不包括“-z”文件测试运算符
在例外列表中。
8. ".." 和 "..." 触发器运算符。 请注意,“...”触发器运算符是
与刚刚描述的“...”省略号完全不同。
在上述 8 种情况下,EXPR 的值直接用作布尔值,因此没有
智能匹配完成。 您可能会将“何时”视为智能匹配。
此外,Perl 检查逻辑运算符的操作数来决定是否使用
通过将上述测试应用于操作数来为每个人进行智能匹配:
9. 如果 EXPR 是“EXPR1 && EXPR2”或“EXPR1 and EXPR2”,则应用测试 递归地 至
EXPR1 和 EXPR2。 除非 都 操作数也通过了测试, 递归地,将
表达式被视为布尔值。 否则,使用智能匹配。
10. 如果 EXPR 是“EXPR1 || EXPR2”、“EXPR1 // EXPR2”或“EXPR1 or EXPR2”,则测试为
应用的 递归地 仅到 EXPR1(它本身可能是一个更高的优先级 AND
运算符,因此受先前规则的约束),而不是 EXPR2。 如果 EXPR1
是使用smartmatching,那么EXPR2也这样做,不管EXPR2包含什么。 但
如果 EXPR2 没有使用智能匹配,那么第二个参数将不会是
任何一个。 这与刚才描述的“&&”情况大不相同,所以要小心。
这些规则很复杂,但目标是让他们做你想做的事(即使你
不太明白他们为什么要这样做)。 例如:
当 (/^\d+$/ && $_ < 75) { ... }
将被视为布尔匹配,因为规则说正则表达式匹配和
对 $_ 的显式测试将被视为布尔值。
除此之外:
当 ([qw(foo bar)] && /baz/) { ... }
将使用智能匹配,因为只有 一种 操作数是一个布尔值:其他用途
smartmatching,然后就赢了。
此外:
当 ([qw(foo bar)] || /^baz/) { ... }
将使用智能匹配(仅考虑第一个操作数),而
当 (/^baz/ || [qw(foo bar)]) { ... }
将只测试正则表达式,这会导致两个操作数都被视为布尔值。 小心
那么,对于这个,因为 arrayref 总是一个真值,这使得它有效
多余的。 不是个好主意。
同义布尔运算符仍将被优化掉。 不要被诱惑
写
当 ("foo" 或 "bar") { ... }
这将优化为“foo”,因此永远不会考虑“bar”(即使规则
说在“foo”上使用智能匹配)。 对于这样的交替,数组 ref 将起作用,
因为这将引发智能匹配:
当 ([qw(foo bar)] { ... }
这有点等同于 C 风格的 switch 语句的 fallthrough 功能
(不要混淆 Perl 的 fallthrough 功能——见下文),其中相同
块用于几个“case”语句。
另一个有用的快捷方式是,如果您使用文字数组或哈希作为参数
“给定”,它变成了一个参考。 所以 "given(@foo)" 和 "given(\@foo)" 是一样的,
例如。
“default”的行为与“when(1 == 1)”完全一样,也就是说它总是匹配。
破坏
您可以使用“break”关键字跳出封闭的“given”块。 每一个“什么时候”
块以“中断”隐式结束。
跌倒
您可以使用“continue”关键字从一种情况跳到下一种情况:
给定($foo){
当 (/x/) { 说 '$foo 包含一个 x'; 继续 }
当 (/y/) { 说 '$foo 包含 y' }
默认 { 说 '$foo 不包含 ay' }
}
回程 折扣值
当“给定”语句也是一个有效的表达式时(例如,当它是最后一个
块的语句),它的计算结果为:
· 一旦遇到明确的“中断”,就会出现一个空列表。
· 成功的“when”/“default”子句的最后一个评估表达式的值,
如果碰巧有一个。
· 如果没有条件,则“给定”块的最后一个评估表达式的值
真实的。
在最后两种情况下,最后一个表达式是在应用于的上下文中计算的
“给定”块。
请注意,与“if”和“unless”不同,失败的“when”语句总是评估为空
名单。
我的 $price = 做 {
给定 ($item) {
当([“梨”,“苹果”]){1}
“投票”时中断; #我的选票买不到
1e10 当/蒙娜丽莎/;
“未知”;
}
};
目前,“给定”块不能总是用作适当的表达式。 这可能是
在 Perl 的未来版本中解决。
交换 in a 循环
您可以使用“foreach()”循环,而不是使用“given()”。 例如,这是一种方法
计算特定字符串在数组中出现的次数:
使用 v5.10.1;
我的 $count = 0;
对于(@array){
当 ("foo") { ++$count }
}
print "\@array 包含 $count 份 'foo'\n";
或者在更新的版本中:
使用 v5.14;
我的 $count = 0;
对于(@array){
++$count 当 "foo";
}
print "\@array 包含 $count 份 'foo'\n";
在所有“when”块的末尾,有一个隐含的“next”。 你可以用
如果您只对第一场比赛感兴趣,则为明确的“最后一场”。
如果您明确指定循环变量,这将不起作用,如“for $item (@array)”。
您必须使用默认变量 $_。
差异 , Perl的 6
Perl 5 smartmatch 和“given”/“when”构造与其 Perl 6 不兼容
类似物。 最明显和最不重要的区别是,在 Perl 5 中,
“given()”和“when()”的参数周围需要括号(除非这个
最后一个用作语句修饰符)。 Perl 6 中的括号在
控制结构,例如“if()”、“while()”或“when()”; 它们不能在
Perl 5 没有很多潜在的混淆,因为 Perl 5 会解析
表达
给定 $foo {
...
}
好像“给定”的参数是散列 %foo 的一个元素,解释
大括号作为散列元素语法。
然而,他们还有很多很多其他的不同。 例如,这适用于 Perl 5:
使用 v5.12;
我的@primary = ("red", "blue", "green");
如果(@primary ~~“红色”){
说“主要的智能匹配红色”;
}
如果(“红色”~~ @primary){
说“红色智能匹配初级”;
}
说“就是这样,伙计们!”;
但它在 Perl 6 中根本不起作用。相反,您应该使用(可并行化的)“任何”
操作员:
如果有的话(@primary)eq“红色”{
说“主要的智能匹配红色”;
}
如果“红色”等式任何(@primary){
说“红色智能匹配初级”;
}
perlop中“Smartmatch Operator”中的smartmatch表与那个不一样
由 Perl 6 规范提出,主要是由于 Perl 6 和 Perl 之间的差异
5 的数据模型,也是因为 Perl 6 规范自 Perl 5 冲进
早期采用。
在 Perl 6 中,“when()”将始终与其参数进行隐式智能匹配,而在 Perl 中
5 将这种隐式智能匹配抑制在
各种相当松散定义的情况,如上所述。 (区别在于
主要是因为 Perl 5 甚至在内部都没有布尔类型。)
使用 onworks.net 服务在线使用 perlsyn