我想为Perl语言添加一项新功能,以便输入更少$self->
。
例如,翻译:
use Moo;
has a_attr => (is=>'rw');
sub XXX {
print $self->a_attr;
}
要:
use Moo;
use MyFeatureModule;
has a_attr => (is=>'rw');
sub XXX {
print _a_attr;
}
操作方法?
答案 0 :(得分:3)
这不需要对Perl的语法进行任何更改,只需更改其语义。幸运的是,这并不太难。
您可以通过为您的包提供AUTOLOAD
子来实现您想要的,当您调用尚未定义的子时(即您的示例中为_a_attr
),该子将自动启动。然后,此AUTOLOAD
方法可以使用Devel::Caller从其来电者抓取$_[0]
(即$self
),将其注入@_
,然后goto
原始方法。
use v5.14;
use strictures;
package Foo {
use Moo;
has xyzzy => (is => 'ro', default => 42);
sub sayit {
say _xyzzy();
}
sub AUTOLOAD {
require Devel::Caller;
my ($invocant) = Devel::Caller::caller_args(1);
unshift @_, $invocant;
my ($method) = (our $AUTOLOAD =~ /::_(\w+)\z/)
or die "Method not found!";
my $coderef = $invocant->can($method)
or die "Method not found!";
goto $coderef;
};
}
my $obj = Foo->new;
$obj->sayit;
这是个好主意吗?好吧,我当然不会这样做。除了为您的代码引入不必要的减速级别以及破坏继承之外,还可能会让任何必须在您之后维护代码的人感到困惑。 (如果你从项目中休息一下,这可能是你未来的自我,并在6个月内回到它。)