【发布时间】:2009-03-11 16:03:59
【问题描述】:
"How can I monkey-patch an instance method in Perl?" 的问题让我开始思考。我可以动态地重新定义 Perl 方法吗?假设我有这样的课程:
package MyClass;
sub new {
my $class = shift;
my $val = shift;
my $self = { val=> $val};
bless($self, $class);
return $self;
};
sub get_val {
my $self = shift;
return $self->{val}+10;
}
1;
假设两个数字相加真的很昂贵。
我想修改该类,以便仅在我第一次调用该对象的方法时才计算 $val+10。对该方法的后续调用将返回一个缓存值。
我可以轻松地修改方法以包含缓存,但是:
- 我有一堆这样的方法。
- 我不想弄脏这个方法。
我真正想做的是指定一个方法列表,我知道这些方法对于给定实例总是返回相同的值。然后我想获取这个列表并将其传递给一个函数,以便为这些方法添加缓存支持
有没有有效的方法来做到这一点?
跟进。下面的代码有效,但是因为 use strict 不允许按字符串引用,所以我不是 100% 想要的。
sub myfn {
printf("computing\n");
return 10;
}
sub cache_fn {
my $fnref = shift;
my $orig = $fnref;
my $cacheval;
return sub {
if (defined($cacheval)) { return $cacheval; }
$cacheval = &$orig();
return $cacheval;
}
}
*{myfn} = cache_fn(\&myfn);
如何修改才能做到这一点?:
cache_fn(&myfn);
【问题讨论】:
-
{ 没有警告“重新定义”; *myfn = cache_fn(\&myfn); } - 这消除了模棱两可和重新定义的警告。请参阅我关于 cache_fn(&myfn); 的新答案
-
您可能想研究记忆化(有一些很好的 CPAN 模块),或者使用 Moose 触发器在属性中缓存昂贵的计算,并根据需要使用触发器重新计算它们。
标签: perl