Kontext scalar oder array
hotti
- perl
Moin,
gegeben ist ein hash
%names = (
'name' => ['Lottermann'],
'vname' => ['Erwin', 'Horst'],
);
und der liegt als Referenz $ref vor. In der Ausgabe muss ich wissen, was ich erwarte, also ein Scalar oder ein Array:
# erwarte mehrere Werte
printf "%s, %s\n", ($$ref{'vname'}->[0]) ? @{$$ref{'vname'}} : qw(0 0);
# erwarte nur einen Wert
printf "%s\n", $$ref{'name'}->[0];
Muss daher die Ausgabe ein bischen präparieren, damit Perl nicht meckert. Die Frage ist, ob das evntl. ein bischen kleiner geht, so z.B.:
@Vornamen = ...;
$Name = ...;
Geht das mit o.g. hash oder brauch ich da eine etwas andere Datenstruktur?
Hotti
Muss es unbedingt ein sprintf-Ausdruck sein?
say join q(, ), @{ $_ } for values %names;
__END__
Lottermann
Erwin, Horst
Muss es unbedingt ein sprintf-Ausdruck sein?
egal, wantarray ist mein (neuer) Freund ;-)
Danke und viele Grüße,
Lottermann
Hallo Lottermann
Du hast hier mehr als nur ein Hash es ist ein Hash of Arrays und ein Array kannste immer printen auch wenn es 1 elementig ist.
Wenn deine Frage ist wie du jetzt dieses einem Scalar zuweisen kannst ohne wg des Contexts die Länge des Arrays zu bekommen würde ich Stringification des Arrays durch Interpolation empfehlen:
$name="@{$ref->{name}}";
(natürlich macht cpan mit join implizit das gleiche, aber es ging ja um kurz und knackig ... :)
egal, wantarray ist mein (neuer) Freund ;-)
mgmngh .... hat nur bedingt mit wantarray zu tun weil keine Funktion aufgerufen wird.
Grüße
Erwin Lindemann
hi,
mgmngh .... hat nur bedingt mit wantarray zu tun weil keine Funktion aufgerufen wird.
Die hab ich mittlerweile. wantarray ist echt der Hammer, kein Wunder, dass es in vielen Modulen zu finden ist ;-)
Also meine Lösung ist die, dass ich jetzt 2 Funktionen habe, eine Funktion erstellt den hash und gibt eine Ref darauf. Die 2. Funktion ist diejenige, die im Kontext von wantarray steht:
sub pram{
my $key = shift;
$pramref = parseAll() if not defined $pramref;
if($key){
if(wantarray){ return @{$$pramref{$key}}; }
else{ return $$pramref{$key}->[0]; }
}
else{
return(keys %{$pramref});
}
}
pram('name') liefert mir so einen Namen, pram('vname') hingegen liefert mir bei Bedarf ein Array der Vornamen, falls es mehrere gibt. Die Funktion parseAll() ist eine abgespeckte Version für CGI::param(), ich kann also, wenn ich meine pram() mehrmals aufrufe, den hash dazu im Vorab erstellen, muss also nicht jedesmal den Parser laufen lassen. Falls der Parser nicht vorgeladen wurde, wird er mit pram() angezogen. Mein Parser macht ein bischen mehr als CGI.pm, ich hab auch http-request-header zu parsen, das macht mein parser gleich mit ;-)
Viele Grüße,
Horst Hackfleisch
Mein Parser macht ein bischen mehr als CGI.pm, ich hab auch http-request-header zu parsen, das macht mein parser gleich mit ;-)
und die Funktion param() im CGI Modul nicht? Was macht denn die Funktion sonst?
Struppi.
Mein Parser macht ein bischen mehr als CGI.pm, ich hab auch http-request-header zu parsen, das macht mein parser gleich mit ;-)
und die Funktion param() im CGI Modul nicht?
Doch, kann CGI::param() auch, habs grad gesehen, danke für Deinen Hinweis Struppi. Aber egal, ich hab jetzt meinen eigenen Parser(*) und nachdem ich use CGI; aus einigen Scripts gestrichen habe, rocken die jetzt richtig los: Es ist so, als würden Engel schieben ;-)
(*) unter Verzicht auf multipart/form-data
Was natürlich nicht heißt, dass ich CGI.pm nun überhaupt nicht mehr verwende. Wenn es sein muss, kann ich CGI.pm selbstverständlich jederzeit in mein Framework (was für ein Wort!) einbinden. Lieber bissl schlanker programmieren und dafür etwas fetter essen.
Viele Grüße,
Horst Hackethal