不祝福Perl 对象意味着有一个可怕的设计吗?
如果是,任何人都可以向我解释一下吗?
顺便说一句,这是引发此问题的讨论,请查看对该问题的评论
3 回答
需要unbless
肯定会引起人们的注意。由于您仍然可以将对象用作原始数据结构,因此几乎不需要它。
对接收 unblessed 哈希引用与对象比较挑剔的模块往往具有不那么挑剔的选项,例如 JSON 中的 allow_blessed 和 convert_blessed。
一个应用程序是一个实现为哈希引用的对象,您还希望
重载取消%{}
引用运算符 [编辑:并且您还希望支持比 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
我在这里使用这个模式,作为另一个例子。
这是一个无聊而愚蠢的问题。您没有任何目的,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
的例子,它被比我更多的人抹黑