perl tricks
这是我在知乎上的答题。
// 操作符
$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 ... }$fh>
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