Nobbi: Parameterübergabe

Hallo,
in meinem Perl-Programm habe ich Unterroutinen, die jeweils eine große Anzahl von Parametern benötigen.
Dadurch sind die Aufrufe recht unübersichtlich.
Gibt es da eine elegantere Möglichkeit?
Ein erheblicher Teil dieser Parameter wird von allen Unterroutinen benötigt. Ist es sinnvoll, diese dann als global zu definieren.
Vielen Dank für Eure Tipps.
Nobbi

  1. Hi,

    in meinem Perl-Programm habe ich Unterroutinen, die jeweils eine große Anzahl von Parametern benötigen.
    Dadurch sind die Aufrufe recht unübersichtlich.
    Gibt es da eine elegantere Möglichkeit?

    ich höre in der Ferne einen Ruf. Er kommt von weit her, der Wind versucht die Laute zu verwischen, aber dennoch versteht man das eine Wort, welches immer wieder wiederholt wird: "Objektorientierung! Objektorientierung!"

    Ein erheblicher Teil dieser Parameter wird von allen Unterroutinen benötigt.

    Objektorientierung.

    Ist es sinnvoll, diese dann als global zu definieren.

    War das eine Frage.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hallo,

      ich höre in der Ferne einen Ruf. Er kommt von weit her, der Wind versucht die Laute zu verwischen, aber dennoch versteht man das eine Wort, welches immer wieder wiederholt wird: "Objektorientierung! Objektorientierung!"

      Wie poetisch, allerdings hilft mir das momentan nicht weiter!

      Objektorientierung.

      s.o.

      Ist es sinnvoll, diese dann als global zu definieren.

      War das eine Frage.

      Ja, natürlich! Man wird ja wohl mal ein Satzzeichen vergessen dürfen.

      Gruß
      Nobbi

      NB. Ich hoffe, dass im Forum nicht nur Schwafler sind sondern auch Leute, die konkret helfen wollen.

      1. Hi,

        Wie poetisch, allerdings hilft mir das momentan nicht weiter!

        warum nicht?

        NB. Ich hoffe, dass im Forum nicht nur Schwafler sind sondern auch Leute, die konkret helfen wollen.

        Wenn Du meinst, die Hilfe sei zu wenig konkret, solltest Du dies begründen, anstatt in Abholhaltung zu verharren und darauf zu warten, dass andere Deine Probleme für Dich lösen.

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        -Please-Search-Archive-First: Absolutely Yes
        1. Genauso so gut hättest Du schreiben können, ich solle eine andere Sprache verwenden!

          1. hallo,

            Genauso so gut hättest Du schreiben können, ich solle eine andere Sprache verwenden!

            Dann verwende doch mal testweise eine andere Sprache, beispielsweise PHP. Wenn dann deine Funktionen (das kann ja ungefähr dem entsprechen, was in Perl Subroutinen sind) auch wieder ganz viele Übergabeparameter benötigen, und du nachfragst, wird dir wieder der Rat entgegenschlagen, doch auf Objektorientierung zu achten.

            Behandle deine Subroutinen als Objekte. Das ist alles.

            Grüße aus Berlin

            Christoph S.

            --
            Visitenkarte
            ss:| zu:) ls:& fo:) va:) sh:| rl:|
            1. Behandle deine Subroutinen als Objekte. Das ist alles.

              Nein, absolut nicht, etwas konkreter müsste man da schon werden. Subroutinen kann man nicht mal eben so als Objekte behandeln, insofern ist Dein Hinweis wenig hilfreich. Freilich kann man ein eigenes Konfigurationsobjekt nutzen (oder was vorgefertigtes von CPAN.org). Im einfachsten Falle genügt auch ein eigener Namensraum (als Package-Datei oder innerhalb  des Scripts):

              package myConfig;  
                
              use strict;  
                
              our $sense_of_life = 42;  
              our $number_of_the_beast = 666;  
                
              1;
              

              Und der Zugriff:

              use myConfig;  
              use strict;  
                
              print $myConfig::sense_of_life;  
              print $myConfig::number_of_the_beast;
              

              Nur mal so als Denkanstoß.

              Siechfred

              --
              Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
              1. Behandle deine Subroutinen als Objekte. Das ist alles.

                Nein, absolut nicht, etwas konkreter müsste man da schon werden. Subroutinen kann man nicht mal eben so als Objekte behandeln, insofern ist Dein Hinweis wenig hilfreich. Freilich kann man ein eigenes Konfigurationsobjekt nutzen (oder was vorgefertigtes von CPAN.org).

                Ich glaube man kann aus den Schilderungen des OP und dessen was die vermeintliche Lösung ist, schliessen dass es nicht dass es um Konfigurationsvariabeln geht.

                Auch scheint der OP Schwierigkeiten mit Perlobjekten zu haben (zumindest nach dessen Reaktion auf den sinnvollen Vorschlag von Cheatah zu beurteilen), desweiteren läßt sich vermuten, dass der OP nicht besonders häufig Module vom CPAN nutzt, da diese ja auch nicht selten mit Hashparametern arbeiten (z.b. das CGI Modul) und er diese Möglichkeit nicht kannte.

                Es bleibt, wir Wissen nichts konkretes, ausser das der OP Schwierigkeiten mit zuvielen Parametern hat, kennen weder den Kontext, woher die Parameter kommen, in welchen zusammenhang sie evtl. stehen und ob es bereits Module/Objekte gibt, die verwendetet werden.

                Aber dein Vorschlag wäre zumindest einer der (echte) globale Variabeln vermeidet.

                Struppi.

          2. Hi,

            Genauso so gut hättest Du schreiben können, ich solle eine andere Sprache verwenden!

            klar, wenn sie wie Perl objektorientiert arbeiten kann. Aber warum sollte ich Dich von Perl abbringen wollen?

            Cheatah

            --
            X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
            X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
            X-Will-Answer-Email: No
            X-Please-Search-Archive-First: Absolutely Yes
  2. gudn tach!

    in meinem Perl-Programm habe ich Unterroutinen, die jeweils eine große Anzahl von Parametern benötigen.
    Dadurch sind die Aufrufe recht unübersichtlich.
    Gibt es da eine elegantere Möglichkeit?

    wie waers mit einem pointer auf ein assoziatives array?

    prost
    seth

    1. Hallo,
      klingt gut!
      Danke

      1. Hi

        Da du auch nicht sonderlich speziell gefragt hast, hier allgemein gehaltene Antworten.

        Pointer auf Hashes (=assoziatives Array) zu übergeben ist eine bereits genannte Möglichkeit.

        Zudem solltest du erwägen bei vielen Argumenten benannte Parameter zu übergeben.

        OOP in Perl erfordert leider einen höheren Einstiegsaufwand als in vielen anderen Sprachen, aber in einfachen Fällen kann man auch sehr gut mit Closures arbeiten.

        Ciao
          Kurt

        1. Hi Forum

          obwohl das Flattening von Listen die Parametrisierung von Perlroutinen IMHO schwerer macht, kann man auch schicke Überladungseffekte erreichen

          ~~~"perl"

          use strict;
          use warnings;

          use Data::Dumper;

          my %default=(
           ich =>  "ICH",
           du =>  "DU",
          );

          sub named_arg{
           my %args=(%default,@_);
           print '%args: ', Dumper %args ;
          }

          my %standard=(
           ihr =>  'Forum',
          );

          my %Mr_Nerv=(
           ich =>  "Renate Beppo-Bautz geb. Nobbi",
           ihr =>  "Deppen",
          );

          named_arg(ich =>'Kurt');

          named_arg(ich =>'Kurt', %standard);

          named_arg(ich =>'Kurt', %standard, %Mr_Nerv);

          \_\_DATA\_\_  
            
          %args: $VAR1 = {  
                    'ich' => 'Kurt',  
                    'du' => 'DU'  
                  };  
          %args: $VAR1 = {  
                    'ihr' => 'Forum',  
                    'ich' => 'Kurt',  
                    'du' => 'DU'  
                  };  
          %args: $VAR1 = {  
                    'ihr' => 'Deppen',  
                    'ich' => 'Renate Beppo-Bautz geb. Nobbi',  
                    'du' => 'DU'  
                  };  
            
            
            
            
            
          
          
  3. in meinem Perl-Programm habe ich Unterroutinen, die jeweils eine große » Dadurch sind die Aufrufe recht unübersichtlich.
    Gibt es da eine elegantere Möglichkeit?

    Anzahl von Parametern benötigen.

    Wenn du die immer brauchsr, wirst du wohl um OOP nicht drumherum kommen, wenn es dir nur darum geht, dass es lästig ist sich immer die Reihenfolge zu merken und du nicht immer alle Parameter brauchst, ist die erwähnte Hash Referenz ein probates und häufig verwendetes Mittel.

    Ein erheblicher Teil dieser Parameter wird von allen Unterroutinen benötigt. Ist es sinnvoll, diese dann als global zu definieren.

    Nein.

    Struppi.

    1. Hallo,

      Wenn du die immer brauchsr, wirst du wohl um OOP nicht drumherum kommen, wenn es dir nur darum geht, dass es lästig ist sich immer die Reihenfolge zu merken und du nicht immer alle Parameter brauchst, ist die erwähnte Hash Referenz ein probates und häufig verwendetes Mittel.

      Habe mal angefangen mich in OOP einzulesen.
      Dabei habe ich mit der Modultechnik begonnen.
      Dabei ist mir folgendes aufgefallen.
      In vielen Beispielen werden in der EXPORT-Anweisung zahlreiche Variablen angegeben, die im rufenden Programm gar nicht angesprochen werden.
      Ist dies dann sinnvoll?
      (Es besteht doch die Gefahr, dass Variablen der Unterroutine versehentlich geändert werden).
      Diese zahlreichen Angaben wohl deshalb, weil andere rufenden Programme andere Variablen benötigen. Aber kann man es dann nicht anders machen?
      Wie werden die exportierten Variablen eigentlich bezeichnet?
      Sind sie global (da in Haupt- und Unterprogramm bekannt)?
      Gruß
      Nobbi

      1. Habe mal angefangen mich in OOP einzulesen.
        Dabei habe ich mit der Modultechnik begonnen.

        Das ist natürlich der richtige Weg, aber hat erstmal nichts mit OOP zu tun. Trotzdem musst du Wissen wie man mit packages umgeht.

        Dabei ist mir folgendes aufgefallen.
        In vielen Beispielen werden in der EXPORT-Anweisung zahlreiche Variablen angegeben, die im rufenden Programm gar nicht angesprochen werden.
        Ist dies dann sinnvoll?

        Kommt darauf an, viele CPAN Module haben nur eine kleine funktionalität und werden i.d.R. nicht OOP eingesetzt, d.h. sie werden eingebunden und exportieren, entweder per default oder bei Bedarf, bestimmte Funktionen oder Variabeln, das ist sinnvoll. Du kennst das vielleicht vom CGI Modul, wo du bestimmte Gruppen von Funktionen exportieren kannst (z.b. :standard). Ist das Modul größer, sollte man aufpassen, den man "verschmutzt" sich damit sein Namensraum und bekommt evtl. Konflikte mit den Namen der eigenen Funktionen oder Variabeln.

        (Es besteht doch die Gefahr, dass Variablen der Unterroutine versehentlich geändert werden).

        Wenn Variabeln exportiert werden, dann soll das ja so sein, dass du die Kontrolle über diese bekommst, um sie mit deinen Werten zu füllen.

        Diese zahlreichen Angaben wohl deshalb, weil andere rufenden Programme andere Variablen benötigen. Aber kann man es dann nicht anders machen?

        Natürlich kann man das anders machen, in dem man wirklich OOP arbeitet. Perl bietet dir in dieser Hinsicht erhebliche Freiheiten, es gibt z.b. keine echten privaten Variabeln (man kann diese aber durchaus auch erzeugen).

        Wie werden die exportierten Variablen eigentlich bezeichnet?
        Sind sie global (da in Haupt- und Unterprogramm bekannt)?

        Nein global wären sie, wenn sie in allen Modulen/packages bekannt werden. Aber wie man sie explizit nennt weiß ich nicht.

        Du hast aber auch gesehen dass es unterschiedliche Möglichkeiten gibt zu Exportieren? Entweder du Export immer oder nur auf Wunsch.

        Aber im Grunde kann man dir nicht wirklich konkret helfen, das was Cheatah dir gesagt hat ist so ziemlich auch mein erster Gedanken gewesen, aber um konkreter zu werden, müßte man mehr über den Kontext Wissen.

        Struppi.

        1. Hallo

          ..., aber um konkreter zu werden, müßte man mehr über den Kontext wissen.

          Es werden diverse Unterroutinen aufgerufen der Art:
          ...
          header($farbe,$format,$url,$kopfzeile,...);
          ...
          inhalt($farbe,$inhalt,$url,...);
          ...
          fehlermeldung($farbe,$format,$url,$fehlerart,$fehlertext,.......);
          ...
          $erg = rechne($p1, $p2);
          print "$erg";
          ...

          Wenn ich das Modulkonzept richtig verstehe, könnte ich jetzt ein Modul mymod.pm erstellen mit den Routinen

          • header
          • inhalt
          • fehlermeldung
            ...
            und alle obigen Variablen in EXPORT angeben.
            Damit könnte ich aufrufen
            mymod::header
            mymod::inhalt
            mymod::fehlermeldung
            d.h. ohne die Parameterangabe im Aufruf?

          Und
          mymod::rechne;           # ohne Zuweisung an $erg
          print "$erg";

          Oder liege ich da völlig falsch?
          Gruß
          Nobbi

          1. Ich hab bis jetzt nicht geantwortet, weil die Frage eigentlich den Rahmen eines Forums sprengt. Ich versuch's mal

            Es werden diverse Unterroutinen aufgerufen der Art:
            ...
            header($farbe,$format,$url,$kopfzeile,...);
            ...
            inhalt($farbe,$inhalt,$url,...);
            ...
            fehlermeldung($farbe,$format,$url,$fehlerart,$fehlertext,.......);

            Ich gehe mal davon aus, dass wir von einem CGI Programm sprechen, du willst also eine Internetseite ausgeben. Sicherverwendest du schon das CGI Modul mit dem du leicht die HTML Ausgabe zusammenbasteln kannst. Wenn das Projekt größer ist, empfiehlt es sicher aber mit einem Templatesystem zu arbeiten z.b. HTML::Template, dann musst du dir in deinem Perlskript keinen Gedanken mehr um die HTML Ausgabe machen.

            Wenn ich das Modulkonzept richtig verstehe, könnte ich jetzt ein Modul mymod.pm erstellen mit den Routinen

            • header
            • inhalt
            • fehlermeldung
              ...
              und alle obigen Variablen in EXPORT angeben.

            Das wäre ein Modul ja (aber nicht mit Objektorientierter Programmierung verwechseln, damit hat es überhaupt nichts zu tun). Die Frage die du dir stellen musst ist: welches sind Modulvariabeln, also nur dort notwendig?
            So wie du sie oben beschrieben hast, machen die Funktionen meiner Meinung viel zuviel. Auch Exportieren sollte man sparsam, damit verschmutzt du dir den Namensraum des Skriptes und wirst Schwierigkeiten beim Fehlersuchen bekommen.

            Du solltest Funktionalität trennen, konkret läßt sich nur mit den Namen der Parameter, natürlich nicht viel sagen, aber z.b. eine Funktion die Fehlermeldung heißt, würde ich nur den Text übergeben.

            Aber wenn du wirklich der Meinung bist dass die Funktion soviele Parameter braucht, dann heißt dein Objekt Fehlermeldung und hat die diversen Eigenschaften wie farbe, format, url, usw.

            Damit könnte ich aufrufen
            mymod::header
            mymod::inhalt
            mymod::fehlermeldung
            d.h. ohne die Parameterangabe im Aufruf?

            Nein, so nicht.

            Module sind in erster Linie dazu da, häufig verwendete Funktionen auszulagern, damit du diese auch an anderer Stelle einbinden und verwenden kannst, außerdem kannst du Variabeln vor dem Zugriff aus dem Hauptprogramm kapseln.

            Noch besser wird aber die Sache wenn du mit Objekten arbeitest, dann musst du keine Funktionen exportieren, da dann alles Funktionen an das Objekt gebunden sind.

            Struppi.