1

祝福Perl 对象意味着有一个可怕的设计吗?
如果是,任何人都可以向我解释一下吗?
顺便说一句,这是引发此问题的讨论,请查看对该问题的评论

4

3 回答 3

4

需要unbless肯定会引起人们的注意。由于您仍然可以将对象用作原始数据结构,因此几乎不需要它。

对接收 unblessed 哈希引用与对象比较挑剔的模块往往具有不那么挑剔的选项,例如 JSON 中的 allow_blessed 和 convert_blessed。

于 2015-08-15T20:32:47.797 回答
4

一个应用程序是一个实现为哈希引用的对象,您还希望 重载取消%{}引用运算符 [编辑:并且您还希望支持比 v5.10.1 更早的 perls - 否则您应该只使用no overloading.]

package Foo;
use overload '+' => sub { $_[0]->get + $_[1] },
             ...,
             '%{}' => sub { return { foo => "bar", this => $_[0] } },
             ...;

现在对于任何$foo具有 typeFoo的元素,尝试访问类似的元素$foo->{$key}将调用您的重载%{}方法,并且您的访问将失败。

解决方法是在访问对象成员时临时更改对象的类型,并在完成后将其更改回来。您可以通过取消对对象的祝福来做到这一点,但是通过将其祝福为垃圾值来更常见(并且更容易做到)。

sub Foo::bar {   # access 'bar' member of Foo object
  my $self = shift;
  # $self->{bar} will invoke Foo::{'%{}'}, and we don't wan't that

  my $ref = ref $self;
  unbless($self);    #   or  bless $self, 'Not::An::Object::Name'
  # now $self->{bar} is accessible

  my $value = $self->{bar};
  bless $self, $ref;        # restore object type
  return $value;
}

另一个例子在“Two-face-References”一节中给出overload


我在这里使用这个模式,作为另一个例子。

于 2015-08-15T22:00:53.180 回答
2

这是一个无聊而愚蠢的问题。您没有任何目的,unbless而是从一个不起眼的 CPAN 模块中随机选择它来询问为什么它反映了糟糕的设计。您不妨问如何取消声明已用my. 这在 XS 代码中也很有可能,但我希望它显然是相当愚蠢的?

我遇到的问题unbless是您创建了一个数据结构——从标量变量或文件句柄到嵌套散列或数组的任何内容——并被调用bless,以便 Perl 知道如何解决对该对象的方法调用

所以现在你想要unbless它。这将使数据保持完整,主要区别在于任何方法调用现在都会导致致命错误

Can't call method ... on unblessed reference

那你是unbless为了什么?如果你依赖 Perl 给你这个致命错误,那么分配undef给导致这个致命错误的对象同样容易

Can't call method ... on an undefined value

但优点是你的数据结构可能会被破坏,从而释放内存

如果你想要更可靠的东西,因为引用可能会传递给多个代码部分,这将是一个远距离行动unbless的例子,它被比我更多的人抹黑

于 2015-08-15T20:57:43.490 回答