hash mit funktionen
am 08.09.2006 10:58:54 von Hirgumir
Hi, ich habe da eine Idee, funktioniert aber nicht.
Es währe toll, wenn ich einen Hash dafür verwenden könnte Funktionen
zu starten.
Wenn ich also Beispielsweise Werte zwichen 1 bis 255 habe aufgrund
dessen ich verschiedene subs starten muß, währe es doch prima, wenn
ich nur schreiben könnte:
$funktionsNummer =3D 2; # ein Wert aus den 1..255.
$result =3D $hash{$funktionsNummer};
Das Problem liegt in darin, dass die Funktion in diesem Moment gar
nicht ausgeführt wird, sondern nur bei der Definition des Hashes:
my %hash =3D (
1 =3D> &lese_dreissig_zeichen(7),
2 =3D> &hallo(49),
3 =3D> &lese_dreissig_zeichen(128));
Die Funktioen werden alle einml ausgeführt und das wars. Starten kann
man die Funktionen dann nicht mehr über den Hash.
Gibt es ähnliche Methoden oder kann man das besser machen ohne Switch,
IfElsif ... etc zu verwenden.
Re: hash mit funktionen
am 08.09.2006 11:16:47 von Christian Kirsch
Hirgumir schrieb:
> Hi, ich habe da eine Idee, funktioniert aber nicht.
>
> Es währe toll, wenn ich einen Hash dafür verwenden könnte Funktionen
> zu starten.
> Wenn ich also Beispielsweise Werte zwichen 1 bis 255 habe aufgrund
> dessen ich verschiedene subs starten muß, währe es doch prima, wenn
> ich nur schreiben könnte:
>
> $funktionsNummer = 2; # ein Wert aus den 1..255.
> $result = $hash{$funktionsNummer};
>
> Das Problem liegt in darin, dass die Funktion in diesem Moment gar
> nicht ausgeführt wird, sondern nur bei der Definition des Hashes:
>
> my %hash = (
> 1 => &lese_dreissig_zeichen(7),
> 2 => &hallo(49),
> 3 => &lese_dreissig_zeichen(128));
>
> Die Funktioen werden alle einml ausgeführt und das wars. Starten kann
> man die Funktionen dann nicht mehr über den Hash.
>
>
Klar - Du rufst sie ja auch auf.
Du könntest z.B. eine Referenz auf eine anonyme Subroutine benutzen:
my %hash = (
1 => sub { lies_dreissig_zeichen(7); },
2 => sub { hallo(49) },
3 => sub { lies_dreissig_zeichen(128);});
und später so aufrufen
&$hash{1}
Das Perl-Buch enthält sicherlich dazu was, außerdem könnte der
Abschnitt über Closures dort für Dich interessant sein.
Re: hash mit funktionen
am 08.09.2006 11:30:40 von Hirgumir
Hallo Christian,
ich bin begeistert. Es funktioniert. Ich habs verstanden.
Vielen Dank
Übrigens, für Mitlesende: Der Aufruf muß in Klammern gesetzt werden,
da es sonst nicht richtig interpretiert wird.
&{$hash{1}}
Gruß
Hirgumir
Christian Kirsch schrieb:
> Hirgumir schrieb:
> > Hi, ich habe da eine Idee, funktioniert aber nicht.
> >
> > Es währe toll, wenn ich einen Hash dafür verwenden könnte Funktio=
nen
> > zu starten.
> > Wenn ich also Beispielsweise Werte zwichen 1 bis 255 habe aufgrund
> > dessen ich verschiedene subs starten muß, währe es doch prima, wenn
> > ich nur schreiben könnte:
> >
> > $funktionsNummer =3D 2; # ein Wert aus den 1..255.
> > $result =3D $hash{$funktionsNummer};
> >
> > Das Problem liegt in darin, dass die Funktion in diesem Moment gar
> > nicht ausgeführt wird, sondern nur bei der Definition des Hashes:
> >
> > my %hash =3D (
> > 1 =3D> &lese_dreissig_zeichen(7),
> > 2 =3D> &hallo(49),
> > 3 =3D> &lese_dreissig_zeichen(128));
> >
> > Die Funktioen werden alle einml ausgeführt und das wars. Starten kann
> > man die Funktionen dann nicht mehr über den Hash.
> >
> >
>
> Klar - Du rufst sie ja auch auf.
> Du könntest z.B. eine Referenz auf eine anonyme Subroutine benutzen:
>
> my %hash =3D (
> 1 =3D> sub { lies_dreissig_zeichen(7); },
> 2 =3D> sub { hallo(49) },
> 3 =3D> sub { lies_dreissig_zeichen(128);});
>
> und später so aufrufen
> &$hash{1}
>
> Das Perl-Buch enthält sicherlich dazu was, außerdem könnte der
> Abschnitt über Closures dort für Dich interessant sein.
Re: hash mit funktionen
am 08.09.2006 11:44:43 von Christian Winter
Hirgumir schrieb:
> Hi, ich habe da eine Idee, funktioniert aber nicht.
>
> Es währe toll, wenn ich einen Hash dafür verwenden könnte Funktionen
> zu starten.
> Wenn ich also Beispielsweise Werte zwichen 1 bis 255 habe aufgrund
> dessen ich verschiedene subs starten muß, währe es doch prima, wenn
> ich nur schreiben könnte:
>
> $funktionsNummer = 2; # ein Wert aus den 1..255.
> $result = $hash{$funktionsNummer};
>
> Das Problem liegt in darin, dass die Funktion in diesem Moment gar
> nicht ausgeführt wird, sondern nur bei der Definition des Hashes:
>
> my %hash = (
> 1 => &lese_dreissig_zeichen(7),
> 2 => &hallo(49),
> 3 => &lese_dreissig_zeichen(128));
Grundsätzlich bist Du mit Deiner Idee nicht so weit ab vom Schuss,
allerdings hast Du 3 Fehler drin:
1. um eine Referenz auf eine sub zu setzen, musst du das Perl auch so
sagen, also:
1 => \&lese_dreissig_zeichen,
2. ein Coderef kann nicht mit Paramtern gesetzt werden, du musst also
entweder die Parameter erst beim tatsächlichen Aufruf übergeben, oder
den Aufruf selbst in einer anonymen sub kapseln.
Entweder:
1 => \&lese_dreissig_zeichen,
$result = $hash{1}->(7);
Oder
1 => sub { lese_dreissig_zeichen(7) },
3. Damit Perl weiss, dass Du eine Codereferenz aufrufen willst und nicht
nur einen Skalar oder eine Referenz auslesen, musst du das in der
Notation angeben:
$result = $hash{$funktionsNummer}->();
Du könntest, wenn Du wirklich durchgehend für jede Zahl eine sub
definierst, auch ein Array als Storage nehmen:
my @handlers = (
sub {;}, # index 0
sub { lese_dreissig_zeichen(7); },
sub { hallo(49); },
# ...
);
$result = $handlers[$funkionsNummer]->();
Als Lektüre empfehle ich "perldoc perlref" und "perldoc perlreftut".
HTH
-Christian
Re: hash mit funktionen
am 08.09.2006 11:47:48 von Klaus
> > Hirgumir schrieb:
> > > Es währe toll, wenn ich einen Hash dafür verwenden könnte Funkt=
ionen
> > > zu starten.
> Christian Kirsch schrieb:
> > Du könntest z.B. eine Referenz auf eine anonyme Subroutine benutzen:
> >
> > my %hash =3D (
> > 1 =3D> sub { lies_dreissig_zeichen(7); },
> > 2 =3D> sub { hallo(49) },
> > 3 =3D> sub { lies_dreissig_zeichen(128);});
> >
> > und später so aufrufen
> > &$hash{1}
> >
> > Das Perl-Buch enthält sicherlich dazu was, außerdem könnte der
> > Abschnitt über Closures dort für Dich interessant sein.
Hirgumir wrote:
> Übrigens, für Mitlesende: Der Aufruf muß in Klammern gesetzt werden,
> da es sonst nicht richtig interpretiert wird.
> &{$hash{1}}
Absolut korrekt, siehe dazu auch das Beispiel in "perldoc perlref",
paragraph "Using References":
&{ $dispatch{$index} }(1,2,3); # call correct routine
Re: hash mit funktionen
am 08.09.2006 12:03:46 von Christian Lackas
* Hirgumir [2006-09-08]:
Hallo Hirgumir,
> Übrigens, für Mitlesende: Der Aufruf muß in Klammern gesetzt werden,
> da es sonst nicht richtig interpretiert wird.
> &{$hash{1}}
ich finde ja folgende Notation deutlich lesbarer:
$hash{1}->();
Gruß
Christian
--
With no more than six levels of misquotation, any statement can be made to say
whatever you wish. (John McCarthy, 2002)
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker
Re: hash mit funktionen
am 08.09.2006 12:39:12 von Hirgumir
Hallo Ihr Christians
Ich muß sagen, dass mir die Variante von Christian Winter am besten
gefällt, weil ich dort keine Probleme mit use strict bekomme. Die
erste funktionierende Variante führte zur Fehlermeldung:
Bareword "funktion" not allowed while "strict subs" in use at ...
Das habe ich erst gemerkt als ich anschließend use strict
hingeschriben habe.
Christian Lackas schrieb:
> * Hirgumir [2006-09-08]:
>
> Hallo Hirgumir,
>
> > Übrigens, für Mitlesende: Der Aufruf muß in Klammern gesetzt werd=
en,
> > da es sonst nicht richtig interpretiert wird.
> > &{$hash{1}}
>
> ich finde ja folgende Notation deutlich lesbarer:
>
> $hash{1}->();
>
> Gruß
> Christian
>
> --
> With no more than six levels of misquotation, any statement can be made t=
o say
> whatever you wish. (John McCarthy, 2002)
> http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker
Re: hash mit funktionen
am 08.09.2006 13:59:41 von Mirko Westermeier
Hirgumir schrieb:
[Zitat repariert, bitte nicht pop-toasten]
>>> &{$hash{1}}
>>
>> ich finde ja folgende Notation deutlich lesbarer:
>>
>> $hash{1}->();
>
> Ich muß sagen, dass mir die Variante von Christian Winter am besten
> gefällt, weil ich dort keine Probleme mit use strict bekomme. Die
> erste funktionierende Variante führte zur Fehlermeldung:
> Bareword "funktion" not allowed while "strict subs" in use at ...
Das hat aber mit $hash{1}->(); sicher nichts zu tun. Ich kann da auch
kein Bareword "funktion" entdecken.
$ perl -Mstrict -wle 'my %h; $h{1} = sub { print 42 }; $h{1}->()'
42
Ybrinx: wenn Du die Notation nicht magst, kannst Du Deine dispatch table
auch in einen ge'tie'ten Hash wegkapseln, der die Funktionen bei FETCH
automagisch aufruft.
Dann hättest Du tatsächlich nur noch, was Du anfangs wolltest:
$result = $hash{$funktionsNummer};
Wäre zwar wohl Overkill, aber wenn Du's mal anders machen willst... ;-)
perldoc perltie (Das geht auch mit Arrays, wenn Du tatsächlich nur
Nummern hast)
Mit freundlichem Gruß
Mirko 'Columbus' Westermeier
--
Entschäumungsbeauftragter und Wurstrechtvertreter zu detebe
E-Mail: , OpenPGP-Key-ID: 0x730E195D
Key fingerprint: 55A8 9646 9B58 60AC B5BC 9661 FDD4 93C0 730E 195D
E-Mails von mir sind signiert. Unsignierte E-Mails sind nicht von mir.
Re: hash mit funktionen
am 09.09.2006 11:19:04 von Christian Lackas
* Hirgumir [2006-09-08]:
Hallo Hirgumir,
> Ich muß sagen, dass mir die Variante von Christian Winter am besten
> gefällt, weil ich dort keine Probleme mit use strict bekomme.
beide unsere Varianten
&{$hash{1}} und $hash{1}->()
sind völlig äquivalent, die Verwendung von '&' bei Funktionen ist
allerdings mehr Perl 4-Style. In beiden Fällen bekommst du keine
Probleme mit 'use strict' (wenn du es denn richtig machst).
> Die erste funktionierende Variante führte zur Fehlermeldung: Bareword
> "funktion" not allowed while "strict subs" in use at ...
Es ist für uns jetzt leider nicht nachvollziehbar was bei dir die 'erste
funktionierende Variante' war oder wo das Wort 'funktion' vorkommt (in
unseren Beispiel jedenfalls nicht).
Gruß
Christian
--
Murphys Law 1: Die Wahrscheinlichkeit des Geschehens steht im umgekehrten
Verhältnis zum Wunsch.
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker