1

我有一组方法,我希望调用者能够覆盖一个值,或者它默认为实例变量。

所以我一直在努力做的是:

method foo( Str :$blah = $self->blah ) {
    #doStuff
}

这会引发解析错误,所以我最终到处都这样做

method foo( Str :$blah? ) {
    $blah = $self->blah unless defined $blah;
    #doStuff
}

不可怕,但当 MooseX::Method::Signatures 支持默认概念并修复了我所有其他标准的“方法开始”行时,这似乎很愚蠢。

当我尝试做这样的事情并且我在网络上找不到遇到同样问题的其他人时,我总是以错误的方式解决问题。似乎我可能试图将功能程序塞入 oo 布局,而不是实际的 oo,因为这些方法是用于外部调用的更多辅助函数,而不是在对象上操作的方法。因此,只需检查我是否只是错误地定义它,或者我正在做的事情是否“愚蠢”或 Parse::Method::Signatures 不支持。

4

1 回答 1

1

AFAIK Signatures 模块将自身连接到 Perl 解析器并注入一些代码来处理原型。值得注意的是,这很有效。

也就是说,使用非常量值作为默认值可能会出现问题。在某些情况下,调用一些代码来预填充一个值可能会造成严重破坏。具体来说,应该只在没有给定参数值的情况下调用预填充值的代码,还是应该始终调用它?我们应该如何处理副作用?应该caller是什么?如果我有一个全局$self对象,那不应该接收方法调用,因为范围规则明确规定了这一点吗?(因为our $x=5; my $x=$x;是有效的,但my $x=$x不是)。更好的是,如果默认值填充方法调用调用相同的方法,但又没有可选参数的值,会发生什么情况?

您总是可以回退到老式的可选参数:

sub foo {
  my ($self, $blah) = @_;
  # something like my ($self, $blah) = (@_, $self->blah); wouldn't work, of course.
  $blah //= $self->blah; # nicer than old `unless defined`
  ...;
}

或者,在这种情况下:

method foo (:$blah?) {
   $blah //= $self->blah
}

我发现定义或运算符的这种使用非常有趣。

于 2012-12-05T13:19:11.410 回答