PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : perl und hashes



elrond
01-07-2008, 16:31
hallo,

ich habe folgendes problem:

Ich versuche in einem script eine kopie von einem hash zu erzeugen und schreibend darauf zuzugreifen. Funktioniert, aber auch das Original ändert sich.. :confused:

ich hab das mal in ein testscript gepackt


#!/usr/bin/perl -w
use Data::Dumper;

my %h_1=();
$h_1{'a'}{'b'}{'c'}='text';
print "-- h_1 nach erster zuweisung-----------\n";
print Dumper(%h_1);
my %h_2=%h_1;
print "-- h_2 nach kopie-----------\n";
print Dumper(%h_2);
$h_2{'a'}{'b'}{'c'}='text2';
print "-- h_2 nach zuweisung-----------\n";
print Dumper(%h_2);
print "-- h_1 nach zuweisung-----------\n";
print Dumper(%h_1);


Ausgabe:


-- h_1 nach erster zuweisung-----------
$VAR1 = 'a';
$VAR2 = {
'b' => {
'c' => 'text'
}
};
-- h_2 nach kopie-----------
$VAR1 = 'a';
$VAR2 = {
'b' => {
'c' => 'text'
}
};
-- h_2 nach zuweisung-----------
$VAR1 = 'a';
$VAR2 = {
'b' => {
'c' => 'text2'
}
};
-- h_1 nach zuweisung-----------
$VAR1 = 'a';
$VAR2 = {
'b' => {
'c' => 'text2'
}
};


für mich muß aber %h_1 seinen wert behalten, den es zum zeitpunkt der kopie hatte, da %h_1 immer wieder als original herhalten soll...

habt ihr einen tipp für mich?

jan61
01-07-2008, 19:38
Moin,

Dein P.S. deutet an, dass Du selbst den Fehler gefunden hast? Für mich sah es so aus, dass Du durch die Zuweisung an $h_1{'a'}... einen Hash mit Hashreferenzen aufgebaut hast - damit kopierst Du natürlich Adressen, keine Werte.

Wie hast Du das denn nun gelöst? Ist sicher auch für die Allgemeinheit spannend.

Jan

peschmae
01-07-2008, 21:47
Das P.S. ist Teil seiner Signatur ;)

MfG Peschmä

jan61
01-07-2008, 22:39
Moin,


Das P.S. ist Teil seiner Signatur ;)

ah - dann hab ich mir ja nicht umsonst den Kopf zerbrochen ;-)

So kann man die Leute auch verwirren *grml*

Jan

elrond
02-07-2008, 06:34
war nicht meine absicht :D

Ich möchte tatsächlich inhalte kopieren keine zeiger darauf....


...die Zuweisung an $h_1{'a'}...

ich kenne keine andere möglichkeit auf elemente des hashes zuzugreifen...

jan61
02-07-2008, 17:56
Moin,

dei Frage ist erstmal, was für einen Hash Du überhaupt willst. Wie Du an der Dumper-Ausgabe sehen kannst, ist Dein Hash so aufgebaut:
$h_1{'a'} ist eine Hashreferenz, nennen wir sie mal $href_a.
$href_a->{'b'} ist eine Hashreferenz, nennen wir sie mal $href_b.
$href_b->{'c'} ist ein Skalar, nämlich 'text'.

Ist dieser Aufbau Absicht? Oder willst Du einfach einen Hash %h_1 mit drei Schlüsseln? Wenn Du einen verschachtelten Hash kopieren willst, wirst Du wohl die Elemente einzeln kopieren müssen (mir fällt im Moment keine Funktion ein, die die Hashreferenzen auflöst), im Moment kopierst Du die Hashreferenzen (was ja eigentlich Pointer auf die Hashes sind) mit und damit greifst Du auf die gleichen Speicherbereiche zu.

Jan

elrond
03-07-2008, 08:06
Moin,

ich versuche folgendes:

Ich lese aus Performancegründen einmalig XML-Daten aus meiner DB und mittels XML::Simple habe ich einen schönen Hash mit den Daten in der Hand. Diesen will ich als Template benutzen. Also kopiere ich den Hash auf einen neuen, verändere ein paar Daten, hänge das Ding an einen großen Hash und schreibe so Datensatz für Datensatz wieder weg...

Aus bekanntem Grund sehen nun alle Datensätze so aus wie der erste.... :rolleyes:

Mir war nicht klar, dass eben der zugriff $h_1{'a'} ebenso eine Hashreferenz ist wie $h_1->{'a'}...
Aus meinem dicken Perl-Buch(Farid Hajji) geht das nicht hervor. Ist normalerweise wirklich gut...

Wahrscheinlich werde ich die Inhalte tatsächlich einzeln kopieren müssen.

jan61
03-07-2008, 18:28
Moin,


...Mir war nicht klar, dass eben der zugriff $h_1{'a'} ebenso eine Hashreferenz ist wie $h_1->{'a'}...

ist es auch nicht - aber der Inhalt von $h_1{'a'} (also der Wert des Keys) ist eine Hashreferenz. Das kommt durch die Art, wie Du den Hash angelegt hast - siehst Du eben in der Dumper-Ausgabe sehr schön.

Jan

EDIT: Tu mal so: print ref $h_1{'a'}, "\n";