2016-04-26 5 views
2

Ich habe einen globalen Perl-Hash, dem ich den Wert aus meiner lokalen Referenz zuweisen, bin ich nicht sicher, ob das eine Kopie auf den globalen Hash oder verwendet die gleiche Referenz, aber das sollte sein ein lokaler Speicher für den Block.Global Perl Hash Referenz Asignment

#!/usr/bin/env perl 

use strict; 
use warnings; 

my $hash; 
foreach $a (1..10) { 
    my $localref = {"test"=> 1}; 
    $hash->[$a] = $localref; # does this result in copy? 
} 
+3

Nur als eine Randnotiz .... Sie greifen auf $ Hash als Array, nicht als Hash ($ Hash -> {$ a} = $ localref 'wäre die richtige Sache zu tun) – eballes

+3

Ihr Code enthält keine globalen Hashes oder andere globale Variablen. – mob

Antwort

1

Ich nehme an, das die globale hashref sein sollte:

my $hash; 

Die Schleife geht Trog 1 bis 10 einen lokalen Bereich Hashreferenz $ localref erstellen:

foreach $a (1..10) { 
    my $localref = {"test"=> 1}; 

$ localref ist jetzt ein Zeiger auf die Speicheradresse eines hashref enthält {test => 1}. Versuchen Sie, einen print Befehl hinzufügen, um es zu sehen:

print $localref; 

Sie werden feststellen, dass die Speicheradresse für jeden Schleifendurchlauf ändert gezeigt.

$hash->[$a] = $localref; # does this result in copy? 
} 

$hash->[$a] wird mit einem variablen $ hash als ArrayRef genannt. Sie sollten in Erwägung ziehen, es umzubenennen.

Versuchen Sie den Inhalt Ihres „globalen“ $ hash nach der Schleife zeigt:

for (1..10) { 
    print $_."\t".$hash->[$_]; 
} 

Sie werden sehen, alle Ihre Referenzen noch am Leben.

Use Data :: Dumper um den Inhalt zu zeigen:

use Data::Dumper; 
print Dumper($hash); 

Schluss Schlussfolgerung:

Der Speicherplatz Speicherung Ihrer HashRefs immer gleich bleibt, wird der Inhalt niemals kopiert werden, aber die Referenz (Adresse Information) wird kopiert. Zwei Referenzen auf den gleichen Ort existieren für einen kurzen Moment zwischen $hash->[$a] = $localref; und }.

PS: Der von {"test"=> 1} verwendete Speicher wird freigegeben, sobald keine Referenz mehr existiert.

+0

danke Sebastian, ich habe versucht, die Referenzen zu drucken, sie sind die gleichen Referenzen. Speicher wird also nicht freigegeben, es sei denn, es hat alle Referenzen zuletzt, obwohl es in einem anderen Bereich erstellt wurde. – PMat

+0

Das ist richtig @newguy.Dies wird "REFCNT" oder Referenzzählung genannt. Sobald die "REFCNT" auf 0 fällt, wird das Element freigegeben. – stevieb

+0

Ja. Eine Referenzvariable (wie $ localref oder das $ array) ist wie eine Visitenkarte mit der Adresse. Es wegzuwerfen bringt das Haus an dieser Adresse nicht um, man weiß nur nicht mehr, wo es sich befindet - aber andere Leute (Visitenkarten) tun das vielleicht immer noch. – Sebastian

2

$hash ist eigentlich ein Array ref, kein Hash-ref, und nein, das Element ($localref) Sie zur Aref sind Zuordnung ist keine Kopie, weil es sich um eine Referenz handelt. Um eine Kopie zu machen, Sie zu dereferenzieren haben vor dem Einfügen: %{ $array->[$a] } = %$localref;

+0

Ja, es ist ein Array Ref in dem obigen Beispiel, ich meine in einer generischen Weise, im Falle einer Referenz. Das, was ich erwartet habe, aber $ localref ist ein lokaler Speicher, wie funktioniert das? – PMat

+1

Da das Einfügen eines lokalen (dh lexikalischen) Elements in ein Element eines größeren Bereichs als Referenz bedeutet, dass die innere Variable nicht außerhalb des Gültigkeitsbereichs liegt bis das Element im größeren Umfang tut. In Ihrem Fall ist der Gültigkeitsbereich global, so dass die innere $ localref nicht außerhalb des Gültigkeitsbereichs liegt, bis das Programm beendet wird. – stevieb

+0

danke stevieb – PMat