如何重新定义Perl类的方法?

“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仅在第一次调用该对象的方法时计算.对该方法的后续调用将返回缓存的值.

我可以轻松地修改包含缓存的方法,但是:

>我有一堆这样的方法.
>我宁愿不要弄脏这种方法.

我真正想要做的是指定一个方法的列表,我知道总是为给定的实例返回相同的值.然后,我想把这个列表传递给一个函数,为这些方法添加缓存支持

有没有一个有效的方法来完成这个?

跟进.下面的代码工作,但是因为使用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);

解决方法

您可以像这样从另一个包覆盖get_val方法
*{MyClass::get_val} = sub { return $some_cached_value };

如果你有方法名称列表,你可以这样做:

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 };
}

这是你想象的吗

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...