PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Perl] Hash vergisst (fast) alle keys



ThorstenHirsch
06-07-2005, 16:21
Servus!

Ich weiß nicht woran's liegen kann, schaut euch mal bitte folgendes an:


my %hash=();

$hash{'@eins@'}=1;
$hash{'@zwei@'}=2;
$hash{'@drei@'}=3;

open(FH,"<einedatei.txt");

machemol(*FH,%hash);

sub machemol
{
my $fh = shift;
my %mapping = shift;

foreach my $key (keys %mapping)
{
print "key $key\n";
}
}

Ausgabe ist "key @drei@".
Was ist mit den anderen beiden passiert?

Gruß
Thorsten

michael.sprick
06-07-2005, 17:09
Das Problem liegt hier:



sub machemol
{
my $fh = shift;
my %mapping = shift;


shift ist ja in wirklichkeit shift(@_).
Shift() verkürzt das Array @_ indem es alle Indizes um eins dekrementiert. Zusätzlich gibt shift() das Element was vorne "rausfällt" zurück.
Die anderen Elemente verbleiben in @_.

Es gibt mehrere Möglichkeiten damit umzugehen.
Die einfachste ist:



sub machemol
{
my $fh = shift;
my %mapping = @_;
Allerdings ist das nicht immer machbar, denn Du willst ja evtl. auch mal einen Skalar, ein Hash UND zusätzlich noch ein normales Array übergeben... spätestens dann bekommst Du bei obiger Lösung ein Problem.

Am sichersten ist es, Du übergibst eine Referenz...



machemol(*FH,\%hash);

sub machemol
{
my $fh = shift;
my $mapref = shift;

foreach my $key (keys %{$mapref})
{
print "key $key\n";
}
}



hth

ThorstenHirsch
06-07-2005, 17:19
Danke, Michael!

Ich hatte es sogar schon mit ner Referenz probiert, aber dann war plötzlich alles 1 (...etwas später, das eigentliche Skript ist nämlich etwas komplizierter). Jetzt seh ich dass ich die Hashreferenz anderes ansprechen muss und es deswegen nicht funktioniert hat. Danke nochmal!

Gruß
Thorsten

michael.sprick
06-07-2005, 17:42
Ja, Du musst dereferenzieren...

z.B.



my $var = "String";
my $ref = \$var
my $var2 = ${$ref};

oder

my @array = ('eins','zwei','drei');
my $ref = \@array;
my @array2 = @{$ref};

und bei Hash kennst Du´s ja jetzt ;)

siehe auch:

perldoc perlref
perldoc perlreftut