hotti: Code referenzieren

Hi,

bin mal wieder über diese Dinge gestolpert, hoppla, das ist mir nicht ganz klar, 2 Varianten:

  
# Struktur für Menu und Eingangsseite  
my %menu = (  
    1 => ['Html', 'Inhalte erstellen und bearbeiten', &html],  
    2 => ['Html', 'Inhalte erstellen und bearbeiten', \&html],  
);  
  
# Aufruf der Funktionen  
#1  
print $menu{1}->[2]  
  
#2  
print $menu{2}->[2]->();  

Was ist da jetzt der Unterschied, spielt die Perlversion eine Rolle? Auf meiner Kiste ist 5.6.1, da geht Beides. MMn dürfte #1 breits mit dem '&' eine Referenz auf den code darstellen, #2 wäre eine Refernz auf Referenz, sehe ich das richtig? Bitte mal um Hinweise,

Schöne Grüße,
Horst

--
Differenzen und Summen, kürzen nur die Dummen.
  1. Struktur für Menu und Eingangsseite

    my %menu = (
        1 => ['Html', 'Inhalte erstellen und bearbeiten', &html],
        2 => ['Html', 'Inhalte erstellen und bearbeiten', &html],
    );

    Im ersten Fall führst du die Funktion aus und weist das Resultat dem Array zu.
    Im zweiten Fall speicherst du eine Referenz, ohne die Funktion auszuführen.
    Die Funktion wird erst beim dereferenzieren ausgeführt.

    Aufruf der Funktionen

    #1
    print $menu{1}->[2]

    Nein, kein Funktionsaufruf, sondern schlicht zugriff auf das Arrayelement.

    #2
    print $menu{2}->[2]->();

      
    Zugriff auf die Referenz im Array und Dereferenzierung derselben, führt die Funktion aus.  
      
    
    > Was ist da jetzt der Unterschied,  
      
    siehe oben...  
      
    Bei Dispatch-Tabellen will man letzteres in aller Regel.  
      
    mfg Beat
    
    -- 
    
    ><o(((°>           ><o(((°>  
    
       <°)))o><                     ><o(((°>o  
    Der Valigator leibt diese Fische
    
    1. [code lang=perl]

      Struktur für Menu und Eingangsseite

      my %menu = (
          1 => ['Html', 'Inhalte erstellen und bearbeiten', &html],
          2 => ['Html', 'Inhalte erstellen und bearbeiten', &html],
      );

      Im ersten Fall führst du die Funktion aus und weist das Resultat dem Array zu.
      Im zweiten Fall speicherst du eine Referenz, ohne die Funktion auszuführen.
      Die Funktion wird erst beim dereferenzieren ausgeführt.

      Beat, mein Lieber, wusste ichs doch, dass Du mir helfen kannst. Jetzt ist mir der Fall klar, ich hätte dann doch lieber #2 ;-)

      Viele Grüße in die schöne Schweiz,
      Horst vom Oberrhein

  2. bin mal wieder über diese Dinge gestolpert, hoppla, das ist mir nicht ganz klar, 2 Varianten:

    Nein! Das sind keine zwei Varianten, sondern zwei völlig unterschiedliche Dinge.

    [code lang=perl]

    Struktur für Menu und Eingangsseite

    my %menu = (
        1 => ['Html', 'Inhalte erstellen und bearbeiten', &html],

    Hier rufst du die Funktion html auf und weist dem 3. Arraywert den Wert zu, den die Funktion zurück gibt.

    2 => ['Html', 'Inhalte erstellen und bearbeiten', &html],

    und hier weist du dem dritten Wert die Referenz auf die Funktion zu.

    Aufruf der Funktionen

    #1
    print $menu{1}->[2]

    Das ist nicht der Aufruf der Funktion, sondern der Rückgabewert.

    #2
    print $menu{2}->[2]->();

    Was ist da jetzt der Unterschied, spielt die Perlversion eine Rolle? Auf meiner Kiste ist 5.6.1, da geht Beides.

    "Gehen" tut natürlich beides, es ist nur etwas völlig unterschiedliches.

    Struppi.

    1. hi Struppi,

      "Gehen" tut natürlich beides, es ist nur etwas völlig unterschiedliches.

      danke auch Dir, ja ist klar jetzt, was passiert. Also ich nehme dann doch die Referenz ;-)

      Es ist so, dass ich nicht gerne eine print-Liste unterbreche, daher geben meine Funktionen nicht selbst was aus, sondern haben einen Rückgabewert, der in die print-Anweisungs-Liste eingebaut wird. Das Array in meinem Menu-Hash soll natürlich klein bleiben, klar da muss ne Referenz rein:

        
      # Struktur für Menu und Eingangsseite  
      my %menu = (  
          1 => ['HTML', 'HTML-Inhalte erstellen und bearbeiten, CSS-Dateien, Titel, Ordner und andere Attribute den Inhalten zuweisen.', \&htmlmanager],  
          2 => ['CSS','Dateien für Cascading Stylesheets erstellen und bearbeiten.', \&cssmanager],  
      );  
      ###########################################################################  
      use strict;  
      use CGI;  
        
      my $u = new CGI;  
        
      if($u->param){  
          if(my $mnr = $u->param('menu')){  
              print $u->header($hth), $u->start_html($htu), $u->h1($htu->{title}), $menu{$mnr}->[2]->(), qq(<p><a href="$ENV{SCRIPT_NAME}">Zum Editor Hauptindex</a></p>), $u->end_html;  
          }  
          else{  
          }  
      # usw.  
      
      

      Morgen gehts dann weiter mit dem kleinen Script, d.h., fertig isses schon, muss nur noch tippen.

      Grüße nach Mainz!
      Hotti

      1. "Gehen" tut natürlich beides, es ist nur etwas völlig unterschiedliches.

        danke auch Dir, ja ist klar jetzt, was passiert. Also ich nehme dann doch die Referenz ;-)

        Es ist so, dass ich nicht gerne eine print-Liste unterbreche, daher geben meine Funktionen nicht selbst was aus, sondern haben einen Rückgabewert, der in die print-Anweisungs-Liste eingebaut wird. Das Array in meinem Menu-Hash soll natürlich klein bleiben, klar da muss ne Referenz rein:

        Irgendwie klingt das für mich, als ob du immer noch nicht den Unterschied der beiden Varianten in deinem ersten Posting verstanden hast. Das erste ist keine Referenz und hat auch nichts damit zu tun.

        Statt:

        my %menu = (  
            1 => ['Html', 'Inhalte erstellen und bearbeiten', &html],  
            2 => ['Html', 'Inhalte erstellen und bearbeiten', \&html],  
        );
        

        könntest du folgendes schreiben (und solltest auch, da das kaufmännische-Und als Funktionssigil nur verwendet werden sollte, wenn du die Parameter weitereichen oder die prototyp Deklaration überschreiben willst)

        my %menu = (  
            1 => ['Html', 'Inhalte erstellen und bearbeiten', html()],  
            2 => ['Html', 'Inhalte erstellen und bearbeiten', \&html],  
        );
        

        Ich hoffe jetzt ist es klarer.

        Struktur für Menu und Eingangsseite

        my %menu = (
            1 => ['HTML', 'HTML-Inhalte erstellen und bearbeiten, CSS-Dateien, Titel, Ordner und andere Attribute den Inhalten zuweisen.', &htmlmanager],
            2 => ['CSS','Dateien für Cascading Stylesheets erstellen und bearbeiten.', &cssmanager],
        );
        [...]

          
        Wobei ich mich frage warum du einen Hash mit Zahlen als keys benutzt, ein Array ist schneller.  
          
        Struppi.
        
        1. hi Struppi,

          Ich hoffe jetzt ist es klarer.

          Das wars doch gestern schon, danke Dir!!!

          Wobei ich mich frage warum du einen Hash mit Zahlen als keys benutzt, ein Array ist schneller.

          Und auch gleich so sortiert, so wie ich das hinschreibe!!! Jow, einen Hash brauche ich an der Stelle auch nicht, das wird dann auch ein (anonymous) Array, danke für Deinen Tipp!!!

          Viele Grüße,
          schönen Sonntag,
          Horst Wonnegau