Perl中的一些技巧性语法收集

Perl中不少常规语法有特殊用法,使得有很多【少为人知】的技巧性写法。本文收集了一些,欢迎大家提供文中未涉及的技巧,感谢。

部分操作符技巧性用法总结:perl secret

Perl Shell

Perl没有像Python、Ruby一样自带交互式的Shell接口,有时候做些简短的测试没有交互式的Shell不是很方便。但实现起来也很方便:

while(print ">> ") {
  chomp ($_ = <>);
  /^q$/ && last;  # 输入q退出,此外last或exit也可以退出
  say "=> ", (eval $_) // "undef";
}

可以设置一个shell命令的命令别名,方便地启动这个简陋但方便的Perl Shell:

alias ipl='perl -E'\''while(print">> "){chomp($_=<>);/^q$/&&last;say"=> ",(eval$_)//"undef";}'\'

可省略token之间的空白

如果两个相邻的token之间连在一起不会产生歧义,那么可以省略这两个token之间的空白分隔符。

print"abc","def\n";   #-> print "abc","def\n"
print$var;      #-> print $var
my$var="abc";   #-> my $var
print~~length$var #-> print length $var

但下面写法会被错误解析,它会当作调用print1函数并传递参数3来解析(注意参数是3而不是+3,参见+符号)。

print1+3;

+符号

在某些省略函数调用括号时,为了避免可能产生的歧义,可在第一个参数前使用+,表示让后面的表达式作为函数参数,相当于加了函数调用的括号。

print(3+4)*4;     # (1).输出7
print ((3+4)*4);  # (2).输出28
print +(3+4)*4;   # (3).输出28,等价于(2)

~~强制转换为标量上下文

有些地方需要标量上下文,但可能处于列表上下文环境,可以使用scalar来强制转换为标量上下文,也可以使用~~强转为标量上下文。单个~表示位取反,且要求标量上下文,两个~表示位取反两次,相当于没有取反,因此将上下文强转为标量上下文,但却不影响计算结果。

my @arr = qw(a b c d);
say ~~@arr;        # 4
say scalar @arr;   # 4

标量上下文中的列表赋值

Perl中的赋值语句有返回值,结合上下文的用法,Perl的赋值操作非常非常灵活。

例如,最简单的赋值语句:

$a = 33;  # 赋值语句直接返回所赋值

标量上下文中的列表:

# 变量被赋值为列表最后一个元素
# 赋值语句也返回最后一个元素的值
$a = (11,22,33);
$a = qw(11,22,33);

列表上下文中的列表:

($a, $b) = (11,22,33);       # (1)
($a) = (11,22,33);           # (2)
($a,$b,$c,$d) = (11,22,33);  # (3)

上面这种赋值语句将前后对应逐个赋值,左边多出的变量被赋值为undef,右边多出的数据被丢弃。

但是注意,这种列表上下文中的列表赋值语句的返回值:在列表上下文中返回左边列表,在标量上下文中返回右边列表的长度

# 赋值语句在列表上下文:
@arr = ($a, $b) = (11,22,33);   # @arr = (11,22)
say (($a, $b) = (11,22,33));    # 输出:1122

# 赋值语句在标量上下文
$len = () = (11,22,33);         # $len = 3
say ~~(($a, $b) = (11,22,33));  # 输出:3