Perl でオブジェクトを祝福解除するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/2329385

  •  22-09-2019
  •  | 
  •  

質問

から perldoc -f 祝福:

bless REF,CLASSNAME

この関数は、によって参照されるものを伝えます。 REF それが今だということ
内のオブジェクト CLASSNAME パッケージ。

不必要なコピーを行わずに祝福されていない構造を取得する方法はありますか?

役に立ちましたか?

解決

データ::構造:: Utilの

  

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

他のヒント

データ::構造::使用率 持っています unbless それをやってくれる関数です。エリックが指摘するように、 JSON::XS 通常、祝福された参照は受け入れられません (ただし、それを無視してデータ構造を処理できることを願っています)。この場合、回避する方法はありません。

しかし、なぜそれを祝福しない必要があると思うのか考えてみましょう。これを自分のクラスでやっているのか、それとも別のクラスでやっているのか?これは疑わしいほど「The Wrong Thing To Do」のように聞こえます。もっと良い方法があるかもしれません。

参照の内部構造が何であるかを知っていると仮定する必要があるため、カプセル化を解除する場合と同じ問題が発生します。それを行う場合は、オブジェクト指向のものを無視して、構造に直接アクセスできます。

独自のクラスでこれを行う場合は、オブジェクトを変更する代わりに、データ構造 (元の構造である必要はない) を返すメソッドを提供することを検討してください。

フォローアップのコメントで、テンプレート ツールキットの動作を回避するためにこれを行っている可能性があると述べています。この状況は、状況に応じて 2 つの方法で発生しました。

  • オブジェクト全体ではなく、必要なデータのみをテンプレートに渡します。
  • オブジェクトにメソッドを追加して、テンプレートに必要なデータを取得します。

Perl は DWIM ですが、TT はさらに DWIMmier であり、残念な場合があります。


これは、私が定義する簡単なハックです。 TO_JSONUNIVERSAL したがって、すべてのオブジェクトに適用されます。ディープコピーを作成し、祝福を解除し、データ構造を返します。

#!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";

アクメ::カース :)

アップデート: ありがとう、イワン!モジュールを混同してしまいました。本当はリンクを貼ろうと思っていたのですが、 アクメ::くそー :))

P.S. こちらも参照 アクメ::くしゃみ :)

P.P.S. 実際には何の役にも立たない、だからこそ Acme::. 。ブライアンの投稿を参照してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top