Schrift
[thread]6756[/thread]

Array of hashs (Seite 2)

Leser: 2


<< |< 1 2 3 >| >> 21 Einträge, 3 Seiten
Crian
 2005-03-03 17:48
#52258 #52258
User since
2003-08-04
5873 Artikel
ModeratorIn
[Homepage]
user image
Hier das zweite Beispiel:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/perl
use strict;
use warnings;
use Storable qw//;

use Data::Dumper; $Data::Dumper::Sortkeys = 1;

my %h1 = (
a => { inhalt => 1 },
b => { inhalt => 2 },
c => { inhalt => 3 },
d => { inhalt => 4 },
);
print "Adresse h1 -> ", \%h1, "\n";
print "Adresse h1_a -> ", $h1{a}, "\n";
print 'h1 : ', Dumper \%h1;

my $h2 = \%h1;
print "Adresse h2 -> ", $h2, "\n";
print "Adresse h2_a -> ", $h2->{a}, "\n";
$h2->{c}->{inhalt} = 33;
print 'h1 : ', Dumper \%h1;
print 'h2 : ', Dumper $h2;

my $h3 = { %h1 };
print "Adresse h3 -> ", $h3, "\n";
print "Adresse h3_a -> ", $h3->{a}, "\n";
$h3->{d}->{inhalt} = 44;
print 'h1 : ', Dumper \%h1;
print 'h3 : ', Dumper $h3;

my $h4 = Storable::dclone \%h1;
print "Adresse h4 -> ", $h4, "\n";
print "Adresse h4_a -> ", $h4->{a}, "\n";
$h4->{a}->{inhalt} = 11;
print 'h1 : ', Dumper \%h1;
print 'h4 : ', Dumper $h4;


Ausgabe:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
Adresse h1   -> HASH(0x1a45948)
Adresse h1_a -> HASH(0x15d5230)
h1 : $VAR1 = {
'a' => {
'inhalt' => 1
},
'b' => {
'inhalt' => 2
},
'c' => {
'inhalt' => 3
},
'd' => {
'inhalt' => 4
}
};
Adresse h2 -> HASH(0x1a45948)
Adresse h2_a -> HASH(0x15d5230)
h1 : $VAR1 = {
'a' => {
'inhalt' => 1
},
'b' => {
'inhalt' => 2
},
'c' => {
'inhalt' => 33
},
'd' => {
'inhalt' => 4
}
};
h2 : $VAR1 = {
'a' => {
'inhalt' => 1
},
'b' => {
'inhalt' => 2
},
'c' => {
'inhalt' => 33
},
'd' => {
'inhalt' => 4
}
};
Adresse h3 -> HASH(0x1b0e4d8)
Adresse h3_a -> HASH(0x15d5230)
h1 : $VAR1 = {
'a' => {
'inhalt' => 1
},
'b' => {
'inhalt' => 2
},
'c' => {
'inhalt' => 33
},
'd' => {
'inhalt' => 44
}
};
h3 : $VAR1 = {
'a' => {
'inhalt' => 1
},
'b' => {
'inhalt' => 2
},
'c' => {
'inhalt' => 33
},
'd' => {
'inhalt' => 44
}
};
Adresse h4 -> HASH(0x15d5464)
Adresse h4_a -> HASH(0x1b7a570)
h1 : $VAR1 = {
'a' => {
'inhalt' => 1
},
'b' => {
'inhalt' => 2
},
'c' => {
'inhalt' => 33
},
'd' => {
'inhalt' => 44
}
};
h4 : $VAR1 = {
'a' => {
'inhalt' => 11
},
'b' => {
'inhalt' => 2
},
'c' => {
'inhalt' => 33
},
'd' => {
'inhalt' => 44
}
};


Wie man sieht, sind zwar die Adressen der Hashes (bzw. der Referenzen) verschiedene, sie verweisen aber alle (bis auf das letzte) auf die gleiche Substrukturen (die Substruktur zu a liegt z.B. immer an Speicherstelle 0x15d5230), deshalb wird diese auch gleich bei allen mitgeändert.
Nur das wirklich geclonte Objekt hat auch geclonte Substrukturen. Und nicht nur in Tiefe 2, sondern auch in Tiefe 123, wenn es sein muss.

Ich hoffe, das war jetzt einigermaßen verständlich.\n\n

<!--EDIT|Crian|1109865486-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
roli
 2005-03-04 17:13
#52259 #52259
User since
2004-12-31
424 Artikel
BenutzerIn
[default_avatar]
Hi Carin,

wenn das eine "duerre Antwort" ist, dann moechte ich von dir keine ausfuehrliche haben, da waere ich ja Wochen beschaeftigt. Ich muss das alles was du hier Postest erstmal verdauen, sind ja schliesslich ein paar Zeilen. DANKE!

Ich glaube allerdings, das ich mich etwas undeutlich ausgedrückt habe. Was ein Hash, eine Referenz ... ist weiss ich schon, bzw. weiss wo ich's nachschlagen kann. Was mich interessiert ist, was bewirken die geschweiften Klammern, so das es ohne nicht geht!
Code: (dl )
$jobconf[$job_no]={%current_job};


Mach's gut

Roland
Roland
--
"Steh vorn, während du fragst;
sitzen soll, wer antwortet."
Aus "Die Edda des Snorri Sturluson" "Gylfis Täuschung" Strophe 2
roli
 2005-03-04 17:43
#52260 #52260
User since
2004-12-31
424 Artikel
BenutzerIn
[default_avatar]
Ich hab's mir jetzt mehrfach durchgelesen, aber bei h3 im zweiten Beispiel setzt's aus. Warum zu Hölle ist die Adresse von h3_a  "HASH(0x15d5230)" die selbe wie bei h2_a und h1_a? h3 ist doch eine Kopie von h1, liegt demnach an einer anderen Position im Speicher, also wuerde ich doch erwarten, das der Inhalt, wie auch immer er beschaffen ist, ebenfalls kopiert wird, und dann auch an einer anderen Stelle im Speicher liegt!
Wieso wird mit
Code: (dl )
$h3->{d}->{inhalt} = 44;
auch der Inhalt von h1 veraendert?

Fragen, nichts als Fragen

Roland
Roland
--
"Steh vorn, während du fragst;
sitzen soll, wer antwortet."
Aus "Die Edda des Snorri Sturluson" "Gylfis Täuschung" Strophe 2
renee
 2005-03-04 18:53
#52261 #52261
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Wenn Du $h3 = {%h1} machst, wird nicht die komplette Datenstruktur kopiert, sondern nur die Keys und wenn der Wert eine Referenz ist, die Referenz auf den Wert. Das nennt man glaube ich shallow copy.
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Dubu
 2005-03-04 19:11
#52262 #52262
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=renee,04.03.2005, 17:53]Wenn Du $h3 = {%h1} machst, wird nicht die komplette Datenstruktur kopiert, sondern nur die Keys und wenn der Wert eine Referenz ist, die Referenz auf den Wert. Das nennt man glaube ich shallow copy.[/quote]
Jein. Es werden schon Schluessel und Werte kopiert, aber wenn der kopierte Wert eine Referenz ist, dann zeigt der Wert in der Kopie natuerlich auf die gleiche Adresse. Aber Shallow Copy passt schon. 8)

Die Wortwahl ist vielleicht etwas schlecht. Was hinter "Adresse h1   ->" ausgegeben wird, ist tatsaechlich die Adresse des Hashes %h1, aber hinter "Adresse h1_a ->" steht nicht die Adresse von $h1->{a}, sondern der Wert.
roli
 2005-03-04 19:51
#52263 #52263
User since
2004-12-31
424 Artikel
BenutzerIn
[default_avatar]
Danke Ihr 2,

jetzt habe ich wieder was wonach ich googeln kann ;-}
Aber wirklich verstehen, warum mein Script nur laeuft, wenn ich
Code: (dl )
$jobconf[$job_no]={%current_job};
(also ein Shallow Copy) verwende, und nicht wenn ich
Code: (dl )
$jobconf[$job_no]=%current_job;
benutze "tu" ich nicht. Irgendwie beschleicht mich das Gefuehl, das ich ggf. ein ganz anderes Problem habe.

Roland
Roland
--
"Steh vorn, während du fragst;
sitzen soll, wer antwortet."
Aus "Die Edda des Snorri Sturluson" "Gylfis Täuschung" Strophe 2
renee
 2005-03-05 00:32
#52264 #52264
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Eine Referenz legt keine Kopie des Hashs an. Du hast dem Arrayelement eine Referenz zugewiesen.

Vielleicht macht das folgende das etwas deutlicher, was das Problem bei Deinem ursprünglichen Code ist:

Stell Dir vor, Du hast einen Schatz. Dieser Schatz stellt den Wert dar. Jetzt malst Du Dir eine Schatzkarte, die der Schlüssel zum Schatz ist. Du willst aber die Schatzkarte aber nicht immer bei Dir haben, deswegen schreibst Du Dir in Dein Notizbuch einen Hinweis auf, wo die Schatzkarte zu finden ist - zum Beispiel die Schublade Deines Schreibtisches (also quasi die Referenz auf das Schlüssel-Wert-Paar [der Hash]). Wenn Du jetzt aber Schatzkarte und Schatz vernichtest (undef Hash), dann hast Du zwar noch die Referenz auf den Hash, aber hinter dieser Referenz (Angabe, unter welcher Adresse etwas zu finden ist) ist nix mehr. Wenn Du in die Schublade schaust, die Du Dir aufgeschrieben hast, dann ist diese Leer, weil die Schatzkarte ja vernichtet wurde...

@Dubu: Hast Recht, vielleicht wirklich keine sehr gute Wortwahl, aber Du hast ja das geschrieben, was ich ausdrücken wollte...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Crian
 2005-03-05 01:42
#52265 #52265
User since
2003-08-04
5873 Artikel
ModeratorIn
[Homepage]
user image
Ich dachte genau das hätten die Beispiele erklärt :cool:
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
roli
 2005-03-05 13:40
#52266 #52266
User since
2004-12-31
424 Artikel
BenutzerIn
[default_avatar]
Hi,

so 100% sicher das ich's verstanden habe bin ich mir nicht, das meine Urspruengliche Zuweisung mit der Referenz nix gibt, wenn ich dann undef "mache", habe ich begriffen.
Aber warum's (nur) mit "$jobconf[$job_no]={%current_job};" geht, also einem Shallow Copy, und nicht mit einer gewoehnlichen Zuweisung "$jobconf[$job_no]=%current_job;" verstehe ich halt noch nicht.
Aber ich denke, bevor ich eure Geduld ueberstrapaziere, sollte ich erstmal lesen, Ihr habt mir ja doch einiges an Input geliefert.

Vielen Dank erstmal

Roland
Roland
--
"Steh vorn, während du fragst;
sitzen soll, wer antwortet."
Aus "Die Edda des Snorri Sturluson" "Gylfis Täuschung" Strophe 2
Dubu
 2005-03-10 21:39
#52267 #52267
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=roli,05.03.2005, 12:40]Aber warum's (nur) mit "$jobconf[$job_no]={%current_job};" geht, also einem Shallow Copy, und nicht mit einer gewoehnlichen Zuweisung "$jobconf[$job_no]=%current_job;" verstehe ich halt noch nicht.[/quote]
$jobconf[$job_no] ist ein Eintrag in einem Array und kann damit nur ein Skalar oder eine Referenz sein.
%current_job ist dagegen ein Hash. Wenn ein Hash in skalarem Kontext aufgerufen wird (wie in dieser Zuweisung), liefert er die Anzahl der belegten und der reservierten Buckets als String "n/m" zurueck - das, was du gesehen hast.

In $jobconf[$job_no]={%current_job} erzeugen die geschwungenen Klammern eine Referenz auf einen anonymen Hash, der als Inhalt alle Elemente aus %current_job enthaelt. Diese Referenz kann wiederum problemlos in $jobconf[$job_no] gespeichert werden.

Analog kann man mit eckigen Klammern eine Referenz auf ein anonymes Array anlegen. Vergleiche
@array = (1, 2, 3, 4, 5)
mit
$array_ref = [ 1, 2, 3, 4, 5 ]
oder
$array_ref = [ @array ]
<< |< 1 2 3 >| >> 21 Einträge, 3 Seiten



View all threads created 2005-03-02 23:06.