Perl:如何深层复制一个有福的对象?

我期望做一个深奥的(在这一点上,浅可能就足够了)复制一个有福的对象。

美孚类

package Foo;
our $FOO = new Foo;       # initial run

sub new {
   my $class = shift;
   my $self  = {};
   bless $self, $class;
   return $self;
}

主程序

use Foo;
my $copy = $Foo::FOO;     # instead of creating a ref, want to deep copy here
$copy->{bar} = 'bar';

bar出现在$Foo::FOO$copy 。 我意识到我可以通过将它设置为$copy = { %{$Foo::FOO} }来创建一个对象的$copy = { %{$Foo::FOO} } ,但是不会再被祝福; 此外,这只适用于简单的数据结构(现在不是问题)。 是复制这种方式然后祝福的唯一方法(例如$copy = bless { %{$Foo::FOO} }, q{Foo}; )?

我试图避免使用Moose,Clone或其他非核心模块/软件包,因此请在回复时记住这一点。 因为它更突出,所以它显得更加粗糙


复制应该是API的一部分。 模块的用户永远不会知道在创建新对象时需要做什么特别的操作(考虑将每个对象注册到包中的my哈希中)。

因此,为您的对象提供一个clone方法。 在里面,你可以使用任何你喜欢的肮脏的技巧:

sub clone {
    my $self = shift;
    my $copy = bless { %$self }, ref $self;
    $register{$copy} = localtime; # Or whatever else you need to do with a new object.
    # ...
    return $copy;
}

use Storable 'dclone';

$ corelist Storable

Storable was first released with perl v5.7.3

另外,你可以利用可存储的钩子来操纵复制对象的更好的控制(不是我已经完成了,但这就是文档声明的)。


my $copy = bless { %$self }, ref $self; 在@ chorba的答案是不够的。 它只会克隆第一层。 存储在$self任何引用都不会被克隆。 这造成的后果是......

$obj->{ponies} = [qw(Dash Sparkle Jack)];
$clone = $obj->clone;
push @{$clone->{ponies}}, "Pinkie";
print join ", ", @{$obj->{ponies}};  # Dash Sparkle Jack Pinkie

你现在可能没有任何参考资料,但你可能会迟些。 或者其他人将一个人粘在你的物体上。 或者他们将继承并添加一个。

你可以写一个很深的克隆程序,但这并不简单。 我强烈建议使用克隆。 它没有依赖关系,因此您可以简单地将Clone.pm复制到您的项目中。

另一种选择是@Zaid提到的Storable :: dclone,它已经在很长一段时间内处于核心地位。

无论您使用什么方法,在您的课堂上提供克隆方法都是正确的,即使它只是克隆或Stored :: dclone的包装。 这会将你的对象的用户从你的对象克隆的细节中屏蔽掉。

链接地址: http://www.djcxy.com/p/79369.html

上一篇: Perl: How to deep copy a blessed object?

下一篇: Creating clone of an object not working with virtual base class