gpt4 book ai didi

perl - 如何在 Perl 和 Moose 中创建不可变对象(immutable对象)的循环图?

转载 作者:行者123 更新时间:2023-12-04 11:17:31 25 4
gpt4 key购买 nike

这似乎是一个明显没有希望的情况,但是在 Perl 中创建不可变对象(immutable对象)的循环图有什么技巧吗?像这样的东西:

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 , 我能做些什么?

最佳答案

你可以玩延迟初始化的游戏:

package Node;
use Moose;

has parent => (
is => 'ro',
isa => 'Node',
lazy => 1,
init_arg => undef,
builder => '_build_parent',
);

has _parent => (
is => 'ro',
init_arg => 'parent',
);

has child => (
is => 'ro',
isa => 'Node',
lazy => 1,
init_arg => undef,
builder => '_build_child',
);

has _child => (
is => 'ro',
init_arg => 'child',
predicate => undef,
);

has name => is => 'ro', isa => 'Str';

动态生成构建器和谓词:
BEGIN {
for (qw/ parent child /) {
no strict 'refs';

my $squirreled = "_" . $_;

*{"_build" . $squirreled} = sub {
my($self) = @_;
my $proto = $self->$squirreled;
ref $proto eq "REF" ? $$proto : $proto;
};

*{"has" . $squirreled} = sub {
my($self) = @_;
defined $self->$squirreled;
};
}
}

这允许
my $a = Node->new(parent => \my $b, name => "A");
$b = Node->new(child => $a, name => "B");

for ($a, $b) {
print $_->name, ":\n";
if ($_->has_parent) {
print " - parent: ", $_->parent->name, "\n";
}
elsif ($_->has_child) {
print " - child: ", $_->child->name, "\n";
}
}

它的输出是
A:
- parent: B
B:
- child: A

使用 η-conversion‎ 可以使代码更优雅,但 Moose 不会将参数传递给构建器方法。

关于perl - 如何在 Perl 和 Moose 中创建不可变对象(immutable对象)的循环图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1775486/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com