Thread Dereferenzierung klappt nicht (14 answers)
Opened by bianca at 2022-02-06 09:40

haj
 2022-02-06 12:45
#194229 #194229
User since
2015-01-07
527 Artikel
BenutzerIn

user image
Das einfache zuerst:
2022-02-06T08:40:53 bianca
Kann das Problem damit zu tun haben, dass ein Hashkey eine Referenz auf ein anderes Hash ist?

Ein Hash-Key ist immer ein String und nie eine Referenz.

Ansonsten ist Dein Code nicht so ganz leicht nachzuvollziehen. Da gibt's unbenutzte Teile (Fcntl, Date::Calc, $coderef) und es ist etwas mühsam, die Ausgaben von Data::Dumper per Hand zu vergleichen, ohne zu wissen, wie's denn aussehen soll. Ich habe trotzdem einen Verdacht, was da passiert:

Eine Zuweisung wie my %tmp_io = %$io; erstellt eine "flache" Kopie von %$io. Wenn der Hash geschachtelt ist (also Werte des Hash selbst Referenzen sind), dann wird die Referenz kopiert - das Ding zeigt also in der Kopie und im Original auf den gleichen Hash. Was Du in der Kopie in einer tieferen Ebene änderst, änderst Du also auch im Original.

In Deinem Codebeispiel änderst Du $tmp_io{verkn}, das ist in der obersten Ebene und damit unfallfrei. In Deiner "Fehlerzeile" $tmp_io{links}{refer} = $io->{links}{refer}{$entry}; änderst Du in den Innereien: $tmp_io{links} ist eine Referenz. Wenn Du also auch mit my %tmp_io = %$io; eine flache Kopie erstellst, dann wird diese Referenz kopiert und zeigt in %tmp_io auf den gleichen Hash. Und wenn Du dann in diesem Hash den Wert des Schlüssels refer änderst, dann änderst Du ihn auch in $io!

Wenn Du unfallfrei in geschachtelten Hashes arbeiten willst, dann musst Du anstelle der einfachen Kopie Deine Struktur klonen. Dazu gibt's diverse Module auf CPAN, aber für den Normalfall tun's zwei aus dem Perl-Core: CPAN:Data::Dumper und CPAN:Storable.

Anwendungsbeispiele:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
use 5.020;
use strict;
use warnings;

my %deep = (
    a => {
        aa => {
            aaa => 1, aab => 2,
        },
        ab => 3,
    },
    b => 4
);

use Data::Dumper;
my $VAR1; # sonst beisst's den eval wegen use strict;
my %ddclone = %{ eval Dumper(\%deep) };

use Storable qw(dclone);
my %stclone = %{dclone \%deep};

View full thread Dereferenzierung klappt nicht