7

これは明らかに絶望的なケースのように思えるかもしれませんが、Perlで不変オブジェクトの循環グラフを作成するためのトリックはありますか?このようなもの:

package Node;
use Moose;
has [qw/parent child/] => (is => 'ro', isa => 'Node');

package main;
my $a = Node->new;
my $b = Node->new(parent => $a);

$a->child今、私が指摘したい場合、私は$b何ができますか?

4

3 に答える 3

5
于 2009-11-21T16:32:53.933 に答える
4

私は実際に不変の言語がこのようなことをどのように行うかを見に行く必要がありました、そして次のことはおそらく合理的な試みだと思います。

use 5.10.0;
{

    package Node;
    use Moose;
    has [qw(parent child)] => ( isa => 'Node', is => 'ro' );

    sub BUILD {
        my ( $self, $p ) = @_;
        return unless exists $p->{_child};
        my $child = Node->new( parent => $self, %{ delete $p->{_child} }, );
        $self->meta->get_attribute('child')->set_value( $self, $child );
    }
}

say Node->new( _child => {} )->dump

基本的に、オブジェクトを個別に構築しようとする代わりに、引数の受け渡しに基づいて親に子を自動活性化させます。これの出力は、あなたが望んでいた構造であると私は信じています。

$VAR1 = bless( {
                 'child' => bless( {
                                     'parent' => $VAR1
                                   }, 'Node' )
               }, 'Node' );
于 2009-11-21T18:54:11.717 に答える
1

私はまだMooseを初めて使用しますが、トリガーは機能しますか?

use Modern::Perl;

package Node;
use Moose;
has 'parent' => (
    is => 'ro',
    isa => 'Node',
    trigger => sub{
        my ($self, $parent) = @_;
        $parent->{child} = $self unless defined $parent->child;
    }
);

has 'child' => (
    is => 'ro',
    isa => 'Node',
    trigger => sub{
        my ($self, $child) = @_;
        $child->{parent} = $self unless defined $child->parent;
    }
);

package main;
my $p = Node->new;
my $c = Node->new(parent => $p);

say $p, ' == ', $c->parent;
say $c, ' == ', $p->child;
于 2009-11-21T16:06:18.590 に答える