【问题标题】:How do I create a custom write accessor when using Moose?使用 Moose 时如何创建自定义写入访问器?
【发布时间】:2013-08-30 21:39:29
【问题描述】:

编辑:在下面添加了答案,此处留下的问题仅用于历史目的。

Moose documentation 声明:

如果你愿意,你也可以显式指定方法名 用于读取和写入属性的值。这是 当您希望公开属性时特别方便 可读,但只能私人设置。例如:

has 'weight' => (
  is     => 'ro',
  writer => '_set_weight',   
 );

如果重量是基于其他方法计算的,这可能会很有用。 例如,每次调用eat方法时,我们可能会调整 重量。这让我们隐藏了权重的实现细节 变化,但仍向该类的用户提供权重值。

基于这个例子,我写了如下代码:

has '_current_url' => (
    is => 'ro',
    isa => 'URI',
    writer => '_write_URI_to_current_url',
);

# Thus we ensure only a URI object gets written to current_url always
sub _current_url
{
    my $self = shift;
    $self->_write_URI_to_current_url(URI->new_abs($_[0], $self->start_url));
}

我的目的是确保设置 current_url 始终将其设置为 URI 对象,即使它是使用简单字符串调用的。但是,当我尝试运行代码时,我得到:

无法为 _current_url 的只读访问器赋值

在我尝试设置 current_url 的地方(在我的班级内)(使用$self->_current_url($str);)。

这是我与 Moose 的第二天,所以我对这里发生的事情感到很困惑。据我了解,is => 'ro' 只要求 Moose 不要创建与属性同名的默认写访问器,这种理解是否正确?我怎样才能在这里实现我的目标?

【问题讨论】:

  • 对于您在这里所做的,您真正想要的是调查类型和类型强制。您不需要自定义编写器,您需要自定义强制。
  • @cjm Coercion 是我尝试的第一件事,但问题是类型更改的 via 取决于 Moose 不喜欢的第二个参数 $self->start_url,因此导致错误。 via 中的 sub 是否传递了 $self 的副本,是否可以对强制使用不同的属性?

标签: perl moose accessor


【解决方案1】:

好的,我相信我已经找到了问题所在。

我在上面粘贴的 _current_url 方法被 Moose 生成的同名只读访问器覆盖,因此当我尝试使用值调用 $self->_current_url 时,它会抛出上述错误以指示读取-only 访问器不能设置值。

我猜错误消息最好是Cannot assign a value **through** a read-only accessor of _current_url,而不是**to** a read-only accessor

将子名称更改为_set_current_url 解决了问题。我想实现同样的另一种方法是告诉 Moose _current_url is => 'rw' 然后创建一个 around '_current_url'。我没有尝试过这种方法。

【讨论】:

    【解决方案2】:

    游戏迟到了,但刚刚看到这篇文章,不久前遇到了同样的事情。 '_set_current_url' 看起来真的像一个属性访问器而不是一个属性。可能要考虑:

    has '_current_url' => {
      is => 'rw',
      isa => 'URI',
      writer => 'set_current_url',
      reader => 'get_current_url'
      }
    

    这种方式更简洁一些,因为属性是原始的 '_current_url' 并且您有获取/设置属性的访问器。

    【讨论】:

    • 我的理解是writerreader 选项会更改自动创建的访问器的名称,这是不正确的吗?如果它是正确的,那么在这种情况下自动创建一个名为 set_current_url 的写入器听起来没有用,因为关键是要自定义写入访问器,我是否遗漏了什么?
    • 自动创建的访问器是'_current_url'。如果从“has”语句中删除“writer”和“reader”,则可以使用“_current_url”(即$object->_current_url)获取/设置属性。当您使用 writer/reader 时,它会禁用对具有 '_current_url' 的属性的访问,并要求您使用 'set_current_url' 和 'get_current_url'。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 2022-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多