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;
}
package My::Pkg;
use Storable qw/dclone/;
use Data::Structure::Util qw/unbless/;
sub _distribute_private_attr {
$_[0]->{_private_attrs} = {...}
}
sub new {
my $obj = bless { Foo => [qw/bar/] };
$obj->_distribute_private_attr();
return $obj;
}
sub load {
my $cls = shift;
my $data = retrieve $_[0];
my $obj = bless $data, $cls;
$obj->_distribute_private_attr();
return $obj
}
sub save {
my $obj = shift;
my $data = unbless ( dclone $obj );
delete $data->{_private_attrs};
store $data, $_[0];
}
1;
package main;
use Some::Other::Mod;
my $obj = My::Pkg -> new;
$obj->{Bar} = "Baz";
$obj->save ("someFile");
my $obj2 = My::Pkg->load("someFile"); # Now we can do this
my $obj3 = Some::Other::Mod->load("someFile"); # or this
my $data = retrieve "someFile"; # or this
4条答案
按热度按时间ecfdbz9o1#
需要
unbless
肯定会引起人们的注意。由于您仍然可以使用对象作为原始数据结构,因此几乎不需要它。那些对接收不受祝福的哈希引用和对象很挑剔的模块往往有一些不那么挑剔的选项,例如JSON中的allow_blessed和convert_blessed。
e0uiprwp2#
一个应用程序是作为散列引用实现的对象,您还希望overload
%{}
解引用操作符[编辑:并且您还希望支持v5.10.1之前的perls--否则您应该只使用no overloading
。]字符串
现在,对于任何类型为
Foo
的$foo
,尝试访问像$foo->{$key}
这样的元素将调用重载的%{}
方法,访问将失败。解决方法是在访问对象的成员时临时更改对象的类型,并在完成后将其更改回来。您可以通过取消对对象的祝福来做到这一点,但更常见的做法(也更容易做到)是将其祝福为垃圾值。
型
另一个示例在
overload
中的“双面引用”一节中给出我在这里使用这个模式,作为另一个例子。
vof42yt13#
这是一个无聊而愚蠢的问题。您对
unbless
没有任何目的,而是从一个晦涩的CPAN模块中随机选择了它,询问它为什么反映了糟糕的设计。您还可以询问如何 * 取消声明 * 一个已用my
声明的变量。这在XS代码中也是很有可能的,但我希望这显然是相当愚蠢的?unbless
的问题是,您创建了一个数据结构--从标量变量、文件句柄到嵌套的散列或数组--并调用了bless
,以便Perl知道如何解析该对象上的方法调用所以现在你要
unbless
它。这将使数据保持不变,主要的区别在于,任何方法调用现在都将导致致命错误字符串
你的
unbless
是干什么用的?如果您依赖于Perl来给予此致命错误,那么将undef
赋值给导致此致命错误的对象也是很容易的型
但它的优点是可以破坏数据结构,从而释放内存
如果您想要更可靠的东西,那么,因为引用可能会传递到多个代码段,所以
unbless
将是action at a distance的一个例子,而action at a distance被比我更多的人所怀疑xghobddn4#
我认为
unbless
在我想存储对象数据时很有用,但不存储带有类名的对象数据;准确地说,当你的对象数据的性质意味着是生产数据,而不是为对象自引用工作。字符串
现在,存储的数据结构可以被其他人使用,而不会扰乱其他类的东西,但是没有任何东西扰乱运行时示例。