Aufruf von subroutinen

Aufruf von subroutinen

am 09.04.2006 22:22:56 von Mehmet Soysal

Hallo,
ich versuche Perl Subroutinen, anhand von eingaben aufzurufen.
Jedoch habe ich nicht herausgefunden wie ich es anstellen soll.


also
my $eingabe =
#eingabe zum Beispiel "get_fish"
#jetzt soll die entsprechende Subroutine "get_fish" aufgerufen werden
&($eingabe)();

das obere funktioniert so nicht, aber kann mir jemand nen TIP geben was
ich da übersehen habe, oder wie man sowas realisieren kann.



MfG
M.SOYSAL

Re: Aufruf von subroutinen

am 09.04.2006 22:45:16 von Slaven Rezic

Mehmet Soysal writes:

> Hallo,
> ich versuche Perl Subroutinen, anhand von eingaben aufzurufen.
> Jedoch habe ich nicht herausgefunden wie ich es anstellen soll.
>
>
> also
> my $eingabe =
> #eingabe zum Beispiel "get_fish"
> #jetzt soll die entsprechende Subroutine "get_fish" aufgerufen werden
> &($eingabe)();
>
> das obere funktioniert so nicht, aber kann mir jemand nen TIP geben was
> ich da übersehen habe, oder wie man sowas realisieren kann.
>

Du musst für $eingabe in geschweiften statt runden Klammern schreiben.
Falls du "use strict" benutzt, muss man zusätzlich "no strict 'refs'"
verwenden.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de
babybike - routeplanner for cyclists in Berlin
handheld (e.g. Compaq iPAQ with Linux) version of bbbike
http://bbbike.sourceforge.net

Re: Aufruf von subroutinen

am 09.04.2006 22:53:49 von Mirco Wahab

Hallo Mehmet

> ich versuche Perl Subroutinen, anhand von eingaben aufzurufen.
> Jedoch habe ich nicht herausgefunden wie ich es anstellen soll.

Slaven hat Dir schon einige Tipps
gegeben, Du kannst auch 'eval'
benutzen, um 'Tippfehler' gezielt
zu behandeln, z.B.:

sub get_fish{ print "in sub get_fish\n"; }
# ...
my $eingabe = <>;
eval ($eingabe) or warn "$!";

oder in der Art ..

Viele Grüße

M.

Re: Aufruf von subroutinen

am 09.04.2006 23:31:37 von Wolf Behrenhoff

Mehmet Soysal schrieb:
> Hallo,
> ich versuche Perl Subroutinen, anhand von eingaben aufzurufen.
> Jedoch habe ich nicht herausgefunden wie ich es anstellen soll.

Es ist fast immer eine schlechte Idee, subs auf diese Art aufzurufen.
'perldoc -q "variable name"' erklärt dir, warum es eine schlechte Idee
ist, auf diese Art eine Variable anzusprechen. Das ist dann genauso auf
subs übertragbar.

Wolf

Re: Aufruf von subroutinen

am 10.04.2006 00:12:38 von Ch Lamprecht

Mehmet Soysal schrieb:
> Hallo,
> ich versuche Perl Subroutinen, anhand von eingaben aufzurufen.
> Jedoch habe ich nicht herausgefunden wie ich es anstellen soll.
>
>
Hallo,
mit einem hash der Codereferenzen enthält geht das z.B.so:
(An Stelle der anonymen Subs können natürlich auch Referenzen auf deine
benannten Subroutinen stehen)

use warnings;
use strict;
my %subs ;
for my $val(1..5){
$subs{"sub$val"}= sub{print "sub$val was called\n";}
}
while (<>){
chomp;
$subs{$_}->() if ref $subs{$_}eq 'CODE';
}


Christoph
--

perl -e "print scalar reverse q/ed.enilno@ergn.l.hc/"

Re: Aufruf von subroutinen

am 10.04.2006 09:14:48 von Frank Seitz

Slaven Rezic wrote:
> Mehmet Soysal writes:
>>
>>ich versuche Perl Subroutinen, anhand von eingaben aufzurufen.
>>Jedoch habe ich nicht herausgefunden wie ich es anstellen soll.
>>
>>also
>>my $eingabe =
>>#eingabe zum Beispiel "get_fish"
>>#jetzt soll die entsprechende Subroutine "get_fish" aufgerufen werden
>>&($eingabe)();
>
> Du musst für $eingabe in geschweiften statt runden Klammern schreiben.
> Falls du "use strict" benutzt, muss man zusätzlich "no strict 'refs'"
> verwenden.

Wobei die geschweiften Klammern auch weggelassen werden können.

Noch eine Möglichkeit: Die Subroutines in ein
Package verlegen und als Methoden aufrufen.
In dem Fall ist kein "no strict 'refs'" erforderlich.

X->$eingabe();

package X;

sub get_fish { my $class = shift; ... }

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Aufruf von subroutinen

am 10.04.2006 09:19:52 von Frank Seitz

Wolf Behrenhoff wrote:
> Mehmet Soysal schrieb:
>>
>>ich versuche Perl Subroutinen, anhand von eingaben aufzurufen.
>>Jedoch habe ich nicht herausgefunden wie ich es anstellen soll.
>
> Es ist fast immer eine schlechte Idee, subs auf diese Art aufzurufen.
> 'perldoc -q "variable name"' erklärt dir, warum es eine schlechte Idee
> ist, auf diese Art eine Variable anzusprechen. Das ist dann genauso auf
> subs übertragbar.

Dem würde ich keinesfalls zustimmen.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Aufruf von subroutinen

am 10.04.2006 10:19:57 von Mirco Wahab

Hallo Frank
> Slaven Rezic wrote:
>> Mehmet Soysal writes:
>>> ich versuche Perl Subroutinen, anhand von eingaben aufzurufen.
>>> Jedoch habe ich nicht herausgefunden wie ich es anstellen soll.
>
> [Use The Package]

Das ist erstaunlich einfach und überzeugend :))

Geht eigentlich auch statt Deinem:

#!/usr/bin/perl -w
use strict;

package X;
sub get_fish { my $class=shift; print shift," : $class : get_fish\n";}

chomp(my $eingabe = <>);
X->$eingabe ('klappt');


das Ganze ebenfalls in 'indirect object syntax'?
Also sowas wie:
...
$eingabe X ('klappt');

oder
...
$eingabe X 'klappt';


(wie muss man $eingabe quoten?).

Viele Grüße

M.

Re: Aufruf von subroutinen

am 10.04.2006 10:41:40 von Frank Seitz

Mirco Wahab wrote:

> das Ganze ebenfalls in 'indirect object syntax'?
> Also sowas wie:
> ...
> $eingabe X ('klappt');
>
> oder
> ...
> $eingabe X 'klappt';
>
>
> (wie muss man $eingabe quoten?).

Dazu kann ich nichts sagen. Ich benutze die
'indirect object syntax' nicht, da ich die nicht mag.
Dem Augenschein nach sieht es mir nicht so aus,
als ob es damit möglich ist.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Aufruf von subroutinen

am 10.04.2006 11:17:30 von Wolf Behrenhoff

Frank Seitz schrieb:
> Wolf Behrenhoff wrote:
>> Mehmet Soysal schrieb:
>>> ich versuche Perl Subroutinen, anhand von eingaben aufzurufen.
>>> Jedoch habe ich nicht herausgefunden wie ich es anstellen soll.
>> Es ist fast immer eine schlechte Idee, subs auf diese Art aufzurufen.
>> 'perldoc -q "variable name"' erklärt dir, warum es eine schlechte Idee
>> ist, auf diese Art eine Variable anzusprechen. Das ist dann genauso auf
>> subs übertragbar.
>
> Dem würde ich keinesfalls zustimmen.

Warum nicht?
Generell oder weil die Erklärung nicht genau zutrifft?

Angenommen, ich habe ein Programm, das eine sub "setDefaultPassword"
hat, die das Passwort für was auch immer zurücksetzt. Nun verlange ich
in einer Usereingabe die Entscheidung, ob sub "A" oder sub "B"
aufgerufen werden soll. Danach rufe ich die eingegebene sub auf. Wenn
der User nun statt A oder B aber setDefaultPassword eingibt, habe ich
vermutlich ein Sicherheitsproblem.

Daher ist es IMHO ein besserer Weg, wie in dem perldoc-Artikel
beschrieben, zum Beispiel einen Hash zu nehmen.

Zum Beispiel so (C steht hier für eine sub, die der User nicht aufrufen
kann):

sub A{print"ich bin A\n"}
sub B{print"ich bin B\n"}
sub C{print"ich bin C\n"}
%exe = ( A => \&A,
B => \&B);
while(chomp($in=)){ $exe{$in}->() }

Hier bekommst du einen Fehler (die sub "&main::" gibt es nicht), wenn du
etwas ungültiges eingibst, es wird aber nie eine andere sub (etwa C)
ausgeführt werden können, die nicht in %exe drin steht. (dennoch sollte
man das natürlich auch hier überprüfen)

Wolf

Re: Aufruf von subroutinen

am 10.04.2006 12:28:58 von Frank Seitz

Wolf Behrenhoff wrote:
> Frank Seitz schrieb:
>>>
>>>Es ist fast immer eine schlechte Idee, subs auf diese Art aufzurufen.
>>>'perldoc -q "variable name"' erklärt dir, warum es eine schlechte Idee
>>>ist, auf diese Art eine Variable anzusprechen. Das ist dann genauso auf
>>>subs übertragbar.
>>
>>Dem würde ich keinesfalls zustimmen.
>
> Warum nicht?
> Generell oder weil die Erklärung nicht genau zutrifft?

Generell, da ich es als sehr nützlich und sinnvoll erachte,
Subroutines über ihren Namen, der als Zeichenkette vorliegt,
ansprechen zu können.

Anwendungsbeispiel: Gegeben irgendwelche Objekte mit irgendwelchen
Eigenschaften, die durch Methoden abgefragt werden können.
Die Objekte sollen gemäß einer oder mehrerer ihrer
Eigenschaften sortiert werden. Hierfür soll eine
allgemeine Funktion/Methode realisiert werden, die
die Liste der Eigenschaften als Parameter empfängt.

> Angenommen, ich habe ein Programm, das eine sub "setDefaultPassword"
> hat, die das Passwort für was auch immer zurücksetzt. Nun verlange ich
> in einer Usereingabe die Entscheidung, ob sub "A" oder sub "B"
> aufgerufen werden soll. Danach rufe ich die eingegebene sub auf. Wenn
> der User nun statt A oder B aber setDefaultPassword eingibt, habe ich
> vermutlich ein Sicherheitsproblem.
>
> Daher ist es IMHO ein besserer Weg, wie in dem perldoc-Artikel
> beschrieben, zum Beispiel einen Hash zu nehmen.
>
> Zum Beispiel so (C steht hier für eine sub, die der User nicht aufrufen
> kann):
>
> sub A{print"ich bin A\n"}
> sub B{print"ich bin B\n"}
> sub C{print"ich bin C\n"}
> %exe = ( A => \&A,
> B => \&B);
> while(chomp($in=)){ $exe{$in}->() }
>
> Hier bekommst du einen Fehler (die sub "&main::" gibt es nicht), wenn du
> etwas ungültiges eingibst, es wird aber nie eine andere sub (etwa C)
> ausgeführt werden können, die nicht in %exe drin steht. (dennoch sollte
> man das natürlich auch hier überprüfen)

Dort, wo eine Benutzereingabe erfolgt, gehört IMO
sowieso ein Gültigkeitstest hin. Wenn der bestanden ist,
kann der Aufruf genausogut über

X->$eingabe();

bzw. in Deinem Beispiel

main->$in();

erfolgen.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel