我无法理解,为什么Perl在像这样的程序中执行大括号中的代码:
unknown_method { # some code };
我的节目:
文件Transaction.pm:
package Transaction; use strict; use warnings; use feature qw/ say /; sub transaction(&) { say 'BEGIN TRANSACTION'; eval { shift->() }; if ( $@ ) { say 'ROLLBACK TRANSACTION'; die($@); # reraise error } else { say 'COMMIT TRANSACTION'; } } 1;
文件run_properly.pl:
use feature qw/ say /; use Transaction; eval { Transaction::transaction { say "insert some data to DB"; die("KnownException") } }; warn $@;
文件run_wrong.pl:
use feature qw/ say /; # I forgot to import Transaction eval { Transaction::transaction { say "insert some data to DB"; die("KnownException") } }; warn $@;
执行:
$perl run_properly.pl BEGIN TRANSACTION insert some data to DB ROLLBACK TRANSACTION KnownException at run_properly.pl line 6.
和
$perl run_wrong.pl insert some data to DB KnownException at run_wrong.pl line 6.
为什么Perl允许这样的事情?
解决方法
Perl在语法上是灵活的,并且通常有多种语法可以做.例如,调用方法.这是常规和推荐的语法:
Foo -> new (1,2,3); # ^-object ^- method ^- arguments
这是间接语法:
new Foo 1,3; # ^- method ^- object ^- arguments,parens are optional
这一切都很好,但是当我们想要将复杂计算的结果用作间接对象表示法的对象时会发生什么?
# set up some constructors for demonstration purposes *Foo::new = *Bar::new = sub {say "@_"}; # This obvIoUsly fails # new (rand > .5 ? "Foo" : "Bar") 1,3;
解决方案是一个dative块:
new {rand > .5 ? "Foo" : "Bar"} 1,3;
您可能已经知道文件句柄中的dative块:print {$handles [-1]} $_.
在方法解析之前执行dative块,因为方法解析通常(但不是在你的情况下)取决于对象的类型.但是,如果块死亡,则不会解决任何方法.
间接符号仍然非常受构造函数的欢迎,因为它使Perl看起来像C.但是,Perl(与C不同)没有新的运算符:它只是一种常规方法.这种灵活性可能是一个坏主意,因此如果您对此有强烈的兴趣,可以使用no indirect
“修复”它.