Perl 5.10中$AUTOLOAD求值报语法错误,5.26正常的原因及兼容方案
Perl AUTOLOAD代码兼容问题
我使用了一段AUTOLOAD示例代码,但我的RF::Component::Multi模块的CPAN测试报告显示如下错误:
Bareword found where operator expected at .../RF/Component/Multi.pm line 102, near "s/^.:://sr"
syntax error at .../RF/Component/Multi.pm line 102, near "s/^.:://sr"
对应的代码片段:
# Thanks @ikegami sub AUTOLOAD { my $method_name = our $AUTOLOAD =~ s/^.*:://sr; my $method = sub { my $self = shift; return [ map { $_->$method_name(@_) } @$self ]; }; { no strict 'refs'; *$method_name = $method; } goto &$method; }
现提出以下技术问题:
- Perl 5.10不兼容的点是什么?
- 代码中是否使用了Perl 5.10以上版本的特性?若有,如何实现向后兼容?若需要指定
use 5.xx,应选择哪个版本? - 是否需要添加
use vars '$AUTOLOAD'?
问题解答
1. Perl 5.10不兼容的点
错误根源是替换表达式s/^.*:://sr里的r修饰符——Perl 5.10不支持该修饰符,会将r识别为裸词,触发语法错误。
2. 高版本特性及兼容方案
代码用到了两个Perl 5.14及以上版本的特性:
r修饰符:让替换操作返回修改后的字符串,而非直接修改原变量(Perl 5.14引入)s修饰符:让.匹配换行符(同样是Perl 5.14引入,若你的$AUTOLOAD不会包含换行符,该修饰符可直接移除)
向后兼容修改方案:
将原代码中的my $method_name = our $AUTOLOAD =~ s/^.*:://sr;替换为:
(my $method_name = our $AUTOLOAD) =~ s/^.*:://s;
这段代码先复制$AUTOLOAD的值到$method_name,再对副本执行替换,效果和原代码的r修饰符完全一致,且兼容Perl 5.10及更早版本。
若要保留原写法,需指定use 5.014;,因为r和s修饰符均为Perl 5.14才引入的特性。
3. 是否需要添加use vars '$AUTOLOAD'
不需要。代码中our $AUTOLOAD已经完成了包变量的声明,效果和use vars '$AUTOLOAD'完全相同,且our是Perl 5.6及以上版本就支持的现代语法,比use vars更简洁规范。
内容的提问来源于stack exchange,提问作者KJ7LNW
相关产品推荐
相关产品推荐

