Perl 有什么奇技淫巧?

不知道什么才算奇与淫,但我感觉这是perl的长项。

列一下,平时经常会用到的一些我觉得比较有意思的技巧

那些不常用到,或者牺牲可读性的用法,比如()x!!, -+- , =()=这些操作符虽然酷炫,还是先不提了

  • // 操作符
$a = $b // $c;

# $a = $b, 如果$b 为undef, $a = $c

常常我会这么写来给变量定义一个默认值

$some_var //= 0;
  • ... yada yada

当我们定义一个函数而打算在未来实现它

sub unimplemented {
    ...
}

三个dot 这个操作符表示这里还有待实现,程序运行不会报错,但如果使用到这个未定义的函数,则会抛出'unimplement'的异常

这个操作符有个名字 yada yada 是来自日语的词汇,释义为等等,之类的意思

  • -> 和 autobox

-> 操作符有个比较有意思的一个地方,除了我们常用的

$hash->{key} 
$list->[0]
$obj->method()

之外,还有一个神奇的功能来实现autobox,也就是所谓的·一切皆对象·

my $len = sub { length(shift) };
"hello"->$len();

如果想要没有$的autobox, "hello"->len(),可以看看CPAN 上的autobox::Core

  • s///r

是否遇到希望用s///来得到想要的字符串而不希望改变原来的变量?

$x = "I like dogs.";
$y = $x =~ s/dogs/cats/r;
print "$x $y\n"; # prints "I like dogs. I like cats."
  • here doc 和 inline file

here doc 可以像下面这样定义一个长的字符串

my $str = <<__;
some string here
bla blah
__

inline file 可以像下面这样在程序内部定义一个file,就像操作文件句柄一样

while( <DATA> ) {
    print;
}
__DATA__
a b c d
1 2 3 4

这两个真是很实在的语法,非常实用

  • flip-flop

.. 除了在列表上下文作为范围操作符使用

'a'..'z' # ('a', 'b', ... 'z')

在标量上下文也有特别的用法,称作flip-flop操作符,行为就像一个状态触发器。

while(<$fh>)
{
  next if 1..100; # skip 1 ~ 100 line
  ...
}
  • autovivification

这个应该是perl所特有的一种用法

使得我可以不必依次定义一个数据的每一级类型,而直接对其进行任意深度的赋值

my $hash = {};

$hash->{a}->{b}->{c} = 1;

方便之外,也可能会带来麻烦

my $hash = {};
if ( exists $hash->{a} ) {
    print 'exists';     # no
}
if ( exists $hash->{a}->{b} ) {
    print 'exists';     # no
}
if ( exists $hash->{a} ) {
    print 'exists now'  # yes
}

我们可以使用`no autovivification` 来关闭这一特性

  • quote word list: qw

这个非常常用,在写一个字符串数组的时候,不用麻烦的大引号了逗号了

qw( item1 item2 item3 ) # ('item1', 'item2', 'item3')
  • x
'a' x 4 # 'aaaa'
# 对数组同样有效
(1,2,3) x 3 # (1,2,3,1,2,3,1,2,3)

  • label

可以在任意位置定义标签,通过goto 进行跳转。

当然很多人都不推荐在程序大量使用goto, 但是perl中定义标签还有一个非常有用的功能,就是循环中使用next 或 last + 标签来进行跨层使用。

LABEL:
for ( @list_A) {
    for ( @list_B ) {
       ...;
       next LABEL;
    }

}
  • @{[...]}

由于perl的sigil的存在,使得perl在print 的时候很容易内插变量,比如在c 中

printf("my name is %s, i'm %d", name, age)

而在perl 中就可以这么写

print "my name is $name, i'm $age";

@{[...]} 更是极大的扩展了这一功能,你可以在字符串中内插表达式

my $x = 1;
my $y = 2;
print "$x + $y = @{[ $x + $y ]}"
  • ($x, $y) = ($y, $x )

python 中的 a, b = b, a

完 -

编辑于 2015-01-19 23:26

Published

Category

Zhihu

Tags