Lude: Funktion ausfuehren, deren Namen nur als Skalar bekannt

Hi,

ich moechte in Abhaengigkeit des Wertes eines Skalars eine Funktion ausfuehren lassen. Primitive Ansaetze, wie

&($in{WhatToDo});
 &$in{WhatToDo};

funzten net.

Wie geht es richtig? (Hoffentlich geht's mit dem griffigen Perl, in anderen Sprachen geht's ja oft nicht.)

Gruss,
Lude

  1. Servus,

    ich glaube mich daran zu erinnern, dass Du den umweg über exec()machen musst.
    Da ich kein Perl Buch zur Hand habe kann ich dir leider nicht sonderlich weiter helfen, nur soviel:
    Gehen tut es.

    Gruss Matze

  2. use Mosche;

    ich moechte in Abhaengigkeit des Wertes eines Skalars eine Funktion ausfuehren lassen.

    eval $scalar; funktioniert bei mir..

    Wenn du die entsprechende Funktion nur so (also "indirekt") aufrufst, empfehle ich dir aber was anderes:

    my %subs;
    $subs{'meine_sub'} = sub {
        print "test";
    }; # Semikolon nicht vergessen

    Aufruf:

    my $str = 'meine_sub';
    $subs{$str}(); # oder auch: $subs{$str}->(); # Parameter wie gewohnt in () übergeben

    Dass müsste prinzipiell auch schneller sein. Auf jeden Fall halte ich diese Lösung für "sauberer", weil man leichter die Existenz der ensprechenden Funktion überprüfen kann (defined $subs{'meine_sub'} ? ...). Weiterhin kann man dir nicht so leicht fremden Code rüberschieben:

    my $str = "rm -rf /"; eval $str; # Vorsicht: Code nicht ausprobieren :-)

    use Tschoe qw(Matti);

    --
      Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
    1. ich moechte in Abhaengigkeit des Wertes eines Skalars eine Funktion ausfuehren lassen.

      eval $scalar; funktioniert bei mir..

      ist abe rnicht nötig.

      Wenn du die entsprechende Funktion nur so (also "indirekt") aufrufst, empfehle ich dir aber was anderes:

      my %subs;
      $subs{'meine_sub'} = sub {
          print "test";
      }; # Semikolon nicht vergessen

      Das ist aber umständlicher als die Funktion ganz normal zu definieren und der Kontrollstruktur nur die Namen der Funktionen mitzugeben.

      Ich benutze z.b. sowas:

      ausgelagert in einer Datei Action.pm
      my @action = (
      {
      name => 'bla',
      function => 'func',
      modul => 'datei'
      },
      {
      name => 'bla',
      function => 'func',
      modul => 'datei'
      }
      );

      und der aufruf mit dem Parameter Action:

      my $action = $action[param('action')];

      require $action->{modul} if(exists $action->{modul} && -e  $action->{modul}) ;
      &{$action->{function}}() if(exists $action->{function} && defined $action->{function}) ;

      Dadurch kann ich alles in einer Datei kontrollieren (es sind noch mehr informationen in @action drin, z.b. wie das Menü dargestellt wird)

      Struppi.

      1. use Mosche;

        eval $scalar; funktioniert bei mir..

        ist abe rnicht nötig.

        Wie gesagt, dass halte ich auch nicht für sehr sauber...

        Das ist aber umständlicher als die Funktion ganz normal zu definieren und der Kontrollstruktur nur die Namen der Funktionen mitzugeben.

        Das verstehe ich nicht ganz. Könntest du das bitte nochmal erläutern. Schaue dir mal bitte den Quelltextwust in [pref:t=70607&m=406316] an.

        Deine Lösung (aus [pref:t=70607&m=406329]) hat den Makel, dass du explizit 'refs' auf no-Strict-Modus schaltest. Solche Warnungen haben meistens ihre Gründe...

        Ich benutze z.b. sowas: [...]

        Naja, du benutzt im Grunde nichts anderes. Im Abhängigkeit eines Strings wird eine passende Datei geladen. Ich persönlich (IMHO) benutze kein require, da dann zur Laufzeit irgendwas nachgeladen werden muss, und ich will möglichst vermeiden, irgendwelche Probleme zur Laufzeit zu bekommen.

        use kannst du nicht verwenden (außer in BEGIN), und ein "berechnetes" use macht in den wenigsten Fällen Sinn. Was bei deiner Version relativ schwer fällt:

        Stell dir vor, jede einzelne Funktion du redest wahrscheinlich über Programme im CGI-Kontext, also nenne ich das ganze ab hier Maske) hängt von anderen ab. Solange du nicht entsprechende Zugriffsbeschränkungen zentral ablegst (was deine dezentralen Module (=Masken) ad absurdum führt), musst du diese Zugriffsbeschränkungen dezentral durchführen. (Zugriffsbeschränkungen kann zB auch sein, dass verlangt wird, eine zweite Maske vor einer dritten aufzurufen. Parameter können ja auch gefälscht sein).

        Wenn du diese Beschränkungen dezentral durchführst, dann musst du einen ganzen Haufen von Logik darein investieren, nur weil unterschiedliche Masken sich nicht unbedingt gegenseitig _kennen_. Vielleicht ist nicht alles gleich verständlich, frag dann einfach mal nach. Vielleicht habe ich deinen Ansatz aber auch falsch verstanden.

        Was passiert also: um das ganze zu dezentralisieren, benötigst du einen ganzen Haufen von Logik, die du dann doch irgendwie zentral halten musst.

        Außerdem (auch wenn man solche Fehler abfangen kann, wie du es tust), ist der Zugriff auf das Dateisystem durch Parameter prinzipiell eine Sicherheitslücke. Ohne gut zu wissen, was man tut und was passieren kann, würde ich niemandem eine solche Methode empfehlen.

        Ich habe seit einiger Zeit ein relativ langes Script (~40 Kb) mit meiner Methode am laufen.

        use Tschoe qw(Matti);

        --
          Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
        1. eval $scalar; funktioniert bei mir..

          ist abe rnicht nötig.

          Wie gesagt, dass halte ich auch nicht für sehr sauber...

          stimmt hatte ich überlesen ;-)

          Das ist aber umständlicher als die Funktion ganz normal zu definieren und der Kontrollstruktur nur die Namen der Funktionen mitzugeben.

          Das verstehe ich nicht ganz. Könntest du das bitte nochmal erläutern. Schaue dir mal bitte den Quelltextwust in [pref:t=70607&m=406316] an.

          Naja, er müßte in halt immer schreiben:

          $hash->{funktiosname} = sub () { .... };

          und könnte diese dann auch nicht mehr in verschiedenen Dateien unterbringen.

          in Bezug auf das Orginal:

          if ($in{WhatToDo} eq 'BenutzerQuery') {&BenutzerQuery;}
          ...
          usw.
          ...
          if ($in{WhatToDo} eq 'Update') {&Update;}

          wird zu:

          if(defined &{$in{WhatToDo}) &{$in{WhatToDo}()

          Deine Lösung (aus [pref:t=70607&m=406329]) hat den Makel, dass du explizit 'refs' auf no-Strict-Modus schaltest. Solche Warnungen haben meistens ihre Gründe...

          sicher, aber wenn man weiss warum die Warnung kommt und das man das wirklich will ist no strict das Mittel der Wahl und mit Sicherheit eben deshalb auch vorgesehen.

          Ich benutze z.b. sowas: [...]

          Naja, du benutzt im Grunde nichts anderes. Im Abhängigkeit eines Strings wird eine passende Datei geladen. Ich persönlich (IMHO) benutze kein require, da dann zur Laufzeit irgendwas nachgeladen werden muss, und ich will möglichst vermeiden, irgendwelche Probleme zur Laufzeit zu bekommen.

          Was sollen denn da für Probleme auftauchen?
          Letztlich schmeisst Perl ganz normal die Fehler oder überseh ich da was?
          Für mich sah es so aus als ob ich mit meiner Methode leichter eine komplexe CGI Anwendung erweitern kann.

          Stell dir vor, jede einzelne Funktion du redest wahrscheinlich über Programme im CGI-Kontext, also nenne ich das ganze ab hier Maske) hängt von anderen ab. Solange du nicht entsprechende Zugriffsbeschränkungen zentral ablegst (was deine dezentralen Module (=Masken) ad absurdum führt), musst du diese Zugriffsbeschränkungen dezentral durchführen. (Zugriffsbeschränkungen kann zB auch sein, dass verlangt wird, eine zweite Maske vor einer dritten aufzurufen. Parameter können ja auch gefälscht sein).

          So ganz kapieren tu ich das nicht wo du das Problem siehst.
          Ja ich red von CGI Programmen. In meiner Kontrollstruktur sind auch die Zugriffsbeschränkungen eingebaut.

          Also in etwa so:

          my @action = (
          {
          name => 'bla',
          func => 'func',
          modul => 'datei',
          user => 1
          },
          {
          name => 'bla',
          func => 'func',
          modul => 'datei',
          user => 0
          }
          );

          (Daneben gibt es noch 'menu' um die funktion im Menü anzuzeigen, 'text' als Erläuterungstext)

          Was passiert also: um das ganze zu dezentralisieren, benötigst du einen ganzen Haufen von Logik, die du dann doch irgendwie zentral halten musst.

          So sieht's aus, aber ein Haufen finde ich das nicht. Es ist letztlich eine Funktion mit wenig Zeilen die in dem Modul main (per use eingebunden) zu finden ist:

          sub getAction
          {
          my $action = shift || return '';
          my $modul = shift;

          return 'keine Action' unless $action;

          if(defined $action->{func})
          {
          my $func = $action->{f};
          no strict 'refs';
          if( defined &{$func} )
          {
          return CGI::h1("Zugriff nicht erlaubt!! ($func)")
          if !$user->checkFunc($func);

          return &{$func}();
          }
          else
          {
          return "Funktion: $func () existiert nicht in $modul.". start($modul);
          }
          }
          return start($modul); # ist in jeder pl Datei vorhanden
          }

          Ich seh grad, ich habe mittlerweile das mit dem require geändert, da ich den Schlüssel 'modul' in's Menü einbaue, da steht dann in etwa sowas:

          <a href="$action->{modul}.pl">$action->{text}</A>

          Das wird dann auch dynamisch aufgebaut je nach Zugriffsrechte.

          Außerdem (auch wenn man solche Fehler abfangen kann, wie du es tust), ist der Zugriff auf das Dateisystem durch Parameter prinzipiell eine Sicherheitslücke. Ohne gut zu wissen, was man tut und was passieren kann, würde ich niemandem eine solche Methode empfehlen.

          Naja, die Parameter sind ja nicht direkt dynamisch, ich benutze in diesem Fall nur Parameter die von mir definiert sind.

          Ich habe seit einiger Zeit ein relativ langes Script (~40 Kb) mit meiner Methode am laufen.

          ich kann dir nicht wirklich sagen wieviel KB in Gebrauch sind aber ich hab 45 pm/pl Dateien mit ca. 350KB. Durch die Module finde ich halbwegs schnell die Funktionen falls mal was geändert werden muss und kann relativ schnell zusätzliche Funktionen einbauen, auch wenn sie komplexer sind.

          Falls es dich interessiert das ganze Ding läuft hier http://die-bunte-liga.de/cgi-bin/action.pl und bietet für die Mitglieder noch ein Haufen mehr Funktionen, je nach Zugriffsberechtigung.

          Wenn du irgendwelche schlimmen Lücken siehst, würd ich mich über Tipps freuen.

          Struppi.

          1. use Mosche;

            Naja, er müßte in halt immer schreiben:

            $hash->{funktiosname} = sub () { .... };

            und könnte diese dann auch nicht mehr in verschiedenen Dateien unterbringen.

            OK, wenn man das so sieht. Die 15 Zeichen mehr habe ich auch überlebt :-)

            [...] ich will möglichst vermeiden, irgendwelche Probleme zur Laufzeit zu bekommen.

            Was sollen denn da für Probleme auftauchen?
            Letztlich schmeisst Perl ganz normal die Fehler oder überseh ich da was?

            Naja, wenn ich darauf achte, dass mein Perl-Script möglichst wenig Input bekommt, den es nicht kontrollieren kann, kann ich überhaupt vermeiden, dass Fehler während der Laufzeit auftreten. Ich finde immer, dass Laufzeitfehler am schlimmsten zu finden sind, und deswegen schreibe ich meine Scripte so, dass möglichst alles in einer kontrollierten Umgebung abläuft.

            Bsp (zugegeben einfach):
            Du hast ein Perl-Script, dass zur Laufzeit irgendwelche Dinge nachlädt (womöglich noch dynamisch). Wenn das nicht klappt, hast du gleich mehrere Fehlerquellen. Lädt es hingegen "konstante" Module, dann hast du eine potentielle Fehlerquelle ausgeschlossen. Die Performance ist hierbei nicht mehr wirklich entscheidend: Wenn du darauf wirklich achtest, solltest du:
            a) nicht in Perl programmieren, sondern eine vorab kompilierbare Sprache nehmen oder:
            b) die Module gleich im Speicher des Webservers halten (bei CGI-Skripten). Dann kannst du auch gleich alle Module laden, und das dynamische laden ist unnötig.

            use Tschoe qw(Matti);

            --
              Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
            1. Naja, er müßte in halt immer schreiben:

              $hash->{funktiosname} = sub () { .... };

              und könnte diese dann auch nicht mehr in verschiedenen Dateien unterbringen.

              OK, wenn man das so sieht. Die 15 Zeichen mehr habe ich auch überlebt :-)

              Ich halte meine Variante aber deshalb für komfortabel, weil man die Funktionen die zusamengehören in ein Modul packen kann. Gerade bei einem grossen Projekte wo ständig neue Features dazu kommen können ist dies ein unschlagbarer Vorteil, du willst ja nicht alle Funktionen in eine Datei packen.

              [...] ich will möglichst vermeiden, irgendwelche Probleme zur Laufzeit zu bekommen.

              Was sollen denn da für Probleme auftauchen?
              Letztlich schmeisst Perl ganz normal die Fehler oder überseh ich da was?

              Naja, wenn ich darauf achte, dass mein Perl-Script möglichst wenig Input bekommt, den es nicht kontrollieren kann, kann ich überhaupt vermeiden, dass Fehler während der Laufzeit auftreten. Ich finde immer, dass Laufzeitfehler am schlimmsten zu finden sind, und deswegen schreibe ich meine Scripte so, dass möglichst alles in einer kontrollierten Umgebung abläuft.

              Wieso? Die Fehlermeldung zur Laufzeit sind doch die gleichen. Das CGI Programme schwer zu debuggen sind ist ja nichts neues, aber ob die Module zur Laufzeit oder vorher benutzt werden spielt nur eine untergeordnete Rolle (wie gesagt ich benutz das auch gar nicht mehr so)

              Bsp (zugegeben einfach):
              Du hast ein Perl-Script, dass zur Laufzeit irgendwelche Dinge nachlädt (womöglich noch dynamisch). Wenn das nicht klappt, hast du gleich mehrere Fehlerquellen. Lädt es hingegen "konstante" Module, dann hast du eine potentielle Fehlerquelle ausgeschlossen. Die Performance ist hierbei nicht mehr wirklich entscheidend: Wenn du darauf wirklich achtest, solltest du:

              Du redest von Syntax Fehlern oder?
              also ich hatte bei der entwicklung eigentlich nie Probleme, die ich nicht auch mit ganz normalen Modulen gehabt hätte. Da wie gesagt die Fehlermeldungen ja trotzdem kommen.

              Um die Perfomrance ging es mehr auch eher weniger, wobei natürlich nicht jedes mal 380KB Perl skripte kompilieren will, um evtl. eine 5-zeilige Funktion aufzurufen.

              Wie gesagt aber einer gewissen Größe wirst du gar nicht umhin kommen Modular und je nach Fall verschiedene Module zu laden. Und ich war auf der Suche nach einer Methode dies möglichst zentral zu steuern. Bisher ist mein Ansatz eigentlich ganz praktisch gewesen.

              a) nicht in Perl programmieren, sondern eine vorab kompilierbare Sprache nehmen oder:

              kann ich nicht gut genug, zumal da die Plattformunabhänigkeit verloren ginge.

              b) die Module gleich im Speicher des Webservers halten (bei CGI-Skripten). Dann kannst du auch gleich alle Module laden, und das dynamische laden ist unnötig.

              wie gesagt ich lade nur dynamisch insofern, dass ich nur die Module die für eine Funktion gebraucht werden geladen werden. Macht in meinen Augen auch Sinn. Ob mein Provider mod_perl unterstützt weiss ich gar nicht und ob das Skript dann läuft auch nicht.

              Struppi.

    2. Hallo Matti,

      my $str = "rm -rf /"; eval $str; # Vorsicht: Code nicht ausprobieren
      :-)

      Schlechtes Beispiel. Hier wird lediglich $@ mit einem Fehlercode
      befüllt. Besser wäre vielleicht gewesen

      my $str = 'system("rm -rf /");';

      Grüße,
       CK

      --
      To define recursion, we must first define recursion.
      1. use Mosche;

        my $str = "rm -rf /"; eval $str; # Vorsicht: Code nicht ausprobieren
        Schlechtes Beispiel.

        Deswegen ja "Code nicht ausprobieren" :-)

        use Tschoe qw(Matti);

        --
          Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
  3. Hallo Lude,

    ich moechte in Abhaengigkeit des Wertes eines Skalars eine Funktion ausfuehren lassen. Primitive Ansaetze, wie
     &($in{WhatToDo});
     &$in{WhatToDo};

    Meinst du sowas:

    ($in{'WhatToDo'} eq "Bedingung") ? sub_1() : sub_2();

    Oder habe ich dich da missverstanden?

    Grüße
    Siechfred

  4. Hi,

    Wie geht es richtig? (Hoffentlich geht's mit dem griffigen Perl, in anderen Sprachen geht's ja oft nicht.)

    hmm, guck mal:
    http://perlbase.xwolf.de/cgi-bin/perlbase.cgi?dis.7.3.3
    isses das ?

    Gruss von KA-Mitte, Erwin

    --
    SELFforum - Das Tor zur Welt!
    Theoretiker: Wie kommt das Kupfer in die Leitung?
    Praktiker: Wie kommt der Strom in die Leitung?
    1. use Mosche;

      <quote von http://perlbase.xwolf.de/cgi-bin/perlbase.cgi?dis.7.3.3>
      Aufruf einer in einem hash definierten Funktion:

      vorherige Prüfung ob die Funktion definiert ist

      if(exists $function{'funktionsname'}){
          $function{'funktionsname'}(@parameterliste);
      }
      </quote>

      Wenn man wirklich prüfen will, sollte man das anders machen:

      sub is_sub {
         my $ref = shift;
         return defined $ref && ref($ref) eq 'CODE';
      }

      if (is_sub($function{'funktionsname'})) {
          $function{'funktionsname'}(@parameterliste);
      }

      Im Übrigen finde ich die Art, eine Lösungsmöglichkeit ein drittes Mal zu posten, irgendwie aufdringlich. Aber nur IMHO.

      use Tschoe qw(Matti);

      --
        Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
      1. Hi,

        Im Übrigen finde ich die Art, eine Lösungsmöglichkeit ein drittes Mal zu posten, irgendwie aufdringlich. Aber nur IMHO.

        kennst Du das Problem mit dem 'IMHO'? - Ich sag's Dir mal: in Wirklichkeit will der diese Kuerzel Benutzende fast immer etwas ganz anderes sagen.

        Gruss,
        Lude

        ---
        "Harald Schmidt, wo bist Du?"

        1. use Mosche;

          Im Übrigen finde ich die Art, eine Lösungsmöglichkeit ein drittes Mal zu posten, irgendwie aufdringlich. Aber nur IMHO.

          kennst Du das Problem mit dem 'IMHO'? - Ich sag's Dir mal: in Wirklichkeit will der diese Kuerzel Benutzende fast immer etwas ganz anderes sagen.

          Du kannst dir sicher sein, dass ich damit genau das sagen will, was das Kürzel aussagt. _Ich_ bin der Meinung, dass das ganze aufdringlich ist. Es steht nicht in der Netiquette oder in ähnlichen Dokumenten, und ich argumentiere auch nicht: hey, ich bin eine schützenswerte Minderheit, und meine Meinung gehört deswegen angenommen. Das habe ich im Übrigen auch nicht verlangt....

          use Tschoe qw(Matti);

          --
            Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
          1. Hi,

            kennst Du das Problem mit dem 'IMHO'? - Ich sag's Dir mal: in Wirklichkeit will der diese Kuerzel Benutzende fast immer etwas ganz anderes sagen.

            Du kannst dir sicher sein, dass ich damit genau das sagen will, was das Kürzel aussagt. _Ich_ bin der Meinung, dass das ganze aufdringlich ist.

            klar, ich aber bin der Meinung, dass der Beitrag von 'Erwin' nicht aufdringlich war, sondern ganz klar helfen wollte. Und ich bin der Meinung, dass diese meine Meinung nicht so relevant ist, dass ich sie hier ohne Anlass (BTW - danke fuer den Anlass, danke 'Erwin'!) aeussern muss. Das sollte auch fuer Deine Meinung gelten, oder?

            Gruss,
            Lude

            1. Hallo Lude,

              Und ich bin der Meinung, dass diese meine Meinung nicht so relevant ist, dass ich sie hier ohne Anlass [...] aeussern muss.

              1. Es gab einen Anlass, nämlich dass er es getan hat.
              2. Ich habe das ja nicht alleine in den Raum gestellt, sondern gleichzeitig eine Kritik zu seinem Eintrag in seiner perlbase abgegeben, damit er diese verbessern kann. Ich laufe nicht rum und versuche, allen möglichen Personen hier im Raum an ihr Bein zu pissen.

              So, jetzt aber EOT.

              use Tschoe qw(Matti);

              --
                Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
              1. hi Matti,

                1. Es gab einen Anlass, nämlich dass er es getan hat.

                es kann schon mal sein, dass ich einen thread offen habe, zwischenzeitlich was anderes tun muss, dann weiter schreibe und dann auf submit klicke.
                ^^^^^^^^^^^^^^^^^^^^
                Und ausnahmsweise, aber nur ausnahmsweise gebe ich hier mal die obenstehende Erklärung ab. Ansonsten ist das ein Forum hier und kein Tribunal.

                1. Ich habe das ja nicht alleine in den Raum gestellt, sondern gleichzeitig eine Kritik zu seinem Eintrag in seiner perlbase abgegeben, damit er diese verbessern kann. Ich laufe nicht rum und versuche, allen möglichen Personen hier im Raum an ihr Bein zu pissen.

                Da wärest Du auch der Erste der das schaffen würde ;-)

                Erwin

                --
                SELFforum - Das Tor zur Welt!
                Theoretiker: Wie kommt das Kupfer in die Leitung?
                Praktiker: Wie kommt der Strom in die Leitung?
                1. use Mosche;

                  1. Es gab einen Anlass, nämlich dass er es getan hat.

                  es kann schon mal sein, dass ich einen thread offen habe, zwischenzeitlich was anderes tun muss, dann weiter schreibe und dann auf submit klicke.

                  Das passiert ja, ich habe dir ja auch keine Absicht oder ähnliches unterstellt.

                  Und ausnahmsweise, aber nur ausnahmsweise gebe ich hier mal die obenstehende Erklärung ab. Ansonsten ist das ein Forum hier und kein Tribunal.

                  Ich habe keine Rechtfertigung verlangt. Ich habe offen gesagt, was mich ein wenig gestört hat, und werde das nicht nochmal tun (in gleicher Sache). Ich halte es nur besser, das ganze mal erwähnt zu haben, an so Aussagen kann man sich dann orientieren.

                  Für mich ist das Thema gegessen, deshalb wirklich EOT.

                  use Tschoe qw(Matti);

                  --
                    Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
  5. Hi,

    danke Euch allen! - Etwas schade, dass 'eval($in{WhatToDo})' boese ist. - Ich haette gerne darauf verzichtet ein "sub-Array" zu erstellen, aber diese Codierung ist dennoch viel weniger geschwaetzig als z.B.:

    if ($in{WhatToDo} eq 'BenutzerQuery') {&BenutzerQuery;}
    if ($in{WhatToDo} eq 'BezeichnungenQuery') {&BezeichnungenQuery;}
    if ($in{WhatToDo} eq 'BuchungenQuery') {&BuchungenQuery;}
    if ($in{WhatToDo} eq 'GeldanlagenQuery') {&GeldanlagenQuery;}
    if ($in{WhatToDo} eq 'GeldwechselnQuery') {&GeldwechselnQuery;}
    if ($in{WhatToDo} eq 'JobbearbeitungenQuery') {&JobbearbeitungenQuery;}
    if ($in{WhatToDo} eq 'JobsQuery') {&JobsQuery;}
    if ($in{WhatToDo} eq 'JobstatiQuery') {&JobstatiQuery;}
    if ($in{WhatToDo} eq 'KategorienQuery') {&KategorienQuery;}
    if ($in{WhatToDo} eq 'LaenderQuery') {&LaenderQuery;}
    if ($in{WhatToDo} eq 'OrteQuery') {&OrteQuery;}
    if ($in{WhatToDo} eq 'RechteQuery') {&RechteQuery;}
    if ($in{WhatToDo} eq 'VariablenQuery') {&VariablenQuery;}
    if ($in{WhatToDo} eq 'WaehrungenQuery') {&WaehrungenQuery;}
    if ($in{WhatToDo} eq 'DEL') {&DEL;}
    if ($in{WhatToDo} eq 'Insert') {&Insert;}
    if ($in{WhatToDo} eq 'Update') {&Update;}

    Gruss,
    Lude

    ---
    "Harald Schmidt, wo bist Du?"

    1. Hi,

      danke Euch allen! - Etwas schade, dass 'eval($in{WhatToDo})' boese ist. - Ich haette gerne darauf verzichtet ein "sub-Array" zu erstellen, aber diese Codierung ist dennoch viel weniger geschwaetzig als z.B.:

      if ($in{WhatToDo} eq 'BenutzerQuery') {&BenutzerQuery;}
      if ($in{WhatToDo} eq 'BezeichnungenQuery') {&BezeichnungenQuery;}
      if ($in{WhatToDo} eq 'BuchungenQuery') {&BuchungenQuery;}

      $funktion('BenutzerQuery') = sub{
       # statements
      };

      $funktion('BezeichnungenQuery') = sub{}; # usw

      bei einer Eingabe einfach aufrufen

      $function{$in{WhatToDo}}(@parameterliste);

      voila - ohne großartige Kontrollstruktur ;-)

      Erwin

      --
      SELFforum - Das Tor zur Welt!
      Theoretiker: Wie kommt das Kupfer in die Leitung?
      Praktiker: Wie kommt der Strom in die Leitung?
      1. Hi,

        danke Euch allen! - Etwas schade, dass 'eval($in{WhatToDo})' boese ist. - Ich haette gerne darauf verzichtet ein "sub-Array" zu erstellen, aber diese Codierung ist dennoch viel weniger geschwaetzig als z.B.:

        if ($in{WhatToDo} eq 'BenutzerQuery') {&BenutzerQuery;}
        if ($in{WhatToDo} eq 'BezeichnungenQuery') {&BezeichnungenQuery;}
        if ($in{WhatToDo} eq 'BuchungenQuery') {&BuchungenQuery;}

        $funktion('BenutzerQuery') = sub{
         # statements
        };

        $funktion('BezeichnungenQuery') = sub{}; # usw

        bei einer Eingabe einfach aufrufen

        $function{$in{WhatToDo}}(@parameterliste);

        voila - ohne großartige Kontrollstruktur ;-)

        AlsoDu musst halt nur die Funktionen in dem hash %funktion definieren, weiter oben...

        Ähhm, mach sicherheitshalber doch eine Prüfung:

        if(exists $funktion{$in{'WhatToDo'}}){ $funktion{$in{'WhatToDo'}} }
        else{ # funktion nicht definiert }

        Erwin

        --
        SELFforum - Das Tor zur Welt!
        Theoretiker: Wie kommt das Kupfer in die Leitung?
        Praktiker: Wie kommt der Strom in die Leitung?
  6. ich moechte in Abhaengigkeit des Wertes eines Skalars eine Funktion ausfuehren lassen. Primitive Ansaetze, wie

    &($in{WhatToDo});
     &$in{WhatToDo};

    funzten net.

    So funktioniert es, ich mach das lange schon (gleichzeitig lade ich dann auch das dazugehörige modul zur Laufzeit)

    if(defined &{$in{WhatToDo}})
    {
    no strict 'refs';
    &{$in{WhatToDo}}( ... );
    }
    else
    {
    print "Funktion existiert nicht!";

    }

    Struppi.

  7. Hallo Lude,

    ich moechte in Abhaengigkeit des Wertes eines Skalars eine Funktion
    ausfuehren lassen. Primitive Ansaetze, wie

    &($in{WhatToDo});
    &$in{WhatToDo};

    funzten net.

    'funzen' gibts nicht.

    Wie geht es richtig? (Hoffentlich geht's mit dem griffigen Perl, in
    anderen Sprachen geht's ja oft nicht.)

    Am einfachsten und saubersten ist das ueber ein Modul per Autoload
    zu implementieren:

    Actions.pm:

    package Actions;

    our $AUTOLOAD;

    sub aktion1 {
      my $self = shift;
      ...
    }

    sub aktion2 {
      my $self = shift;
      ...
    }

    sub AUTOLOAD {
      my $self = shift;
      my $subname = lc $AUTOLOAD;

    $subname =~ s/.*:://;

    if($subname ne 'destroy' && $subname ne 'end') {
        if(my $ref = $self->can($subname)) {
          &$ref($self,@_);
        }
        else {
          # Fehler, undefinierte Aktion
        }
      }
    }

    1;

    Script:

    use Actions;

    my $subname = $hash->{WhatToDo};
    my $acts = new Actions;

    $acts->$subname();

    AUTOLOAD wird hier also nur dazu benutzt, um zu prüfen, ob eine
    Methode vielleicht in falscher Gross- oder Kleinschreibweise
    übergeben wurde und um ein eigenes Fehlerhandling zu ermöglichen.
    Die Methode ist sauber und strict-kompatibel. Mehr dazu gibts unter

    perldoc perlsub
    perldoc perlmod
    perldoc perltoot
    perldoc UNIVERSAL

    Grüße,
     CK

    --
    Mit einem Windhauch kannst du das Feuer loeschen. Mit einem Windhauch kannst du das Feuer entfachen.
    1. Hi,

      Am einfachsten und saubersten ist das ueber ein Modul per Autoload
      zu implementieren:
      [...]

      danke fuer den Hinweis! - Wenn ich den Perl-Meister schon da habe, eine kleine Frage zur angeregten 'EVAL'-"Loesung". Gibt es da ggf. eine ungefaehrliche Variante, die der Anforderungslage entsprechen wuerde?

      Gruss,
      Lude

      ---
      "Wenn von dort her der Wind ueber die Felder weht, dann weiss ich es wird Sommer."

      1. Hallo Lude,

        danke fuer den Hinweis! - Wenn ich den Perl-Meister schon da habe,
        eine kleine Frage zur angeregten 'EVAL'-"Loesung". Gibt es da ggf.
        eine ungefaehrliche Variante, die der Anforderungslage entsprechen
        wuerde?

        Jain. Die einzig sichere Methode ist es, zu prüfen, ob 'WhatToDo' in
        einer Whitelist steht, denn sonst kann der Angreifer bel. Code
        ausführen (und sei es nur, dein Script zu irritieren, indem er
        nicht-existente Subs anspricht oder Perl-interne Funktionen benutzt).
        Das rechtfertigt den Aufwand IMHO nicht, da ist die Autoload-Lösung
        beispielsweise sehr viel schöner und einfacher.

        Grüße,
         CK

        --
        Ich bewundere wirklich den Sinn der Bienen für kollektive Verantwortung. Obwohl sich einzelne Bienen hin und wieder bekämpfen, herrscht zwischen Ihnen grundsätzlich ein starkes Gefühl für Eintracht und Zusammenarbeit. Wir Menschen gelten als sehr viel weiter entwickelt, doch mitunter rangieren wir sogar hinter kleinen Insekten.
        1. Hallo nochmal,

          vergessen zu erwähnen: eval ist auch langsamer. Für 'eval "string"' muss
          der Lexer noch ein weiteres mal angeworfen werden, und der String muss
          alle Stati der Perl-VM noch einmal durchlaufen.

          Grüße,
           CK

          --
          Sobald dir ein Gedanke kommt, lache über ihn.