Wertzuweisung $a=$b="xxx"
Gernot
- perl
0 Horst0 Patrick Andrieu0 Gernot0 Patrick Andrieu0 Don P0 Patrick Andrieu
0 Horst
0 Gernot
Hallo,
sind in Perl Wertzuweisungen der Art
$a = $b = "xxx";
zulässig,
wobei dann sowohl $a als auch $b den Wert "xxx" erhalten?
Nett wäre es, wenn Ihr mir auch eine Doku angeben könntet, wo dies
ggf. steht, vielleicht gibt es ja dort weitere "Tricks" für mich.
Gruss
Gernot
Hallo,
sind in Perl Wertzuweisungen der Art
$a = $b = "xxx";
zulässig,
nein, das geht in c aber in Perl geht das schief. Btw.: $a und $b sind Variablen, die Perl selbst benutzt, Finger weg ;)
Tutorial: Google mal nach Eike Grote.
Viele Grüße,
Hotte
Hallo Horst!
nein, das geht in c aber in Perl geht das schief.
Warum? Beipsiel? Abgesehen von dem berechtigen Einwand mit den »Sondervariablen« $a und $b...
$foo = $bar = "buzz";
Viele Grüße aus Frankfurt/Main,
Patrick
Hallo,
Warum? Beipsiel? Abgesehen von dem berechtigen Einwand mit den »Sondervariablen« $a und $b...
Wusste nicht, dass die Sonderbedeutung haben!
$foo = $bar = "buzz";
So geht es also!
Weiss jemand, wo das beschrieben ist?
Danke Gernot
Hallo Gernot!
Weiss jemand, wo das beschrieben ist?
Ich hab's in perldoc perlop nicht gefunden (so viel Englisch bereitet mir Kofpschmerzen *g*). Wenn _Du_ aber gut in Englisch bist, kannst Du es Dir gerne 'reinziehen ;)
Viele Grüße aus Frankfurt/Main,
Patrick
Hallo,
Weiss jemand, wo das beschrieben ist?
Z.B. in:
Larry Wall, Tom Christiansen & Jon Orwant: Programmieren mit Perl, Deutsche Übersetzung von Peter Klicman, O'Reilly & Associates Inc., 2.Auflage 2001 (ISBN 3-89721-144-0), Seite 26, insbesondere Anmerkung 19 dort.
Gruß, Don P
Hallo,
Larry Wall, Tom Christiansen & Jon Orwant: Programmieren mit Perl, Deutsche Übersetzung von Peter Klicman, O'Reilly & Associates Inc., 2.Auflage 2001 (ISBN 3-89721-144-0), Seite 26, insbesondere Anmerkung 19 dort.
Danke, allerdings hatte ich gedacht, dass es auch irgendwo im Netz stehen würde, das Buch werde ich mir deswegen wohl nicht kaufen!
Gruss
Gernot
Hallo,
Danke, allerdings hatte ich gedacht, dass es auch irgendwo im Netz stehen würde, das Buch werde ich mir deswegen wohl nicht kaufen!
Im Internet? Es steht doch in diesem Thread schon mehrfach. Ist dir das nicht genug? Glaubst du uns etwa nicht? An der von mir genannten Stelle steht, dass Zuweisungen einen Wert zurückliefern, und dass bei mehreren Zuweisungen der Art $x = $y = $z = $value immer der rechte Wert ($value) durchgereicht wird.
Gruß, Don P
Hallo,
bitte lese meine Beiträge genauer. Ich habe die Aussage nicht angezweifelt, ich zitiere mich
"Nett wäre es, wenn Ihr mir auch eine Doku angeben könntet, wo dies
ggf. steht, vielleicht gibt es ja dort weitere "Tricks" für mich."
Betonung auf: weitere "Tricks".
Gruss
Gernot
Hi,
Betonung auf: weitere "Tricks".
Abt. "weitere Tricks": diese Syntax ist auch in JS zulässig. :-)
Gruß, Cybaer
Hallo,
bitte lese meine Beiträge genauer. Ich habe die Aussage nicht angezweifelt, ich zitiere mich
"Nett wäre es, wenn Ihr mir auch eine Doku angeben könntet, wo dies
ggf. steht, vielleicht gibt es ja dort weitere "Tricks" für mich."Betonung auf: weitere "Tricks".
Ok, das steht ganz oben. Ich habe zuletzt gelesen:
$foo = $bar = "buzz";
So geht es also!
Weiss jemand, wo das beschrieben ist?
und erinnerte mich nur, dass du schon vorher danach gefragt hattest.
Das Buch von Larry Wall & Co. gilt als das Beste Perl-Buch (Wall hat Perl immerhin "erfunden"). Mir persönlich ist es etwas zu prosaisch, aber etwas besseres ist mir auch noch nicht begegnet. Perl ist ja nicht gerade eine triviale Sprache. Wenn du die lieber in irgendwelchen selbstgebasteten Tutorials im Internet lernen willst, na dann viel Spaß...
Gruß, Don P
Hallo Gernot!
Warum? Beipsiel? Abgesehen von dem berechtigen Einwand mit den »Sondervariablen« $a und $b...
Wusste nicht, dass die Sonderbedeutung haben!
Ja und nein. Sicher kannst Du sie mit Werte belegen, solltest Du aber nicht machen. Denn diese Variablen, die man, nebenbei bemerkt, nicht mit my deklarieren muss, werden für Zahlenvergleiche, Zahlenoperationen und auch Stringvergleiche verwendet ( $a <=> $b, $a cmp $b).
Ach, und »Programmieren mit Perl« solltest Du dennoch kaufen (oder von der Oma, Freundin, wem auch immer schenken lassen).
Viele Grüße aus Frankfurt/Main,
Patrick
Hallo Patrick,
nein, das geht in c aber in Perl geht das schief.
Warum? Beipsiel? Abgesehen von dem berechtigen Einwand mit den »Sondervariablen« $a und $b...
$foo = $bar = "buzz";
Tschuldigung, ich hab Käse erzählt, klaro geht das auch in Perl
$x = $y = 'aldrin';
print "$x $y\n"; # aldrin aldrin
Viele Grüße an Alle,
Hotte
Hallo,
eigentlich ein anderes Thema aber ich will den Vorwurf des "Doppelposting" vermeiden.
Ich rufe eine Subroutine auf mit subr(%hashtab, $par).
In der Subroutine habe ich
my (%tab, $p) = @_;
Ergebnis:
Die Hash-Tabelle ist in Ordnung, $p ist leer (obwohl $par einen Wert besitzt).
Vermutlich liegt es an
my (%tab, $p) = @_;
aber warum?
Gruss
Gernot
Vermutlich liegt es an
my (%tab, $p) = @_;
aber warum?
Weil %tab hier alle Parameter bekommt, du solltest vermutlich auch eine Warnung bekommen (oder hast du etwa die Warnungen nicht eingeschaltet?)
Wenn du mehrere Listen als Parameter übergeben willst, musst du diese als Referenz übergeben, was sowieso besser ist, da so keine Kopien erstellt werden müssen.
http://perldoc.perl.org/perlref.html
Struppi.
Hallo Struppi,
Wenn du mehrere Listen als Parameter übergeben willst, musst du diese als Referenz übergeben, was sowieso besser ist, da so keine Kopien erstellt werden müssen.
ich möchte aber Kopien, die ich in der Subroutine verändere (ohne dass die Werte im rufenden Programm verändert werden).
Das geht dann wohl nicht?
Gruss
Gernot
Moin Moin!
Wenn du mehrere Listen als Parameter übergeben willst, musst du diese als Referenz übergeben, was sowieso besser ist, da so keine Kopien erstellt werden müssen.
ich möchte aber Kopien, die ich in der Subroutine verändere (ohne dass die Werte im rufenden Programm verändert werden).
Das geht dann wohl nicht?
Nicht mit der Aufrufreihenfolge. Vielleicht möchtest Du mit Prototypen tricksen (sub blafasel(\%$) { ... }
), um die Aufrufe unverändert zu lassen und trotzdem eine Referenz auf den Hash zu bekommen. Die müßtest Du dann aber selbst kopieren (my %hash=%$hashparamreference
).
Alexander
Hallo,
Nicht mit der Aufrufreihenfolge. Vielleicht möchtest Du mit Prototypen tricksen (
sub blafasel(\%$) { ... }
), um die Aufrufe unverändert zu lassen und trotzdem eine Referenz auf den Hash zu bekommen. Die müßtest Du dann aber selbst kopieren (my %hash=%$hashparamreference
).
Oh, Schmerz lass nach!
Tricksen möchte ich lieber nicht.
Vielleicht hat noch jemand eine göttliche Eingebung.
Die Aufrufreihenfolge könnte ich ändern.
Gruss
Gernot
Hi,
Die Aufrufreihenfolge könnte ich ändern.
Wenn du erst die Variable und dann den Hash übergibst sollte es klappen.
Das Problem ist, dass eine Listen eine beliebige Länge haben kann und darum alle folgenden Parameter ebenfalls in die Liste geschrieben werden.
mfG,
steckl
Hallo,
Wenn du erst die Variable und dann den Hash übergibst sollte es klappen.
Das Problem ist, dass eine Listen eine beliebige Länge haben kann und darum alle folgenden Parameter ebenfalls in die Liste geschrieben werden.
Ja, so klappt es, aber schön unlogisch - oder?
Gruss
Gernot
Ja, so klappt es, aber schön unlogisch - oder?
Was ist daran unlogisch?
Struppi.
i sag nur "Kommunikativgesetz" - mehr sag i net!
In anderen Worten:
Ich gebe meinem Kind einen Korb mit Birnen und eine Apfel ist das gleiche wie wenn ich ihm einen Apfel und eine Korb mit Birnen gebe.
Gruss
Gernot
Ich gebe meinem Kind einen Korb mit Birnen und eine Apfel ist das gleiche wie wenn ich ihm einen Apfel und eine Korb mit Birnen gebe.
So ist es aber in dem Fall nicht.
Du hälst einem Kind zwei Äpfel hin und wunderst dich das es beide nimmt und beschwerst dich das dein anderes Kind heult, weil es nichts bekommt.
Struppi.
Hallo,
Ich gebe meinem Kind einen Korb mit Birnen und eine Apfel ist das gleiche wie wenn ich ihm einen Apfel und eine Korb mit Birnen gebe.
So ist es aber in dem Fall nicht.
Du hälst einem Kind zwei Äpfel hin und wunderst dich das es beide nimmt und beschwerst dich das dein anderes Kind heult, weil es nichts bekommt.
So ist es aber in dem Fall nicht.
Ich kenne keine Programmiersprache - ausser jetzt Perl - wo die Reihenfolge der Parameter beim Funktions-/Unterroutinenaufruf eine derart gravierende Bedeutung hat.
Gruss
Gernot
Du hälst einem Kind zwei Äpfel hin und wunderst dich das es beide nimmt und beschwerst dich das dein anderes Kind heult, weil es nichts bekommt.
So ist es aber in dem Fall nicht.
Doch exakt so ist es in diesem Fall.
Ich kenne keine Programmiersprache - ausser jetzt Perl - wo die Reihenfolge der Parameter beim Funktions-/Unterroutinenaufruf eine derart gravierende Bedeutung hat.
Die Reihenfolge der Parameter hat in deinem Fall keine Bedeutung, nur die Art der Parameter.
Diese Art der Parameterübergabe ist flexibel und leicht durchschaubar. In anderen Sprachen musst du dich oft festlegen welche Art und wieviele Parameter du übergeben willst, in Perl kannst du einer Funktion immer beliebige Parameter übergeben, diese werden an ein Spezialarray (@_) übergeben.
Deine Schwierigkeit ist vermutlich, dass dir nicht klar ist, dass ein Hash ein Array ist und du deshalb nicht erkennst, dass ein Array als Parameter eben nicht ein Wert ist sondern jeder Eintrag ist ein Parameter, deshalb ist es sinnvoll ein Hash als Referenz zu übergeben oder den von Alexander gezeigten Weg mit Protyping.
Struppi.
Du hälst einem Kind zwei Äpfel hin und wunderst dich das es beide nimmt und beschwerst dich das dein anderes Kind heult, weil es nichts bekommt.
Ich wiederhole: So ist es aber in dem Fall nicht.
Ich halte in meinem Beispiel Äpfel und Birnen nicht zwei Kindern hin sondern nur einem!
Die Reihenfolge der Parameter hat in deinem Fall keine Bedeutung, nur die Art der Parameter.
Auch das ist nachgewiesenerweise Quatsch. Wenn man in meinem Beispiel erst den Skalar und dann die hash-Tabelle angibt, funktioniert es (wie auch in einem anderen Beitrag in diesem Thread erwähnt)
Diese Art der Parameterübergabe ist flexibel und leicht durchschaubar.
Flexibel ja, aber wie man sieht, leider auf Kosten der Logik und Transparenz!
In anderen Sprachen musst du dich oft festlegen welche Art und wieviele Parameter du übergeben willst, in Perl kannst du einer Funktion immer beliebige Parameter übergeben, diese werden an ein Spezialarray (@_) übergeben.
Sorry, vernünftige Sprachen erkennen die Art der Parameter, und damit ist die Übergabe für sie kein Problem.
Deine Schwierigkeit ist vermutlich, dass dir nicht klar ist, dass ein Hash ein Array ist ....
Deine Schwierigkeit ist vermutlich, dass für Dich Perl ein und alles ist, Du nicht über Perl hinaussehen kannst, formale Logik für Dich ein Fremdwort ist und Du schließlich, wie andere kontroverse Diskussionen zeigen, immer Recht haben willst.
Sei's drum - alles was ich oben schrieb, nehme ich zurück.
Ich habe fertig
Gernot
Du hälst einem Kind zwei Äpfel hin und wunderst dich das es beide nimmt und beschwerst dich das dein anderes Kind heult, weil es nichts bekommt.
Ich wiederhole: So ist es aber in dem Fall nicht.
Du kannst es so oft wiederholen wie du willst, es bleibt falsch.
Ich halte in meinem Beispiel Äpfel und Birnen nicht zwei Kindern hin sondern nur einem!
my (%tab, $p) = @_;
ich sehe hier _zwei_ Variabeln und das erste ist ein Array.
Die Reihenfolge der Parameter hat in deinem Fall keine Bedeutung, nur die Art der Parameter.
Auch das ist nachgewiesenerweise Quatsch. Wenn man in meinem Beispiel erst den Skalar und dann die hash-Tabelle angibt, funktioniert es (wie auch in einem anderen Beitrag in diesem Thread erwähnt)
Ja, weil du mit dem letzten Parameter das spezial Array @_ komplett aufsaugst, dass es funktioniert liegt nur daran weil du unbedingt ein Array als Parameter übergeben willst und das ist, wie ich dir schon mehrfach gesagt habe nicht sinnvoll.
Diese Art der Parameterübergabe ist flexibel und leicht durchschaubar.
Flexibel ja, aber wie man sieht, leider auf Kosten der Logik und Transparenz!
In anderen Sprachen musst du dich oft festlegen welche Art und wieviele Parameter du übergeben willst, in Perl kannst du einer Funktion immer beliebige Parameter übergeben, diese werden an ein Spezialarray (@_) übergeben.
Sorry, vernünftige Sprachen erkennen die Art der Parameter, und damit ist die Übergabe für sie kein Problem.
Ja, dafür fehlt in die bei Perl vorhandene flexibilität, ob das vernüftig ist oder nicht, kann ich nicht beurteilen. Ich persönlich habe damit keine Probleme und wenn man es verstanden hat (und verstehen will) ist es auch logisch und vernünftig.
Deine Schwierigkeit ist vermutlich, dass dir nicht klar ist, dass ein Hash ein Array ist ....
Deine Schwierigkeit ist vermutlich, dass für Dich Perl ein und alles ist, Du nicht über Perl hinaussehen kannst, formale Logik für Dich ein Fremdwort ist und Du schließlich, wie andere kontroverse Diskussionen zeigen, immer Recht haben willst.
Falls es dir nicht aufgefallen ist.
_Du_ dikutierst ohne Sachverstand und magst nicht die Erkenntnisse die wir hier dir vermitteln wollten aufnehmen. Die formale Logik ist durchaus vorhanden und wurde dir bereits mehrfach versucht nahe zu bringen, es scheint aber nicht zu klappen.
Tut mir leid das wir es versuchen wollen, aber jemand der dermaßen Stur und und auf seine Ansichten beharrt ist nicht zu helfen. Ich werde gerne in Zukunft darauf verzichten mir deine Probleme anzuschauen.
Struppi.
Du hast Recht - basta
Du hast Recht - basta
Ich weiß, Danke.
Struppi.
你好 Gernot,
Die Reihenfolge der Parameter hat in deinem Fall keine Bedeutung, nur die Art der Parameter.
Auch das ist nachgewiesenerweise Quatsch. Wenn man in meinem Beispiel erst den Skalar und dann die hash-Tabelle angibt, funktioniert es (wie auch in einem anderen Beitrag in diesem Thread erwähnt)
Klar funktioniert das. Gewusst wie:
use strict;
sub x {
my $var = pop;
my %hash = @_;
print "var: ", $var, " hash: ", join ", " => keys %hash;
}
my %hash = (a => 'b', c => 'd');
my $var = 'abc';
x(%hash,$var);
Diese Art der Parameterübergabe ist flexibel und leicht durchschaubar.
Flexibel ja, aber wie man sieht, leider auf Kosten der Logik und Transparenz!
In jedem vernünftigen Perlbuch steht, wie Parameter-Übergabe funktioniert. Sie ist vollständig transparent und logisch. Ob sie schön ist, ist eine andere Frage (ich persönlich finde es eine beschissene Lösung), aber transparent und logisch ist es.
再见,
克里斯蒂安
Moin Moin!
Deine Schwierigkeit ist vermutlich, dass dir nicht klar ist, dass ein Hash ein Array ist und du deshalb nicht erkennst, dass ein Array als Parameter eben nicht ein Wert ist sondern jeder Eintrag ist ein Parameter, deshalb ist es sinnvoll ein Hash als Referenz zu übergeben oder den von Alexander gezeigten Weg mit Protyping.
Argl! Hashes und Array sind zwei völlig verschiedene Sachen. Bei jedem Funktionsaufruf werden alle Parameter der Reihe nach in eine temporäre Liste gepackt, die innerhalb der Funktion dann im Array(!) @_ zur Verfügung steht. Dabei werden (wenn keine Prototypen im Spiel sind) Arrays und Hashes zu einer (Teil-)Liste "geplättet". Diese enthält im Array-Fall alle Array-Elemente in der Reihenfolge des aufsteigenden Indexes. Im Hash-Fall enthält sie abwechselnd Schlüssel und Wert, die Reihenfolge der Paare ist aber explizit *NICHT* garantiert.
Das Gemeine an Perl und insbesondere der Dokumentation ist, dass Listen und Arrays zwei *UNTERSCHIEDLICHE* Sachen sind, obwohl sie oft austauschbar sind und in aller Regel automatisch ineinander konvertiert werden. Um die Verwirrung komplett zu machen, gibt es eine Builtin-Funktion wantarray, die anzeigt, ob eine Funktion im LISTEN-Kontext aufgerufen wurde oder nicht. Das kann eine Zuweisung an ein Array sein (@a=foo(...);), aber auch eine Zuweisung an ein Hash (%h=foo(...);) oder aber eine echte Liste (foreach (foo(...))).
Alexander
Argl! Hashes und Array sind zwei völlig verschiedene Sachen.
Naja, ich hätte vielleicht schreiben, sollen für das Verständnis der Parameterübergabe, sind ein Hash und ein Array relativ gleich. Das die Reihenfolge der Einträge unterschiedlich ist spielt ja hier erstmal keine Rolle. Aber hat sowieso alles nichts genützt.
Struppi.
Hallo Gernot!
Ergänzend zu Struppis Posting...
Hättest Du Dir die Warnungen ausgeben lassen, wäre das, was Dir Struppi eben geantwortet hat, vielleicht vorher klar gewesen. Nehmen wir also Dein Beispiel:
C:\>perl -w
# ^^ Gibt Warnungen aus.
use strict;
my %hashtab = ( 1 => "Sponge Bob",
2 => "Patrick Star");
my $par = "Meerjungfraumann";
print "HASHTAB: ", %hashtab;
print $/;
subr(%hashtab, $par);
sub subr {
my (%tab, $p) = @_;
print "HASH: ", %tab;
print $/, "PAR: $p";
}
Ausgabe:
---------------------------------------------------------
HASHTAB: 1Sponge Bob2Patrick Star
Odd number of elements in hash assignment at - line 15.
Use of uninitialized value in print at - line 16.
Use of uninitialized value in concatenation (.) or string at - line 17.
HASH: 1Sponge BobMeerjungfraumann2Patrick Star
PAR:
---------------------------------------------------------
»Odd number of elements in hash assignment at - line 14.«... aha!
Übergibst Du stattdessen eine Referenz:
C:\>perl -w
use strict;
my %hashtab = ( 1 => "Sponge Bob",
2 => "Patrick Star");
my $par = "Meerjungfraumann";
$, = $/;
print "HASHTAB: ", %hashtab;
print $/;
subr(\%hashtab, $par);
sub subr {
my $tab = shift;
my $p = shift;
my %tab = %$tab;
$, = $/;
print "HASH: ", %tab;
print $/, "PAR: $p";
}
Ausgabe:
---------------------------------------------------------
HASHTAB:
1
Sponge Bob
2
Patrick Star
HASH:
1
Sponge Bob
2
Patrick Star
PAR: Meerjungfraumann
---------------------------------------------------------
Viele Grüße aus Frankfurt/Main,
Patrick
Hallo,
Hättest Du Dir die Warnungen ausgeben lassen, wäre das, was Dir Struppi eben geantwortet hat, vielleicht vorher klar gewesen. Nehmen wir also Dein Beispiel:
ich habe keine Warnungen erhalten, da ich im UP nicht das hash drucke, sondern gezielt die einzelnen Element aus dem Hash lese und weiterverarbeite.
Gruss
Gernot
Hättest Du Dir die Warnungen ausgeben lassen,
Das habe ich ihm bereits gestern gesagt.
ich habe keine Warnungen erhalten, da ich im UP nicht das hash drucke, sondern gezielt die einzelnen Element aus dem Hash lese und weiterverarbeite.
Und wie immer, ein falscher Kommentar ohne Sachverstand.
Struppi.
Hättest Du Dir die Warnungen ausgeben lassen,
Das habe ich ihm bereits gestern gesagt.
ich habe keine Warnungen erhalten, da ich im UP nicht das hash drucke, sondern gezielt die einzelnen Element aus dem Hash lese und weiterverarbeite.
Und wie immer, ein falscher Kommentar ohne Sachverstand.
Struppi.
Du hast Recht - basta!
i sag nur "Kommunikativgesetz" - mehr sag i net!
Soag moal, woas hat Perl jetzt mit Kölner Bushoaltestellen zu tun???
(du als Bayer kommst aber weit herum *fg*)
(Tatsächlich findet Google 60 Treffer für "Kommunikativgesetz", u.a. bei einem Pädagogikportal!)
Ich gebe meinem Kind einen Korb mit Birnen und eine Apfel ist das gleiche wie wenn ich ihm einen Apfel und eine Korb mit Birnen gebe.
Aha Kommutativgesetzt...
Perl Subroutinen kennen in der Übergabe nur Skalare, deine Birnen werden also in Äpfel umgemodelt. (genauer gesagt dein Apfelkorb wird in Einzeläpfel zerlegt) Deswegen gibts keine Kommutierung, höchstens eine Assoziierung.
Der Syntax
($wert1,$wert2)=@arr3;
ist auch ein allgemeiner und nicht auf Parameterübergaben beschränkt. Das Specialfeature dieses Syntax ist:
Arrays in der Klammerliste sind gierig, d.h. der Apfelkorb wird bis zur Hardwaregrenze abgefüllt ( d.h. ist ein Fass ohne Boden), wer in der Liste dahinter kommt geht IMMER leer aus.
Das hat einen schönen Seiteneffekt, Routinen mit unbekannter Anzahl von Restparametern, können einfach behandelt werden
($para1, $para2, @rest, $immer_undef)=@_;
Also immer dran denken Perl übergibt nur *Skalare* (i.d.R [1]). Übergibst du Strukturen werden sie aufgelöst (flattening) und du musst die Elemente wieder richtig zuornen. Deswegen in komplizierten Fällen lieber eine Referenz auf die Struktur übergeben, weil Refs selbst spezielle Skalare sind.
Was die andere Frage anbelangt:
$w=$x=$y="zzz";
meine ich keinen speziellen Syntax zu erkennen, sondern das Abfangen von Rückgabewerten.
D.h. das du $x das Ergebnis aus $y="zzz" zuweist. Die Zuweisung "=" ist nicht void sondern returniert den Zuweisungswert, deswegen wird "zzz" an $x weitergereicht, usw, usf. Da ganz links nichts mehr steht wird der Rückgabewert dann ignoriert.
Alles klar?
Kurt
[1] du kannst natürlich auch mit Prototypen arbeiten, aber die machen den Code später schwerer lesbar, deswegen rät Damian Conway hier zu recht zu sparsamen Einsatz!
Kleiner Nachtrag
[1] du kannst natürlich auch mit Prototypen arbeiten, aber die machen den Code später schwerer lesbar, deswegen rät Damian Conway hier zu recht zu sparsamen Einsatz!
benannte Parameter wären meistens auch eine bessere Option wenn du viele unterschiedliche Argumente übergibst.
Hi,
Das Problem ist, dass eine Listen eine beliebige Länge haben kann und darum alle folgenden Parameter ebenfalls in die Liste geschrieben werden.
Ja, so klappt es, aber schön unlogisch - oder?
Eigentltich nicht.
Woher soll der Interpreter wissen wie viele Elemente eine Liste (in deinem Fall der Hash) haben soll? Also packt er einfach alle Werte die nach dem "=" kommen in die Liste.
Du kannst es so sehen, dass du die Subroutine immer mit einer einzigen Liste als Parameter aufrufst.
($x,$y,$z) ist ja auch nur eine Liste mit 3 Werten.
Sie werden dann in der Unterfunktion alle in der Liste @_ gespeichert.
mfG,
steckl
Tricksen möchte ich lieber nicht.
Vielleicht hat noch jemand eine göttliche Eingebung.
Du kannst auch direkt (wie ich dir bereits sagte) den Hash als Referenz übergeben und dann in der Funktion in einen Hash umwandeln.
Struppi.
Ich rufe eine Subroutine auf mit subr(%hashtab, $par).
In der Subroutine habe ichmy (%tab, $p) = @_;
So und jetzt nochmal eine etwas ausführlichere Erklärung, damit man auch sieht das Norbert hier falsche Sachen erzählt hat.
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my %hash = ( k1 => 'wert1', k2 => 'wert2');
my $skalar = 'parameter';
sub test_prototype (\% $);
test(%hash, $skalar);
test(\%hash, $skalar);
test_prototype(%hash, $skalar);
sub test{
warn "\ncall: test(@_) =" .(scalar @_) ." Parameter\n";
my(%lokal, $leer) = @_;
print '%lokal=', Dumper \%lokal;
print '$leer=', Dumper $leer;
}
sub test_prototype (\% $){
warn "\ncall: test_prototype(@_) =" .(scalar @_) ." Parameter\n";
my($lokal, $leer) = @_;
my %lokal = %$lokal;
print '%lokal=', Dumper \%lokal;
print '$leer=', Dumper $leer;
}
Das Skript zeigt, wie Perl die Parameter übergibt, wie man diese annehmen kann und das Perl durchaus eine Warnungen ausgibt, wenn man diese falsch zuweist. Auch habe ich die von Alexander erwähnte Lösung in der Funktion test_protoptye eingebaut. Die Ausgabe sieht so aus:
call: test(k2 wert2 k1 wert1 parameter) =5 Parameter
Odd number of elements in hash assignment at t.pl line 15.
%lokal=$VAR1 = {
'parameter' => undef,
'k2' => 'wert2',
'k1' => 'wert1'
};
$leer=$VAR1 = undef;
call: test(HASH(0x225b34) parameter) =2 Parameter
%lokal=$VAR1 = {
'HASH(0x225b34)' => 'parameter'
};
$leer=$VAR1 = undef;
call: test_prototype(HASH(0x225b34) parameter) =2 Parameter
%lokal=$VAR1 = {
'k2' => 'wert2',
'k1' => 'wert1'
};
$leer=$VAR1 = 'parameter';
Die Hash-Tabelle ist in Ordnung, $p ist leer (obwohl $par einen Wert besitzt).
Wenn das wirklich so ist und die Warnungen eingeschaltet ist muss die Warnung ausgegeben worden sein:
Odd number of elements in hash assignment at t.pl line 15.
Der Grund dafür ist, das ein Hash im Prinzip nichts weiter als ein Array ist und folglich wird eine Zuweisung in der Form:
%hash = (@array, $skalar, %hash);
Alle auf der rechten Seite vorhandenen Werte dem auf der linken Seite stehenden Hash zuweisen.
Wenn jetzt auf beiden Seiten eine Liste steht:
(%hash, $skalar, $nocheinskalar) = ( ...);
Wird der Hash links, trotzdem alle Werte in der rechten Liste aufnehmen. Das ist kein Verhalten das man abstellen kann sondern ein Feature in Perl, dass durchaus logisch und nützlich ist (ausser wenn man es nicht verstehen will).
Wenn man weiß und versteht das es so ist, dann wird man schnell auf den Trichter kommen, dass es fast immer sinnvoller ist, wenn man irgendeine Form eines Array hat, dieses als Referenz an eine Funktion zu übergeben, was nicht nur das Parameterhandling vereinfacht sondern darüber hinaus auch Speicher spart und schneller ist. Möchte man eine lokale Kopie muss dies halt explizit gesagt werden.
Struppi.