から perldoc -f bless :
bless REF,CLASSNAME
この関数は、
REF
によって参照されているものに現在であることを通知しますCLASSNAME
パッケージ内のオブジェクト。
不必要なコピーをせずに祝福されていない構造を取得する方法はありますか?
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;
出力:
私:237356 ハッシュ:237356
Data :: Structure :: Util には、それを実行するunbless
関数があります。 Erikが指摘しているように、 JSON :: XS は通常、祝福された参照を受け入れません(ただし、それを無視してデータ構造を処理することを望みます)。この場合、それを回避する方法はありません。
しかし、なぜあなたはそれを祝福する必要があると思いますか?あなたはあなた自身のクラスの1つまたは別のクラスのためにこれをしていますか?これは、The Wrong Thing ToDoのように不審に聞こえます。より良い方法があるかもしれません。
参照の内部構造が何であるかを知っていると想定する必要があるため、カプセル化を解除するのと同じ問題が発生します。これを行う場合は、オブジェクト指向のものを無視して、構造に直接アクセスできます。
独自のクラスに対してこれを行う場合は、オブジェクトを変更する代わりに、データ構造(元の構造である必要はありません)を返すメソッドを提供することを検討してください。
フォローアップコメントで、TemplateToolkitの動作を回避するためにこれを行っている可能性があると述べています。私は状況に応じて2つの方法でこの状況になりました:
PerlはDWIMですが、TTはDWIMmierでさえあり、それは時々不幸です。
これは、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 );
オブジェクトが何によって支えられているかがわかっている場合は、パッケージを使用せずにこれを行うことができます。
ハッシュ
$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";
更新:ありがとう、Ivan!モジュールを混同しました。実は私は Acme :: Damn :))へのリンクを与えたかったのです
P。 S。関連項目 Acme :: Sneeze :)
P。 P. S。実際には使用されないので、Acme::
。ブライアンの投稿を参照してください。