【问题标题】:perl Moose accessor madness - can't define only a reader or writer accessor!perl Moose accessor madness - 不能只定义一个 reader 或 writer 访问器!
【发布时间】:2010-10-13 19:13:49
【问题描述】:

所以我只是想做一件非常简单的事情:为 moose 属性定义一个自定义读取器访问器。所以我试试这个:

has 'compiled_regex' => ( 
    isa => 'RegexpRef', 
    is => 'rw', 
    reader => 'get_compiled', 
);

但是get_compiled 永远不会被调用,大概是因为compiled_regex 是读/写的。好的,没问题。我接下来试试这个:

 has 'compiled_regex' => ( 
     isa => 'RegexpRef', 
     writer => '_compile', 
     reader => 'get_compiled', 
 );

这会产生以下错误:

无法通过包“PrettyRegex”在 ../lib/Pretty/Regexs.pm 第 39 行找到对象方法“compiled_regex”。

指的是 _compile 方法中的这一行:

$self->compiled_regex(qr/$self->regex/);

现在我在过去 3 天里没有睡多少觉,所以也许我很困惑,但似乎即使这确实有效,它也会造成无限倒退,因为我已将作者定义为 _compile ...所以我在这里错过了什么?

尝试了思南的答案,但仍然得到:

Can't locate object method "compiled_regex" via package "PrettyRegex" at ../lib/Pretty/Regexs.pm line 41.

【问题讨论】:

  • 我对 Moose 的了解不够深入,无法理解问题所在,但请有人将帖子的标题改为问题。
  • 出于某种原因,我在编辑脚本时将读者的名字命名为get_compiled_regex。这就是您收到该消息的原因。

标签: perl moose


【解决方案1】:

我不清楚你想做什么。 readerwriter 是 Moose 为您创建的方法,而不是您编写和调用的方法。

我认为您需要重申您的问题以解释您要解决的更高级别的问题。我希望有比您目前所想的更好的方法来做到这一点,但如果不知道您真正想要做什么,我们就无法确定。

如果您试图在读取属性时调用您的自定义方法,只需将读取器命名为其他名称(如_get_compiled_regex),并将您的方法命名为compiled_regex。或者在 reader 方法上使用方法修饰符。 (这可能更好,因为如果有人将参数传递给您的阅读器方法,尝试设置属性,您不会忘记die。)

您可能还希望在其他一些属性上设置一个触发器来清除该属性。

【讨论】:

  • 这基本上是问题所在...我已经定义了一个自定义编写器,在属性上说“write_attr”,比如 $self->my_attr。现在 write_attr 的最后一行是 $self->my_attr($some_var)。由于问题中描述的原因,这不起作用,但即使这样做也不会产生无限回归,因为 write_attr 的最后一行有效地调用 write_attr?
  • @ennui:“write_attr 的最后一行...”表明了问题:这不是您应该定义自己的子项。它是使用“writer”指令自动生成的。
  • 你为什么认为你需要一个自定义作家?如果答案是“因为我想对传入的值运行 [一些转换]”,那么您实际上需要类型约束 + 强制。
  • 我也想知道如何编写客户阅读器。我想要一个,因为我的作家有一些逻辑,所以我每次阅读属性时都需要计算它。我最终放弃了,只是创建了一个返回我想要的方法。
【解决方案2】:

我一直在猜测实际的问题是什么,但我感觉以下内容与之相对应:

package My::M;

use Moose;
use namespace::autoclean;

has 'compiled_regex' => (
    isa => 'RegexpRef',
    is  => 'ro',
    writer => '_set_compiled_regex',
);

sub compile {
    my $self = shift;
    my ($pat) = @_;
    $self->_set_compiled_regex(qr/$pat/);
    return;
}

__PACKAGE__->meta->make_immutable;

package main;
use strict; use warnings;

my $m = My::M->new;
$m->compile( '^\W+\z' );

if ( '@#$%%$' =~ $m->compiled_regex ) {
    print "Hmph!\n";
}

【讨论】:

  • @Ether 对不起,评论指的是思南第一个答案,而不是上面那个。
【解决方案3】:

呃?如果您的阅读器称为get_compiled,而您的编写器称为_compile,那么您没有名为compiled_regex 的方法,那么调用该不存在的方法会失败的原因应该很明显。你需要退后几步,解释你想要做什么,而不是你尝试做的方式出了什么问题。

【讨论】:

  • 你明白这就是为什么 perl oo 和 moose 是,呃,奇怪的原因。 compiled_regex 应该是一个属性,而不是一个方法......如何设置该属性应该是,呃,无关紧要。 ——
猜你喜欢
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 2020-02-01
  • 2017-06-10
  • 1970-01-01
相关资源
最近更新 更多