从perldoc -f bless开始:bless REF,CLASSNAME这个函数告诉REF引用的东西CLASSNAME封装中的对象。有没有办法不经过不必要的复制就得到一个不受祝福的结构呢?
bless REF,CLASSNAME
REF
CLASSNAME
epggiuax1#
Data::Structure::Utilunbless($ref)从传递的数据结构中找到的任何对象中删除祝福。
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
0yycz8jy2#
Data::Structure::Util有一个unbless函数可以帮你完成这件事。正如Erik指出的,JSON::XS通常不接受祝福的引用(尽管我希望它能忽略这一点,处理数据结构)。在这种情况下,没有办法绕过它。但是想想为什么你认为你需要取消祝福它。你这样做是为了你自己的一个班级还是另一个班级?这听起来很可疑,像是错误的事情。也许有一个更好的方法。因为你必须假设你知道引用的内部结构,所以你也会遇到与破坏封装相同的问题。如果你要这样做,你可以忽略面向对象的东西,直接访问结构。如果您要为自己的类执行此操作,请考虑提供一个方法来返回数据结构(不必是原始结构),而不是更改对象。您在后续的评论中提到,您这样做可能是为了规避一些Template Toolkit行为。
unbless
Perl是DWIM,但TT甚至是DWIMmier,这有时是不幸的。这里有一个快速的技巧,我在UNIVERSAL中定义了一个TO_JSON,这样它就可以应用于所有的对象。
UNIVERSAL
TO_JSON
#!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 );
js81xvg63#
如果您知道对象由什么支持,则可以在不使用包的情况下执行此操作。散列
$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";
myss37ts4#
Acme::Curse:)
**更新:**谢谢你,Ivan!我混淆了模块。实际上我想给予一个Acme::Damn的链接:))附言另请参阅Acme::Sneeze:)**P.P.S.**它没有真实的的用途,这就是为什么它是Acme::。看布赖恩的帖子。
Acme::
4条答案
按热度按时间epggiuax1#
Data::Structure::Util
unbless($ref)
从传递的数据结构中找到的任何对象中删除祝福。
输出量:
0yycz8jy2#
Data::Structure::Util有一个
unbless
函数可以帮你完成这件事。正如Erik指出的,JSON::XS通常不接受祝福的引用(尽管我希望它能忽略这一点,处理数据结构)。在这种情况下,没有办法绕过它。但是想想为什么你认为你需要取消祝福它。你这样做是为了你自己的一个班级还是另一个班级?这听起来很可疑,像是错误的事情。也许有一个更好的方法。
因为你必须假设你知道引用的内部结构,所以你也会遇到与破坏封装相同的问题。如果你要这样做,你可以忽略面向对象的东西,直接访问结构。
如果您要为自己的类执行此操作,请考虑提供一个方法来返回数据结构(不必是原始结构),而不是更改对象。
您在后续的评论中提到,您这样做可能是为了规避一些Template Toolkit行为。
Perl是DWIM,但TT甚至是DWIMmier,这有时是不幸的。
这里有一个快速的技巧,我在
UNIVERSAL
中定义了一个TO_JSON
,这样它就可以应用于所有的对象。js81xvg63#
如果您知道对象由什么支持,则可以在不使用包的情况下执行此操作。
散列
数组
标量
myss37ts4#
Acme::Curse:)
**更新:**谢谢你,Ivan!我混淆了模块。实际上我想给予一个Acme::Damn的链接:))
附言另请参阅Acme::Sneeze:)
**P.P.S.**它没有真实的的用途,这就是为什么它是
Acme::
。看布赖恩的帖子。