Thread Variablenprefix bei Array/Hash (7 answers)
Opened by t3kkn0kr4t at 2011-02-01 10:21

murphy
 2011-02-07 16:13
#145421 #145421
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
2011-02-07T14:38:39 t3kkn0kr4t
[...]
ist meinem Arbeitskollegen folgendes Snippet zur Veranschaulichung eingefallen:

Code (perl): (dl )
1
2
3
4
5
#!/usr/bin/env perl

%test = "test123";
$link = "test";
print %$link, "\n";

[...]
Funktioniert und verwirrt...

Da hat jemand aber eine merkwürdige Vorstellung von Veranschaulichung ;-)

Was passiert ist folgendes:
  • %test = "test123" erzeugt eine Hashvariable¹, in der dem Schlüssel "test123" der Wert undef zugeodnet wird.
  • $link = "test" erzeugt eine Skalarvariable¹ mit der Zeichenkette "test" als Inhalt.
  • %$link dereferenziert die Skalarvariable $link als Hash¹. Da diese Variable aber gar keine Referenz sondern eine Zeichenkette enthält, wird nach einer Hashvariablen mit dem durch die Zeichenkette gegebenen Namen gesucht. Da solch eine Variable im ersten Schritt angelegt wurde, wird dieser Hash verwendet.
  • print ... evaluiert seine Argumente im Listenkontext, wodurch der dereferenzierte Hash zu den zwei Werten "test123" und undef expandiert.
  • print ... hängt seine Argumente als Zeichenketten aneinander, wobei undef als leere Zeichenkette interpretiert wird². Das Resultat wird ausgegeben.


¹: An diesen Stellen würde in einem ordentlich geschriebenen Perlprogramm, das das Pragma strict verwendet, ein Fehler auftreten.

²: An diesen Stellen würde das Pragma warnings eine Warnung erzeugen.


Eine sauberere Version dieses Codes sähe vielleicht so aus:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
use 5.012;
use warnings;

# Hash erzeugen
my %test = ( test123 => undef );
# Hashreferenz erzeugen
my $link = \%test;

# Hashschlüssel und -werte ausgeben,
# undefinierte Werte explizit durch leere
# Zeichenketten ersetzen
say map { $_ // '' } %$link;


Alternativ könnte man auch eine anonyme Hashreferenz verwenden, die Definition von %test weglassen und
Code (perl): (dl )
my $link = { test123 => undef };

schreiben.
When C++ is your hammer, every problem looks like your thumb.

View full thread Variablenprefix bei Array/Hash