2009-07-21 8 views
22

Ich wurde aufgefordert, einige vorhandenen Code zu ändern, um einige zusätzliche Funktionen hinzuzufügen. Ich habe auf Google gesucht und kann die Antwort nicht finden. Ich habe etwas zu diesem Effekt ...Wie kann ich Hashes als Argumente für Unterroutinen in Perl verwenden?

%first_hash = gen_first_hash(); 
%second_hash = gen_second_hash(); 
do_stuff_with_hashes(%first_hash, %second_hash); 

sub do_stuff_with_hashes 
{ 
    my %first_hash = shift; 
    my %second_hash = shift; 

    # do stuff with the hashes 
} 

ich die folgenden Fehler bin immer:

Odd number of elements in hash assignment at ./gen.pl line 85. 
Odd number of elements in hash assignment at ./gen.pl line 86. 
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 124. 
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 143. 

Linie 85 und 86 sind die ersten beiden Zeilen in der Unterroutine und 124 und 143 sind, wo ich bin auf die Hashes zugreifen. Wenn ich diese Fehler nachschaue, scheint es, dass meine Hashes nicht initialisiert sind. Ich kann jedoch überprüfen, dass die Hashwerte Werte haben. Warum bekomme ich diese Fehler?

+1

Dies ist ein Duplikat. Bitte werfen Sie einen Blick auf http://stackoverflow.com/questions/944784/ – innaM

Antwort

24

Die Hashes werden in flache Listen zusammengefasst, wenn Sie sie an die Funktion übergeben. Wenn Sie also einen Wert aus den Argumenten der Funktion entfernen, erhalten Sie nur einen Wert. Was Sie tun möchten, ist, die Hashes als Referenz zu übergeben.

do_stuff_with_hashes(\%first_hash, \%second_hash); 

Aber dann müssen Sie mit den Hashes als Referenzen arbeiten.

my $first_hash = shift; 
my $second_hash = shift; 
+0

Ich sehe ... Das hat den Trick ... Vielen Dank! – predhme

5

First off,

do_stuff_with_hashes(%first_hash, %second_hash); 

"Streams" die Hashes in eine Liste, das entspricht:

('key1_1', 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ...) 

und dann wählen Sie eine und nur eine dieser Elemente. So

my %first_hash = shift; 

ist wie wenn man sagt:

my %first_hash = 'key1_1'; 
# leaving ('value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ...) 

Sie nicht einen Hash wie { 'key1' } haben kann, da 'key1' ist Zuordnung zu nichts.

+1

Danke für die Erklärung, was hinter den Kulissen vor sich ging. – predhme

9

Hash-Referenzen sind der Weg zu gehen, wie die anderen darauf hingewiesen haben.

Einen anderen Weg bieten, dies nur für Tritte zu tun ... denn wer braucht temporäre Variablen?

do_stuff_with_hashes({ gen_first_hash() }, { gen_second_hash() }); 

Hier sind Sie nur Hashreferenzen on the fly (über die geschweiften Klammern um die Funktionsaufrufe) zu schaffen, in Ihrer do_stuff_with_hashes Funktion zu verwenden. Das ist nichts besonderes, die anderen Methoden sind genauso gültig und wahrscheinlich klarer. Dies kann helfen, wenn Sie diese Aktivität auf Ihrer Reise als eine neue Person in Perl sehen.

+0

Großer Trick! Ich behalte das herum. – predhme

+0

Glücklich zu verpflichten. Eine Sache, die Sie im Auge behalten sollten, wenn Sie in Perl bleiben, ist, dass jeder darauf hinweist, dass "es mehr als einen Weg gibt, es zu tun". Es ist ein Segen und ein Fluch, abhängig von Ihrer Meinung über solche Dinge in Perl Programmierung. Habe Spaß! –

14

Ein bisschen spät, aber,

Wie bereits erwähnt wurde, müssen Sie Referenzen übergeben, nicht Hashes.

Aber wenn Sie Ihre Hashes so verwenden möchten/können, können Sie sie sofort dereferenzieren.

sub do_stuff_with_hashes { 
    my %first_hash = %{shift()}; 
    my %second_hash = %{shift()}; 
}; 
+0

um klar zu sein, ich bin nicht Dereferenzierung der Hashes, ich kopiere sie. – larelogio

Verwandte Themen