新增块操作
我认为,扩展语言并创建伪块操作的能力是其中之一。
您先声明一个子程序原型,指出它首先采用代码引用:
sub do_stuff_with_a_hash (&\%) {
my ( $block_of_code, $hash_ref ) = @_;
while ( my ( $k, $v ) = each %$hash_ref ) {
$block_of_code->( $k, $v );
}
}
你可以在body中这样调用它
use Data::Dumper;
do_stuff_with_a_hash {
local $Data::Dumper::Terse = 1;
my ( $k, $v ) = @_;
say qq(Hey, the key is "$k"!);
say sprintf qq(Hey, the value is "%v"!), Dumper( $v );
} %stuff_for
;
(Data::Dumper::Dumper
是另一个半隐藏的宝石。)注意到在代码块前面不需要sub
关键字,也不需要哈希前面的逗号。最后看起来像这样:map {} @list
源代码过滤器
还有源代码过滤器,使用该功能可以让Perl将代码传递给你以便进行操作。不管是源代码过滤器还是块操作,都不建议在家中尝试。
我曾经用源代码过滤器做了一些很酷的东西,例如创建了一个非常简单的语言来检查时间,使得可以使用简短的Perl一行代码进行一些决策:
perl -MLib::DB -MLib::TL -e 'run_expensive_database_delete() if $hour_of_day < AM_7';
Lib::TL
将扫描变量和常量,创建它们并根据需要进行替换。
再次强调,源代码过滤器可能会很混乱,但功能强大。但是它们可能会导致调试器出现非常糟糕的问题,即使警告信息也可能打印在错误的行号上。我停止使用 Damian 的 Switch ,因为调试器失去了告诉我实际位置的所有能力。但我发现通过修改小段代码并将其保留在同一行上,可以最小化这种影响。
信号挂钩(Signal Hooks)
这通常已经足够了,但并不是那么明显。下面是一个利用旧处理程序的 die 处理程序示例:
my $old_die_handler = $SIG{__DIE__};
$SIG{__DIE__}
= sub { say q(Hey! I'm DYIN' over here!); goto &$old_die_handler; }
;
这意味着每当代码中的其他模块想要停止时,它们必须来找你(除非有人在 $SIG{__DIE__}
上进行破坏性覆盖)。而且你可以被通知有人认为某些事情是错误的。
当然,如果你只想清理一些东西,你也可以使用 END { }
块。
overload::constant
您可以在包括您的模块的包中检查特定类型的文字。例如,如果您在 import
子例程中使用此功能:
overload::constant
integer => sub {
my $lit = shift;
return $lit > 2_000_000_000 ? Math::BigInt->new( $lit ) : $lit
};
如果这样做,意味着调用包中大于20亿的所有整数都将被更改为 Math::BigInt
对象(参见overload::constant)。
分组的整数字面量
顺便说一下,Perl允许您将大数字分成三位一组,并仍然获得可解析的整数。注意上面的 2_000_000_000
表示20亿。