bless REF,CLASSNAME
此函数告诉
REF
引用的东西,它现在是
CLASSNAME
包中的对象。
有没有办法在没有不必要的复制的情况下获得无结构的结构?
答案 0 :(得分:39)
unbless($ref)
从传递的数据结构中找到的任何对象中删除祝福。
#!/usr/bin/perl
use strict; use warnings;
use Scalar::Util qw( refaddr );
use Data::Structure::Util qw( unbless );
my $x = bless { a => 1, b => 2 } => 'My';
printf "%s : %s\n", ref $x, refaddr $x;
unbless $x;
printf "%s : %s\n", ref $x, refaddr $x;
输出:
My : 237356 HASH : 237356
答案 1 :(得分:29)
Data::Structure::Util有一个unbless
功能,可以为您完成。正如Erik指出的那样,JSON::XS通常不接受有福的引用(尽管我希望它会忽略它并处理数据结构)。在这种情况下,没有办法解决它。
但请考虑为什么你认为你需要解开它。你是为自己的班级还是其他班级做这个?这听起来像是错误的事情。可能有更好的方法。
您遇到与破坏封装相同的问题,因为您必须假设您知道引用的内部结构是什么。如果你打算这样做,你可以忽略面向对象的东西并直接访问结构。
如果要为自己的类执行此操作,请考虑提供一种方法来返回数据结构(不必是原始结构),而不是更改对象。
您在后续评论中提到您可能正在执行此操作以解决某些Template Toolkit行为。我根据情况以两种方式处理这种情况:
Perl是DWIM,但TT甚至是DWIMmier,这有时是不幸的。
这是一个快速入侵,我在TO_JSON
中定义了UNIVERSAL
,因此它适用于所有对象。它会进行深层复制,使其无效并返回数据结构。
#!perl
use v5.10;
sub UNIVERSAL::TO_JSON {
my( $self ) = shift;
use Storable qw(dclone);
use Data::Structure::Util qw(unbless);
my $clone = unbless( dclone( $self ) );
$clone;
}
my $data = bless {
foo => bless( [], 'Local::Array' ),
quack => bless( {
map { $_ => bless [$_, $_**2], 'Local::Array' }
grep { is_prime } 1 .. 10
}, 'Local::Hash' ),
}, 'Local::Hash';
use JSON::XS;
my $jsonner = JSON::XS->new->pretty->convert_blessed(1);
say $jsonner->encode( $data );
答案 2 :(得分:23)
如果您知道备份对象的内容,则可以在不使用包的情况下执行此操作。
哈希
$obj = bless {}, 'Obj';
print ref $obj, "\n";
$obj = { %$obj };
print ref $obj, "\n";
阵列
$obj = bless [], 'Obj';
print ref $obj , "\n";
$obj = [ @$obj ];
print ref $obj, "\n";
标量
$obj = bless \$a, "Obj";
print ref $obj, "\n";
$obj = \${ $$obj };
print ref $obj, "\n";
答案 3 :(得分:12)
Acme::Curse :)
更新:谢谢你,伊万!我混淆了模块。其实我想提供一个Acme::Damn的链接:))
<强> P上。 S。另见Acme::Sneeze:)
<强> P上。 P. S. 它没有实际用途,这就是Acme::
的原因。见布莱恩的帖子。