Schrift
[thread]11667[/thread]

Array-Werte in Hash übertragen

Leser: 1


<< |< 1 2 >| >> 15 Einträge, 2 Seiten
RalphFFM
 2008-04-20 12:16
#108567 #108567
User since
2006-11-16
258 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo,

ich habe viele Werte in @_, und möchte nun einen Hash damit füllen,
a la:

%myhash = ('vorname' => $_[0], 'nachname' => $_[1], 'plz' => $_[2], 'ort' => $_[3], 'haustier' => $_[4], 'foobar' => $_[5]);

Das geht doch sicher eleganter zu schreiben? Bitte um einen Tip.
Stehe da irgendwie gerade auf der Leitung.

Danke + Gruß, Ralph
Gast Gast
 2008-04-20 12:59
#108568 #108568
Code (perl): (dl )
@hash{qw/vorname nachname plz ort haustier foobar/} = @_;
RalphFFM
 2008-04-20 13:20
#108569 #108569
User since
2006-11-16
258 Artikel
BenutzerIn
[Homepage] [default_avatar]
Klasse. Sieht gut aus.

Zwischenzeitlich hab ichs auch mit map versucht Perl beizubringen was ich von Perl will:
map {$hash{ q/vorname, nachname, plz, ort, haustier, foobar/ => $_ }} @_;
Habs noch nicht ausgiebig getestet, aber egal ob es funktioniert oder nicht,
letzteres sieht krank aus. Im Gegensatz zur eleganten Lösung von Gast.
RalphFFM
 2008-04-20 14:20
#108571 #108571
User since
2006-11-16
258 Artikel
BenutzerIn
[Homepage] [default_avatar]
Wieso moniert Perl mir einen Syntaxfehler an wenn ich dann noch ein "my" vor
@hash{qw/vorname nachname plz ort haustier foobar/} = @_;
schreibe? Also:
my @hash{qw/vorname nachname plz ort haustier foobar/} = @_;

Wenn ich dagegen den Hash vorher separat mittels
my %hash = ();
deklariere, ist für strict und warnings wieder alles in Butter.
KurtZ
 2008-04-20 14:36
#108573 #108573
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
Vermutlich weil Hashslices die Parserregeln für my hier überfordern, schließlich schreibst du ein @ vor hash und der compiler muss an den Klammern {} erkennen dass es sich um ein hash handelt.

M.a.W. Perl hat hier Verbesserungspotential.
TMTOWTDYOG (there's more than one way to dig your own grave)
renee
 2008-04-20 15:13
#108574 #108574
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
KurtZ+2008-04-20 12:36:21--
M.a.W. Perl hat hier Verbesserungspotential.


Ich finde es eigentlich ganz ok, dass das nicht erlaubt ist. Sonst verstehen Einsteiger erst recht nicht mehr das "Durcheinander" der Sigils... Dann muss noch mehr auf Kontext geachtet werden, was nicht unbedingt zur Lesbarkeit beiträgt...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
KurtZ
 2008-04-20 16:00
#108576 #108576
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
renee+2008-04-20 13:13:10--
Ich finde es eigentlich ganz ok, dass das nicht erlaubt ist. Sonst verstehen Einsteiger erst recht nicht mehr das "Durcheinander" der Sigils... Dann muss noch mehr auf Kontext geachtet werden, was nicht unbedingt zur Lesbarkeit beiträgt...


naja... also ich persönlich ziehe konsequente Orthogonalität vor, je "mathematischer" ein System wird umso besser kann es skalieren, wachsen.

Zum einen sind Hashslices wirklich kein Anfängerfeature, zum anderen haben Sigils ja eine klar definierte Bedeutung, nämlich was hinten rauskommt. Das dieses "Durcheinander" in Perl6 [*] umgemodelt wird, ist IMHO kein Argument in Perl5 durch Ausnahmen den Nicht-Anfänger auszubremsen. Also wenn schon Autovivication dann konsequent !!! PS: [*] irgendwo hab ich gelesen dass das Hauptargument für Perl6 sei, dass sich kaum noch Progger fänden, die sich im verwirrenden Perl5-Parser einarbeiten können, um ihn zu erweitern. Das dürfte auch erklären warum my hier scheitert, die ganzen DWIM-Ausnahmeregelungen sabotieren scheints die Wartbarkeit.
TMTOWTDYOG (there's more than one way to dig your own grave)
KurtZ
 2008-04-20 16:06
#108577 #108577
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
RalphFFM+2008-04-20 10:16:43--
%myhash = ('vorname' => $_[0], 'nachname' => $_[1], 'plz' => $_[2], 'ort' => $_[3], 'haustier' => $_[4], 'foobar' => $_[5]);


Ralph, du weißt aber auch dass du alternativ auch direkt benannte Argumente an ein Sub übergeben könntest? Das steigert oft die Lesbarkeit!


Code (perl): (dl )
1
2
3
4
5
6
7
8
callSub(
   vorname => "tri",  
   nachname => "tra", 
   plz         => "trul",  
   ort           => "la",  
   haustier => "la",  
   foobar      => "!",
)



Linke Hashslices brauche ich eigentlich (fast) nur wenn ich Tabellen auslese...
TMTOWTDYOG (there's more than one way to dig your own grave)
sid burn
 2008-04-20 16:11
#108578 #108578
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Anstatt die einzelnen Werte zu übergeben und dann in einem Hash zu verpacken kannst du auch gleich den Nutzer ein Hash übergeben lasssen.

Das hat ganz einfach den Vorteil das der User sich nicht mehr die Reihenfolge mercken muss. Und erweiterungen für dich werden auch einfacher. Da du nicht immer einfach alles hinten dran hängen musst. Du könntest dein Beispiel also auch folgendermaßen umschreiben.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
# So sieht deine Subroutine aus
sub function {
my ( %args ) = @_;
print $args{vorname};
print $args{nachname};
...
}

# das schreibt dein benutzer deiner Subroutine
function( vorname => 'david', nachname => 'raab' );


Ein weiterer Vorteil, du kannst auch Defaultwerte selber angeben. und die Reihenfolge ist immer noch egal. Beispielsweise hat nicht jeder Nutzer ein Haustier. Er müsste also für den 5ten Wert ei dir ein "undef" übergeben, sofern er den 6ten Wert noch ausfüllen möchte. Mit einem Hash ist ja reihenfolge volkommen egal.

Code: (dl )
1
2
3
4
5
6
7
8
9
sub function {
my ( %args ) = @_;
%args = (
haustiere => [],
%args,
);
}

function( name => 'david', vorname => 'raab' );


Hier setzt du dann default für haustiere eine Array Referenz. Gibt ein Benutzer haustiere an. dann wird der Default überschrieben im nachhinein wieder überschrieben.

Ansonsten ist es noch besser wenn du eine Hashreferrenz übergibst anstatt die Werte so.

Code: (dl )
1
2
3
4
5
6
7
8
sub function {
my ( $arg_href ) = @_;

print $arg_href->{vorname};
...
}

function({ vorname => 'david', nachname => 'raab' });


Der Vorteil hierdrin liegt wenn du beim aufruf schon eine ungerade Anzahl angibst. Beispielsweise folgender Fehler.

Code: (dl )
function( vorname => 'david', haustiere => 'hund', 'katze' )


Dann bricht dein Code mit einer Fehlermeldung ab, da du hier eine ungerade Anzahl für ein Hash hast. Allerdiengs verweist die Fehlermeldung innerhalb der Subroutine nämlich bekommst du ein Fehler in der sub function() ausgegeben. Naja und das Interessiert dich ja wenig. Du willst ja wissen wo du die Fehlerhaften angaben gemacht hast. Wenn du eine Hashreferenz übergibst. Dann muss die Hashreferenz schon korrekt sein. Würde sie nicht korrekt sein. dann würde schon eie Fehlermeldung erscheinen die darauf verweist wo du die hashreferenz zusammen baust.

Ansderer Punkt ist das du flexibler bist. Beispielsweise könntest du auch einen zweiten Parameter angeben. Der dann z.B. bestimmte Optionen regelt. Oder irgendetwas anderes was nicht direkt Personen Daten sind.

Was hierbei noch sehr nett ist ist das Modul Params::Check was ab Perl 5.10 auch zum Core Modul gehört. Damit kannst du testen ob alles korrekt eingegeben wurde.


Ich finde nur die Default Optionen nicht so gut. Aber die kannst du ja neu setzen. Ich setze die Optionen immer so das automatisch ein croak() geworfen wird, und wenn ein unbekannter Name auftauscht auch automatisch dabgebrochen wird. Somit werden auch rechtschreibfehler erkannt. Wenn ein benutzer ausversehen mal "nmae" anstatt "name" eintippt. Oder sonst irgendein name angegeben wird, der überhaupt nicht existiert. Evtl. weil du selber vergessen hast das ganze zu Implementieren. Oder weil ein nutzer beispielsweise die Doku nicht liest und "username" als Parameter eingibt, obwohl das Argument "user" heißt. ;) etc. pp.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
RalphFFM
 2008-04-20 16:42
#108581 #108581
User since
2006-11-16
258 Artikel
BenutzerIn
[Homepage] [default_avatar]
KurtZ+2008-04-20 14:06:36--
Ralph, du weißt aber auch dass du alternativ auch direkt benannte Argumente an ein Sub übergeben könntest? Das steigert oft die Lesbarkeit!
Code (perl): (dl )
1
2
3
4
5
6
7
8
callSub(
   vorname => "tri",  
   nachname => "tra", 
   plz         => "trul",  
   ort           => "la",  
   haustier => "la",  
   foobar      => "!",
)
Diese Situation ist mir noch nicht begegnet, nein, das hatte ich mir bislang noch nicht überlegt. Jedenfalls gut zu wissen, daß das geht!

Ich möchte an dieser Stelle eigentlich keine Sub aufrufen, sondern ich möchte den Hash dann anschließend mittels
$template->param(%hash);
HTML::Template übergeben, um die Variablen zu füllen.

Bin grad fleißig am schreiben und sehen, inwieweit es dann alles so funktioniert.
<< |< 1 2 >| >> 15 Einträge, 2 Seiten



View all threads created 2008-04-20 12:16.