Perl: Wie kann man ein gesegnetes Objekt tief kopieren?

8

Ich suche nach einer tiefen Kopie eines gesegneten Objekts (an dieser Stelle kann es seicht sein).

Foo Klasse

%Vor%

Hauptprogramm

%Vor%

bar erscheint sowohl in $Foo::FOO als auch in $copy . Ich weiß, ich könnte eine Kopie des Objekts erstellen, indem ich es als $copy = { %{$Foo::FOO} } einstelle, aber dann wäre es nicht mehr gesegnet. Außerdem würde dies nur für einfache Datenstrukturen funktionieren (momentan kein Problem). Ist die einzige Möglichkeit, diesen Weg zu kopieren und danach zu segnen (zB $copy = bless { %{$Foo::FOO} }, q{Foo}; )?

Ich versuche, die Verwendung von Moose-, Clone- oder anderen Nicht-Core-Modulen / -Paketen zu vermeiden. Bitte denken Sie daran, wenn Sie antworten. So fett wie es ist mehr aus:)

    
vol7ron 09.05.2013, 14:49
quelle

5 Antworten

10

Das Kopieren sollte Teil der API sein. Der Benutzer Ihres Moduls würde niemals wissen, welche speziellen Aktionen bei der Erstellung eines neuen Objekts erforderlich sind (in Erwägung ziehen, jedes Objekt in einem my Hash in Ihrem Paket zu registrieren).

Stellen Sie daher eine clone -Methode für Ihre Objekte bereit. Darin können Sie alle schmutzigen Tricks verwenden, die Sie mögen:

%Vor%     
choroba 09.05.2013, 15:13
quelle
9

use Storable 'dclone'; ?

%Vor%

Außerdem können Sie mit speicherbaren Hooks herumspielen, um eine bessere Kontrolle über das Kopieren Ihrer Objekte zu erhalten (nicht, dass ich es getan hätte, aber das ist es, was die Dokumentation behauptet).

    
Zaid 09.05.2013 16:02
quelle
4

my $copy = bless { %$self }, ref $self; in @ chorbas Antwort ist unzureichend. Es wird nur die erste Ebene klonen. Alle in $self gespeicherten Referenzen werden nicht geklont. Die Folgen davon sind ...

%Vor%

Sie haben vielleicht keine Referenzen, aber Sie werden es wahrscheinlich später tun. Oder jemand anderes wird einen in dein Objekt stecken. Oder sie unterklassifizieren und fügen eins hinzu.

Sie können eine tiefe Klonroutine schreiben, aber das ist nicht einfach. Ich würde wärmstens empfehlen, Clone zu verwenden. Es hat keine Abhängigkeiten und Sie können einfach Clone.pm in Ihr Projekt kopieren.

Die andere Alternative ist Storable :: dclone , die von @Zaid erwähnt wird, die schon lange im Kern war.

Unabhängig davon, was Sie verwenden, ist die Bereitstellung einer Klonmethode für Ihre Klasse das Richtige, auch wenn es nur ein Wrapper um Clone oder Storable :: dclone ist. Dies schirmt den Benutzer Ihres Objekts vor den Details ab, wie Ihr Objekt geklont wird.

    
Schwern 09.05.2013 18:55
quelle
3

Es gibt keine gute Möglichkeit für das aufrufende Programm zu wissen, was "Kopieren eines Objekts" bedeutet, also sollte ein Objekt wissen, wie es sich selbst kopiert. Perls OO bietet Ihnen hier keine Hilfe, aber das Übliche ist etwas in der Art:

%Vor%     
darch 09.05.2013 17:30
quelle
0

Es tut mir leid, ich kann diesen Satz nicht bemerken:

* Ich versuche, die Verwendung von Moose-, Clone- oder anderen Nicht-Core-Modulen / -Paketen zu vermeiden, also denke bitte daran, wenn du antwortest. Fett, so dass es mehr auffällt :) *

Also konnte diese Antwort nicht akzeptiert werden!

%Vor%     
eric.xiao 28.01.2014 09:03
quelle

Tags und Links