如何重新定义 Perl 类方法? [英] How can I redefine Perl class methods?
问题描述
问题 "我如何进行猴子补丁Perl 中的实例方法?" 让我思考.我可以动态地重新定义 Perl 方法吗?假设我有一堂这样的课:
The question "How can I monkey-patch an instance method in Perl?" got me thinking. Can I dynamically redefine Perl methods? Say I have a class like this one:
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;
假设两个数字相加的成本非常高.
And let's say that adding two numbers is really expensive.
我想修改该类,以便仅在我第一次调用该对象上的方法时计算 $val+10.对该方法的后续调用将返回一个缓存值.
I'd like to modify the class so that $val+10 is only computed the first time I call the method on that object. Subsequent calls to the method would return a cached value.
我可以轻松修改方法以包含缓存,但是:
I could easily modify the method to include caching, but:
- 我有很多这样的方法.
- 我不想弄脏这个方法.
我真正想做的是指定一个方法列表,我知道这些方法总是为给定实例返回相同的值.然后我想获取这个列表并将它传递给一个函数来为这些方法添加缓存支持
What I really want to do is specify a list of methods that I know always return the same value for a given instance. I then want to take this list and pass it to a function to add caching support to those methods
有没有有效的方法来实现这一点?
Is there an effective way to accomplish this?
跟进.下面的代码有效,但因为 use strict 不允许通过字符串引用,所以我不是 100% 我想要的地方.
Follow up. The code below works, but because use strict doesn't allow references by string I'm not 100% where I want to be.
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);
我该如何修改才能做到这一点?:
How do I modify to just do this?:
cache_fn(&myfn);
推荐答案
你可以像这样从另一个包中覆盖像 get_val 这样的方法:
You can overwrite methods like get_val from another package like this:
*{MyClass::get_val} = sub { return $some_cached_value };
如果你有一个方法名称列表,你可以这样做:
If you have a list of method names, you could do something like this:
my @methods = qw/ foo bar get_val /;
foreach my $meth ( @methods ) {
my $method_name = 'MyClass::' . $meth;
no strict 'refs';
*{$method_name} = sub { return $some_cached_value };
}
这是你想象的吗?
这篇关于如何重新定义 Perl 类方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!