Connie: Frage zu packages

0 80

Frage zu packages

Connie
  • perl
  1. 0
    Patrick Andrieu
    1. 0
      Connie
      1. 0
        Connie
        1. 0
          Patrick Andrieu
          1. 0
            Struppi
            1. 0
              Patrick Andrieu
              1. 0
                Struppi
                1. 0
                  Patrick Andrieu
            2. 0
              Connie
              1. 0
                Connie
    2. 0
      Connie
    3. 6

      Konzept der Namensräume; Global, Dynamic und Lexical Scope

      Siechfred
      1. 0
        Connie
      2. 0
        Connie
        1. 0
          Patrick Andrieu
          1. 0
            Connie
            1. 0
              Patrick Andrieu
              1. 0
                Connie
                1. 0
                  Connie
                  1. 0
                    Struppi
                    1. 0
                      Connie
                      1. 0
                        Struppi
                        1. 0
                          Connie
                          1. 0
                            Struppi
                            1. 0
                              Connie
                              1. 0
                                Struppi
                                1. 0
                                  Connie
                                  1. 0
                                    Struppi
                                    1. 0
                                      Connie
                                      1. 0
                                        Struppi
                                      2. 0
                                        Struppi
                                      3. 0
                                        Patrick Andrieu
                                        1. 0
                                          Struppi
                                          1. 0
                                            Kurt
                                            1. 0
                                              Struppi
                                              1. 0
                                                Kurt
                                                1. 0
                                                  Struppi
                                                  1. 0
                                                    Kurt
                                                    1. 0
                                                      Kurt
                                                      1. 0
                                                        Thomas
                                                        1. 0
                                                          Siechfred
                                                          1. 0
                                                            Kurt
                                                            1. 0
                                                              Siechfred
                                                              1. 0
                                                                Kurt
                                                        2. 0
                                                          Kurt
                                                          1. 0
                                                            Kurt
        2. 0
          Siechfred
      3. 0
        Patrick Andrieu
        1. 0
          Kurt
      4. 0
        Kurt
        1. 0

          my erzeugt keinen Packagevariablen!

          Kurt
        2. 0
          Siechfred
          1. 0
            Siechfred
            1. 0

              Konzeption...

              Patrick Andrieu
              • menschelei
            2. 0
              Kurt
              1. 0
                Siechfred
                1. 0
                  Kurt
  2. 0
    Kurt
    1. 0
      Kurt
    2. 0
      Struppi
      1. 0
        Kurt
      2. 0
        Interessierter Leser
        1. 0
          Interessierter Leser
          1. 0

            Coping with Scoping

            Kurt
        2. 0
          Kurt
  3. 0

    Zusammenfassende Darstellung, Kritik willkommen!

    Siechfred
    1. 0
      Kurt
      1. 0
        Struppi
        1. 0
          Kurt
          1. 0
            Struppi
            1. 0
              Thomas
              1. 0
                Struppi
            2. 0
              Kurt
              1. 0
                Struppi
                1. 0

                  1 Klasse= 1 Modul ?

                  Kurt
                  1. 0
                    Struppi
      2. 0
        Siechfred
        1. 0
          Thomas
        2. 0
          Kurt

Hallo,
in dem nachfolgenden Beispiel hätte ich gedacht, dass der letzte print das Ergebnis main:main liefert, nämlich den Wert der in main definiert ist. Stattdessen liefert er den Wert aus dem package p2.

  
#!/usr/bin/perl -w  
  
use strict;  
print "Content-type: text/html\n\n";  
my $var1 = "main";  
print "main:$var1<br>";  
  
  
package p1;  
my $var1 = "p1";  
print "p1:$var1<br>";  
  
package p2;  
my $var1 = "p2";  
print "p2:$var1<br>";  
  
package main;  
print "main:$var1<br>";  

  1. Hallo Connie!

    Testet Du im Browser (ich frage wegen Content-type: text/html)? Dann müsstest Du dafür sorgen, dass Dir die Warnungen im Browser angezeigt werden - oder auf der Konsole testen. Oder, Xitami vorausgesetzt - und hier kenne ich leider nicht die entsprechende Datei im Apache - in die cgierr.log nachschauen: Dort werden neben den Fehlern auch die Warnungen ausgegeben.

    Jedenfalls... die Konsole hätte Dich gewarnt:

    --------------
    C:>perl -w
    use strict;
    print "Content-type: text/html\n\n";
    my $var1 = "main";
    print "main:$var1<br>";

    package p1;
    my $var1 = "p1";
    "my" variable $var1 masks earlier declaration in same scope at - line 8.
    print "p1:$var1<br>";

    package p2;
    my $var1 = "p2";
    "my" variable $var1 masks earlier declaration in same scope at - line 12.
    print "p2:$var1<br>";

    package main;
    print "main:$var1<br>";
    ^Z
    Content-type: text/html

    main:main<br>p1:p1<br>p2:p2<br>main:p2<br>
    --------------

    Es ist zugegebenermaßen nicht einfach mit den Namensräumen, ich habe selbst noch damit zu kämpfen...

    Siehe auch http://spotlight.de/zforen/prl/m/prl-1188412656-27443.html

    Viele Grüße aus Frankfurt/Main,
    Patrick

    --

    _ - jenseits vom delirium - _
    [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
    Nichts ist unmöglich? Doch!
    Heute schon gegökt?
    1. Hier noch das Beispiel, das das erwartete Ergebnis liefert:

        
      #!/usr/bin/perl -w  
        
      $var1 = "main";  
      print "main:$var1<br>";  
        
        
      package p1;  
      $var1 = "p1";  
      print "p1:$var1<br>";  
        
      package p2;  
      $var1 = "p2";  
      print "p2:$var1<br>";  
        
      package main;  
      print "main:$var1<br>";  
      
      ~~~            
      
      1. Warum ist mein anderer Beitrag mit den Fragen verschwunden?

        1. Hallo Connie!

          Warum ist mein anderer Beitrag mit den Fragen verschwunden?

          Du hast gestern hier im Thread zweimal den selben Beitrag abgeschickt (21.40 und 21.41 Uhr). Den von 21.41 Uhr habe ich gelöscht. Da waren keine weiteren Fragen, es ist genau der selbe Inhalt wie im sichtbaren Beitrag von 21.40 Uhr... Was meinst Du genau?

          Viele Grüße aus Frankfurt/Main,
          Patrick

          --

          _ - jenseits vom delirium - _
          [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
          Nichts ist unmöglich? Doch!
          Heute schon gegökt?
          1. Du hast gestern hier im Thread zweimal den selben Beitrag abgeschickt (21.40 und 21.41 Uhr). Den von 21.41 Uhr habe ich gelöscht. Da waren keine weiteren Fragen, es ist genau der selbe Inhalt wie im sichtbaren Beitrag von 21.40 Uhr... Was meinst Du genau?

            Es wurde zwar keine Frage gestellt, aber der Inhalt war unterschiedlich. Ich mache die Löschung rückgängig.

            Struppi.

            1. Hallo Struppi!

              der Inhalt war unterschiedlich. Ich mache die Löschung rückgängig.

              Hm, seht Ihr was, was ich nicht sehe?

              Die folgende Nachricht zum Thema stammt von: Connie, 27. September 2007, 21:40

              Hier noch das Beispiel, das das erwartete Ergebnis liefert:
              #!/usr/bin/perl -w

              $var1 = "main";
              print "main:$var1<br>";

              package p1;
              $var1 = "p1";
              print "p1:$var1<br>";

              package p2;
              $var1 = "p2";
              print "p2:$var1<br>";

              package main;
              print "main:$var1<br>";

              Das Posting wurde bereits 0 mal als fachlich hilfreich bewertet.

              -------------------------------------------

              Die folgende Nachricht zum Thema stammt von: Connie, 27. September 2007, 21:41

              Hier noch das Beispiel, das das erwartete Ergebnis liefert:
              #!/usr/bin/perl -w

              $var1 = "main";
              print "main:$var1<br>";

              package p1;
              $var1 = "p1";
              print "p1:$var1<br>";

              package p2;
              $var1 = "p2";
              print "p2:$var1<br>";

              package main;
              print "main:$var1<br>";

              Das Posting wurde bereits 0 mal als fachlich hilfreich bewertet.

              Viele Grüße aus Frankfurt/Main,
              Patrick

              --

              _ - jenseits vom delirium - _
              [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
              Nichts ist unmöglich? Doch!
              Heute schon gegökt?
              1. Die folgende Nachricht zum Thema stammt von: Connie, 27. September 2007, 21:40

                arghl, das hatte ich gar nicht bemerkt, ich dachte du meinst die von 20:36 und 20:40 und hättest den kleinen Unterschied nicht bemerkt.

                also wieder weg damit.

                Struppi.

                1. Hallo Struppi!

                  also wieder weg damit.

                  Ich habe soeben den Termin beim Augenarzt wieder abgesagt ;)

                  Gut, aber wieder ernst und hoffentlich bekommt Connie eine Antwort!

                  Viele Grüße aus Frankfurt/Main,
                  Patrick

                  --

                  _ - jenseits vom delirium - _
                  [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                  Nichts ist unmöglich? Doch!
                  Heute schon gegökt?
            2. In der Tat, da ist etwas schiefgelaufen.
              Ich hatte erst einige Fragen gestellt (ca. 21:40) und dann kurz danach das Beispiel gepostet. Offensichtlich habe ich aber die Fragen nicht abgeschickt sondern dafür das Beispiel zweimal, sorry.

              Der Beitrag sollte in etwa so lauten.
              Das Beispiel (aus dem Internet) von 21:41 liefert das erwartete Ergebnis, nämlich im letzen print "main:main".
              Nun hatte ich ebenfalls gelesen, dass man "use strict" verwenden sollte, was ich dann auch gemacht hatte. Dann kam aber der Fehler, dass die Variablen nicht def. seien. Daraufhin habe ich das "my" hinzugefügt und es kam zu dem fehlerhaften Beispiel im Eingangsthread.
              Eine der Fragen war nun:
              Wie muss ich es anstellen, dass die zu Beginn definierte Variable im package main am Ende ihren alten Wert hat und in den anderen packages jeweils eigene Variablen verwendet werden?

              1. Jetzt habe ich erst den Beitrag von Siechfried entdeckt.
                Vielleicht verstehe ich den ja und meine Frage erübrigt sich.

    2. Hier noch das Beispiel, das das erwartete Ergebnis liefert:

        
      #!/usr/bin/perl -w  
        
      $var1 = "main";  
      print "main:$var1<br>";  
        
        
      package p1;  
      $var1 = "p1";  
      print "p1:$var1<br>";  
        
      package p2;  
      $var1 = "p2";  
      print "p2:$var1<br>";  
        
      package main;  
      print "main:$var1<br>";  
      
      ~~~            
      
    3. Es ist zugegebenermaßen nicht einfach mit den Namensräumen, ich habe selbst noch damit zu kämpfen...

      Dann will ich mal versuchen, etwas Licht ins Dunkel zu bringen.

      Namespace vs. Scope

      Zunächst muss unterschieden werden zwischen Namespace und Scope. Während Namespace der Namensraum ist, über den eine Variable "identifiziert" wird, bedeutet Scope zum Einen, wo eine Variable gültig ist und zum Anderen nach welchen Regeln (local vs. my, my vs. our). Den Namensraum einer Variablen notiert man durch Voranstellen von 'namespace::', ein Script hat immer den Namensraum 'main::'. Die Angabe des Namensraumes entfällt, wenn er eindeutig ist oder sich auf das aktuelle Package bezieht.

      Symboltabellen, package-Anweisung

      Perl speichert intern alle Symbole (Skalare, Arrays, Hashes, Subs usw.) in internen Symboltabellen. Jeder Namensraum hat eine eigene Symboltabelle, sodass man sagen kann, dass Namespace vereinfacht der Name der Symboltabelle ist, zu dem das Symbol gehört. Die package-Anweisung macht also untechnisch nichts anderes, als zu prüfen, ob es bereits eine Symboltabelle mit dem Namen gibt, den die Funktion als Argument mitbekommt, sie im Bedarfsfall anlegt und dem Script sagt, dass es bis zur nächsten package-Anweisung resp. bis zum Ende des Scriptes diese Symboltabelle verwenden soll. Daneben haben alle Symboltabellen, die das selbe Script betreffen *und* in der Hierarchie oberhalb des aktuellen packages liegen, weiter Gültigkeit, insbesondere 'main'.

      Global Scope

      Perl bietet traditionell die Möglichkeit, Variablen global zu definieren:

      { $foo = 'bar'; }  
      print $foo;
      

      $foo ist global und damit überall im Script sichtbar. Dieses Verfahren ist sehr fehleranfällig und erschwert die Suche nach Problemen, da bei der Modifikation globaler Variablen unerwartete Ergebnisse auftreten können, und dann sucht man verzweifelt nach der Stelle, wo die ungewollte Modifikation stattfand. Dies ist der Hauptgrund, weshalb man das strict-Pragma verwenden sollte - um eben solche fehleranfälligen Strukturen zu vermeiden.

      Dynamic Scope

      Der nächste Schritt ist der sog. Dynamic Scope, repräsentiert durch local. Dabei wird nichts anderes gemacht, als für den umschließenden Block eine Variable anzulegen, die nur dort Gültigkeit hat. Gibt es eine globale Variable, wird sie im Block kopiert und sämtliche Manipulationen innerhalb des Blocks werden ungültig, wenn der Block beendet ist. Gibt es keine gleichnamige globale Variable, wird sie als quasi-lokale Variable angelegt:

      $foo = 'global';  
        
      {  
        local $foo = 'lokal';  
        print $foo;  # lokal  
      }  
        
      print $foo;  # global
      

      Oft wird local mit my gleichgesetzt, das ist aber grundfalsch! Mein Lieblingsartikel hierzu sagt ganz lapidar: "Always use my; never use local." :)

      Stellt sich natürlich die berechtigte Frage, wofür der Dynamic Scope gut sein soll. Diese Frage kann man ganz einfach mit einem kleinen Codeschnipsel beantworten (aus perlfaq5):

      my $input;  
        
      {  
        local(*INPUT, $/);  
        open INPUT, 'datei.txt' || die "can't open: $!";  
        $input = <INPUT>;  
      }
      

      Es gibt nämlich in Perl verschiedene, vom System vorgegebene globale Variablen, so z.B. $/ für den Record Separator (also das Zeichen, das beim Einlesen eine Zeile beendet). Knackpunkt ist die local-Anweisung, die diese globale Variable kopiert. Da keine Wertzuweisung erfolgt, ist ihr Wert undef, sodass man die Datei in einem Rutsch in den Skalar $input einlesen kann. Wird der Block geschlossen, ist die lokale Kopie im Datennirvana, der global definierte Wert bleibt während der ganzen Operation unangetastet.

      Lexical Scope

      Der eleganteste und am wenigsten fehleranfällige Weg, Variablen zu deklarieren, ist der Lexical Scope. Innerhalb eines Namensraumes gibt es bestimmte Regeln, nach denen Variablen sichtbar sind. Außerhalb des umgebenden Blocks oder Namensraums sind sie nur sichtbar, wenn sie mittels our deklariert wurden, wurden sie mittels my deklariert, sind sie nach außen unsichtbar. Nach innen sind beide Varianten für alle nachgeordneten Blöcke und Namensräume sichtbar (das ist übrigens auch die Fehlerquelle des Threadstarters):

      use strict;  
      my $foo = 'declared in main';  
        
      package bar;  
      $foo .= ' and modified in bar';  
      my $foo_loc = 'local in bar';  
      our $foo_glob = 'local in bar but visible outside';  
        
      package main;  
      # wir wollen keinen Scriptabbruch provozieren  
      no strict 'vars';  
      print defined $foo ? $foo : 'undef';  # declared in main and modified in bar  
      print defined $bar::foo_loc ? $bar::foo_loc : 'undef';  # undef  
      print defined $bar::foo_glob ? $bar::foo_glob : 'undef';  # local in bar but visible outside
      

      Hier kann man sehr schön die Auswirkungen des lexikal scopes sehen. $foo ist im Namensraum 'main' deklariert und von da an im gesamten Script sichtbar, also auch im Package bar. Die Variable $foo_loc ist via my als lokal innerhalb des Packages bar deklariert mit der Besonderheit, dass sie außerhalb von bar nicht sichtbar ist, während $foo_glob zwar auch lokal in bar ist, aber durch die Deklaration via our nach außen sichtbar ist. Um auf $foo_glob außerhalb von bar zuzugreifen, notiert man den Namensraum davor (also $bar::foo_glob). Jede Manipulation an $foo_glob, auch außerhalb von bar, hat Auswirkungen auch innerhalb von bar:

      use strict;  
        
      package bar;  
      our $foo_glob = 'local in bar but visible outside';  
        
      sub show_bar {  
        return $foo_glob;  
      }  
        
      package main;  
      $bar::foo_glob .= ', tricky, isn\'t it?';  
      print bar::show_bar;
      

      Faszinierend, was dabei herauskommt, oder? ;)

      Natürlich kann man den lexical scope auch ohne strict-Pragma verwenden, er ist *nicht* an dieses Pragma gebunden! Allerdings nimmt strict dem Programmierer die Prüfung ab, ob er bei allen verwendeten Symbolen die Regeln des lexical scope beachtet hat und warnt bei Verstößen bis hin zum Programmabbruch.

      So, ich hoffe, dass ich etwas Licht ins Dunkel bringen konnte, ansonsten frage gerne nochmal nach.

      Siechfred

      1. Hallo Siechfred!
        Ich muss zugeben, dass ich noch nicht allzuviel verstanden habe, wegen fehlender Syntaxkenntnisse insbes. das Beispiel mit dem Dateilesen. Und im letzten Beispiel hast Du in den Unterroutinen andere Variablennamen verwendet als in main.
        Konkrete Fragen kann ich im Augenblick noch nicht formulieren.
        Wäre nett, wenn Du ab und zu schauen könntest, ob ich mich gemeldet habe.
        Gruß
        Connie

      2. Hallo Siechfred,
        also jetzt einige Fragen.

        Dynamic Scope

        Gibt es eine globale Variable, wird sie im Block kopiert und sämtliche Manipulationen innerhalb des Blocks werden ungültig, wenn der Block beendet ist.

        Unter kopieren verstehe ich die Neuanlage der Variablen in dem Package   m i t  dem Variablenwert

        Gibt es keine gleichnamige globale Variable, wird sie als quasi-lokale Variable angelegt:

        Was heißt quasi-lokal? Wenn die Variable nur in dem Block gültig ist und nicht wie die mit "our" definierte Variablen auch außerhalb, ist dies doch echt lokal - oder nicht?

        Knackpunkt ist die local-Anweisung, die diese globale Variable kopiert. Da keine Wertzuweisung erfolgt, ist ihr Wert undef, ...

        Warum undef, wenn Variable kopiert wurde (s.o.)

        Lexical Scope
        ... Außerhalb des umgebenden Blocks oder Namensraums sind sie nur sichtbar, ....

        Ist Block ein anderer Begriff für Namensraum, wenn nein was hat der Block mit Namespace und Scope zu tun?

        ... wurden sie mittels my deklariert, sind sie nach außen unsichtbar. Nach innen sind beide Varianten für alle nachgeordneten Blöcke und Namensräume sichtbar

        Nach aussen und nach innen ist mir unklar.

        Die Variable $foo_loc ist via my als lokal innerhalb des Packages bar deklariert mit der Besonderheit, dass sie außerhalb von bar nicht sichtbar ist, während $foo_glob zwar auch lokal in bar ist, aber durch die Deklaration via our nach außen sichtbar ist. Um auf $foo_glob außerhalb von bar zuzugreifen, notiert man den Namensraum davor (also $bar::foo_glob). Jede Manipulation an $foo_glob, auch außerhalb von bar, hat Auswirkungen auch innerhalb von bar:

        $foo_glob ist lokal in bar aber von außen sichtbar, ja sogar änderbar.
        Anscheinend verstehe ich lokal falsch. Bisher war ich der Meinung "lokal" heißt nur in der betreffenden Ugebung bekannt (Datenkapselung).

        Gruß Connie

        1. Hallo Connie!

          Ist Block ein anderer Begriff für Namensraum, wenn nein was hat der Block mit Namespace und Scope zu tun?

          Ein Block ist eine Reihenfolgen von Anweisungen oder Deklarationen innerhalb von geschweiften Klammern:

          {
            print "foo\n";
          }

          if (defined $etwas) {
            ...
            ...
            ...
          }

          sub mysub {
            ...
            ...
            ...
          }

          Mit my deklarierten Variablen sind nur innerhalb des Blockes gültig, in welchem sie deklariert worden sind. local-Variablen sind insofern weniger lokal, als dass sie auch ihre Gültigkeit in Unterprogrammen behalten, die innerhalbs des Blocks aufgerufen werden. Ist hier ziemlich gut erklärt.

          Nach aussen und nach innen ist mir unklar.

          Nach außen unsichtbar bedeutet (s.o.): außerhalb des Blockes, in welchem eine my-Variable deklariert wurde, ist sie nicht »sichtbar«, Du kannst auf sie nicht zugreifen.
          Nach innen: Innerhalb des Blockes kannst Du auf diese my-Variable sehr wohl zugreifen.

          Viele Grüße aus Frankfurt/Main,
          Patrick

          --

          _ - jenseits vom delirium - _
          [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
          Nichts ist unmöglich? Doch!
          Heute schon gegökt?
          1. Hallo,
            sorry, aber ich habs immer noch nicht begriffen!

              
            #!/usr/bin/perl -w  
            use strict;  
            package p1;  
            my $var1 = "p1";  
            print "p1:$var1\n";  
            package p2;  
            print "p2:$var1\n";  
            package main;  
            print "main:$var1\n";  
            
            

            Ergebnis:
            p1:p1
            p2:p1
            main:p1

            Die lokale Variable $var1 ist deklariert im package p1 und trotzdem sichtbar im package main und sogar im package p2.
            Ich hätte erwartet, dass die Variable in main und p2 nicht sichtbar ist.
            Packages sollen doch dazu dienen, dass beliebieg viele Leute Routinen entwickeln,
            die dann gemeinsam verwendet werden können. Nach dem obigen Ergebnis müßten sich aber
            die Autoren absprechen, damit nur einer $var1 verwendet.

            Patrick schrieb:
            Nach außen unsichtbar bedeutet (s.o.): außerhalb des Blockes, in welchem eine my-Variable deklariert wurde, ist sie nicht »sichtbar«, Du kannst auf sie nicht zugreifen.
            Nach innen: Innerhalb des Blockes kannst Du auf diese my-Variable sehr wohl zugreifen.

            Wie müßte obiges Beispiel aussehen, damit $var1 in p2 und in main undefiniert ist?

            1. Hallo Connie!

              sorry, aber ich habs immer noch nicht begriffen!

              Ich bin auch nicht sicher, dass ich... aber versuchen wir's mal ;)

              #!/usr/bin/perl -w
              use strict;
              package p1;
              my $var1 = "p1";
              print "p1:$var1\n";
              package p2;
              print "p2:$var1\n";
              package main;
              print "main:$var1\n";

              
              >   
              > Ergebnis:  
              > p1:p1  
              > p2:p1  
              > main:p1  
                
                
              
              > Die lokale Variable $var1 ist deklariert im package p1 und trotzdem sichtbar im package main und sogar im package p2.  
              > Ich hätte erwartet, dass die Variable in main und p2 nicht sichtbar ist.  
                
              [Eike Grothe](http://perl-seiten.homepage.t-online.de/html/perl_modul.html#abs1) schreibt hierzu: »Tritt bei der Programmausführung eine package-Anweisung auf, so gilt ab dort der Namensraum des entsprechenden Packages mit eigenen Variablen. Das heißt, jede Variable ist an ein bestimmtes Package gebunden. Wichtige Ausnahmen hiervon sind Variablen, die mit my deklariert werden, sowie spezielle Variablen wie $\_ oder @ARGV.«  
                
              
              > Packages sollen doch dazu dienen, dass beliebieg viele Leute Routinen entwickeln,  
              > die dann gemeinsam verwendet werden können. Nach dem obigen Ergebnis müßten sich aber  
              > die Autoren absprechen, damit nur einer $var1 verwendet.  
                
              Das ist nahe an der Frage, die ich im Spotlight-Forum stellte: »Also, wie kann ich verhindern, dass ein "Nachfolger", der das Programm bearbeitet, Variablen aus dem Modul überschreibt (Darum ging's mir ja...)?«  
                
              Ich gehe davon aus, dass Du aus den Packages Module machen willst, die Du später mit use ...; eibinden willst? Schon probiert?  
                
              Viele Grüße aus Frankfurt/Main,  
              Patrick
              
              -- 
              ![](http://www.atomic-eggs.com/zensstop.gif)  
                
              \_ - jenseits vom delirium - \_  
                
              [[link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash](http://www.atomic-eggs.com/)]  
              Nichts ist unmöglich? [Doch!](http://www.atomic-eggs.com/cwi/cwi_4.shtml)  
              Heute schon ge[gök](http://goek.atomic-eggs.com/goek_goek.html)t?
              
              1. Hi,

                Eike Grothe schreibt hierzu: »Tritt bei der Programmausführung eine package-Anweisung auf, so gilt ab dort der Namensraum des entsprechenden Packages mit eigenen Variablen. Das heißt, jede Variable ist an ein bestimmtes Package gebunden. Wichtige Ausnahmen hiervon sind Variablen, die mit my deklariert werden, sowie spezielle Variablen wie $_ oder @ARGV.«

                Ich glaube, da herrscht doch unter den Experten noch große Uneinigkeit. Im Buch Webprogrammierung mit Perl und CGI steht:
                Mit my wird der Geltungsbereich einer Variablen eingeengt. Ohne my sind Variablen global und aus jeder Programmebene heraus aufrufbar, aber eben auch überschreibbar. Mit my wird der Geltungsbereich auf einen Namensraum (Anmerkung von mir: also u.a. auf ein package, was in meinem Beispiel nicht der Fall ist) oder eine Anweisungsblock eingeschränkt.

                Mein Vertrauen in Perl ist tief erschüttert!
                Gruß
                Connie

                1. Hi, nochmals

                  Ich glaube, da herrscht doch unter den Experten noch große Uneinigkeit.

                  Ergänzung:
                  Gerade habe ich in
                  http://perldoc.perl.org/perlsub.html#Private-Variables-via-my()
                  gelesen:
                  WARNING: The use of attribute lists on my declarations is still evolving. The current semantics and interface are subject to change.

                  Als wohl nicht so ganz ausgegoren!

                  Gruß Connie

                  1. Ich glaube, da herrscht doch unter den Experten noch große Uneinigkeit.

                    nein, wieso?
                    my deklariert Variabeln lokal in einem Scope nicht in einem Namensraum. Wenn das in deinem Buch anders steht, dann taugt das Buch nichts.

                    Ergänzung:
                    Gerade habe ich in
                    http://perldoc.perl.org/perlsub.html#Private-Variables-via-my()
                    gelesen:
                    WARNING: The use of attribute lists on my declarations is still evolving. The current semantics and interface are subject to change.

                    Als wohl nicht so ganz ausgegoren!

                    Nein, das bezieht sich auf eine Neuerung in Perl, die ich aber auch noch nicht verstanden habe.
                    http://perldoc.perl.org/attributes.html

                    Struppi.

                    1. my deklariert Variabeln lokal in einem Scope nicht in einem Namensraum. Wenn das in deinem Buch anders steht, dann taugt das Buch nichts.

                      So stehts nicht nur in meinem Buch sondern in vielen Beiträgen, u.a. auch in Beiträgen zu diesem thread.

                      Als wohl nicht so ganz ausgegoren!

                      Nein, das bezieht sich auf eine Neuerung in Perl, die ich aber auch noch nicht verstanden habe.
                      http://perldoc.perl.org/attributes.html

                      Ja , u.a. attributes für my.

                      WARNING: attribute declarations for variables are still evolving. The semantics and interfaces of such declarations could change in future versions. They are present for purposes of experimentation with what the semantics ought to be. Do not rely on the current implementation of this feature.

                      Wenn ich auch ältere Definitionsversuche von my, global und local lese, bleibt nur der Schluss: "no nix gnaus woas'mer net"!
                      Der gesunde Menschenverstand sagt mir "Wenn ich eine lokale Variable definiere in einem package, so soll sie auch nur in dem package sichtbar sein. Schließlich soll das package in verschiedene Anwendungen integrierbar sein".
                      Vielleicht ist aber auch nur der Begriff lokal falsch gewählt.
                      Gruß
                      Connie

                      1. Nein, das bezieht sich auf eine Neuerung in Perl, die ich aber auch noch nicht verstanden habe.
                        http://perldoc.perl.org/attributes.html
                        Ja , u.a. attributes für my.

                        Ja, das hat aber nichts mit my an sich zu tun.

                        Wenn ich auch ältere Definitionsversuche von my, global und local lese, bleibt nur der Schluss: "no nix gnaus woas'mer net"!

                        Doch weiß man.

                        Der gesunde Menschenverstand sagt mir "Wenn ich eine lokale Variable definiere in einem package, so soll sie auch nur in dem package sichtbar sein. Schließlich soll das package in verschiedene Anwendungen integrierbar sein".

                        Ja und da du normalerweise package für Module verwendest ist das genau der Fall.
                        Wenn du mehrere Namensräume in einem Modul hast ist das eher ungewöhnlich

                        Vielleicht ist aber auch nur der Begriff lokal falsch gewählt.

                        Mit my deklarierst du Variabeln lokal in einem scope, ein package ist kein scope.

                        Struppi.

                        1. Vielleicht ist aber auch nur der Begriff lokal falsch gewählt.

                          Mit my deklarierst du Variabeln lokal in einem scope, ein package ist kein scope.

                          Zitat perldoc.perl.org:
                          A my declares the listed variables to be local (lexically) to the enclosing block, file, or eval

                          File kann doch auch genau ein package enthalten.

                          Und die Folge dieser seltsamen Definitionen ist damit wohl,
                          dass das Verhalten unterschiedlich ist, je nachdem ich ein package direkt im Programm angebe oder es über use p1 von einer externen Datei hole.
                          Dies ist für mich völlig unverständlich!

                          1. Zitat perldoc.perl.org:
                            A my declares the listed variables to be local (lexically) to the enclosing block, file, or eval

                            File kann doch auch genau ein package enthalten.

                            nein, file ist ein file in dem durchaus mehrere packages sein können.

                            Und die Folge dieser seltsamen Definitionen ist damit wohl,
                            dass das Verhalten unterschiedlich ist, je nachdem ich ein package direkt im Programm angebe oder es über use p1 von einer externen Datei hole.

                            Ein File ist ein neuer scope, ein package nicht, was ist daran denn unverständlich?

                            Dies ist für mich völlig unverständlich!

                            scheint so, obwohl es Siechfred so gut erklärt hat.

                            Struppi.

                            1. File kann doch auch genau ein package enthalten.

                              nein, file ist ein file in dem durchaus mehrere packages sein können.

                              Ich habe nicht geschrieben, dass genau ein package enthalten sein muss, sondern kann!

                              Und die Folge dieser seltsamen Definitionen ist damit wohl,
                              dass das Verhalten unterschiedlich ist, je nachdem ich ein package direkt im Programm angebe oder es über use p1 von einer externen Datei hole.

                              Wo steht geschrieben, dass das Programm anders reagiert, wenn ich ein package in eine Datei auslagere und es mit use einbinde?
                              Und selbst wenn es so dokumentiert sein sollte, so ist es doch ein völlig unnormales Verhalten, wenn ich vergleiche mit entsprechenden copy-/include-...Funktionen in anderen Programmiersprachen!

                              1. File kann doch auch genau ein package enthalten.

                                nein, file ist ein file in dem durchaus mehrere packages sein können.
                                Ich habe nicht geschrieben, dass genau ein package enthalten sein muss, sondern kann!

                                Ich weiß wirklich nicht wo dein Problem ist. Ein package ist ein Namensraum und ein scope ist ein Gültigkeitsbereich. Variabeln sind mit my, lokal in einem Gültigkeitsbereich, aber in allen Namensräumen eines Gültigkeitsbreich zugreifbar.

                                Wo steht geschrieben, dass das Programm anders reagiert, wenn ich ein package in eine Datei auslagere und es mit use einbinde?

                                Ein File ist ein Gültigkeitsbereich.

                                Und selbst wenn es so dokumentiert sein sollte, so ist es doch ein völlig unnormales Verhalten, wenn ich vergleiche mit entsprechenden copy-/include-...Funktionen in anderen Programmiersprachen!

                                Keine Ahnung, ich kenn keine vergleichbaren Programmiersprachen. PHP und C/C++ gehen völlig andere Wege.

                                Struppi.

                                1. Mein Problem ist, dass Du nicht genau liest.
                                  Beispiel:
                                  Meine Aussage:

                                  File kann doch auch genau ein package enthalten.

                                  Deine Antwort:

                                  nein, file ist ein file in dem durchaus mehrere packages sein können.

                                  Wieso das "nein" in Deiner Aussage? Habe ich gesagt muss?

                                  Und mein Problem ist, dass Du nicht auf meine Argumente/Fragen eingehst.
                                  Beispiel:
                                  Meine Frage:

                                  Wo steht geschrieben, dass das Programm anders reagiert, wenn ich ein package in eine Datei auslagere und es mit use einbinde?

                                  Deine Antwort:

                                  Ein File ist ein Gültigkeitsbereich.

                                  Ich kann nur feststellen, dass ich nirgendwo sinngemäß gefunden habe,
                                  "Programme können modular aufgebaut werden. Wenn man aber ein package aus einem Programm in eine Datei auslagert, sind Variablen anders zu behandeln (weil dann der Gültigkeitsbereich der im package definierten my-Variablen plötzlich auf das file beschränkt wird)."

                                  Keine Ahnung, ich kenn keine vergleichbaren Programmiersprachen.

                                  Schade!

                                  1. Mein Problem ist, dass Du nicht genau liest.

                                    sehr seltsam so kommt es mir auch vor.

                                    Beispiel:
                                    Meine Aussage:

                                    File kann doch auch genau ein package enthalten.

                                    Deine Antwort:

                                    nein, file ist ein file in dem durchaus mehrere packages sein können.

                                    Wieso das "nein" in Deiner Aussage? Habe ich gesagt muss?

                                    Hab ich was anderes gesagt?
                                    Ich habe gesagt ein File ist ein File und ein package ist ein package das sind zwei Dinge deren unterschied z.b. sich bei der Verwendung von my asuwirkt. Denn unterschied scheinst oder willst du nicht verstehen. Und ich verstehe nicht warum.

                                    Und mein Problem ist, dass Du nicht auf meine Argumente/Fragen eingehst.
                                    Beispiel:
                                    Meine Frage:

                                    Wo steht geschrieben, dass das Programm anders reagiert, wenn ich ein package in eine Datei auslagere und es mit use einbinde?

                                    Deine Antwort:

                                    Ein File ist ein Gültigkeitsbereich.

                                    Ein File ist ein neuer Gültigkeitsbereich ein package nicht, das ist der Unterschied der dir nicht klar ist, bzw. auf den du in keinsterweise eingehst.

                                    Ich kann nur feststellen, dass ich nirgendwo sinngemäß gefunden habe,
                                    "Programme können modular aufgebaut werden. Wenn man aber ein package aus einem Programm in eine Datei auslagert, sind Variablen anders zu behandeln (weil dann der Gültigkeitsbereich der im package definierten my-Variablen plötzlich auf das file beschränkt wird)."

                                    Nichts ist da plötzlich, da ist exakt das Verhalten was dir hier die ganze Zeit versucht wird zu erklären.

                                    Keine Ahnung, ich kenn keine vergleichbaren Programmiersprachen.
                                    Schade!

                                    Kennst du welche?

                                    Struppi.

                                    1. Mein Problem ist, dass Du nicht genau liest.

                                      sehr seltsam so kommt es mir auch vor.

                                      Beispiel:
                                      Meine Aussage:

                                      File kann doch auch genau ein package enthalten.

                                      Deine Antwort:

                                      nein, file ist ein file in dem durchaus mehrere packages sein können.

                                      Wieso das "nein" in Deiner Aussage? Habe ich gesagt muss?

                                      Hab ich was anderes gesagt?

                                      Allerdings!

                                      "Programme können modular aufgebaut werden. Wenn man aber ein package aus einem Programm in eine Datei auslagert, sind Variablen anders zu behandeln (weil dann der Gültigkeitsbereich der im package definierten my-Variablen plötzlich auf das file beschränkt wird)."

                                      Nichts ist da plötzlich, da ist exakt das Verhalten was dir hier die ganze Zeit versucht wird zu erklären.

                                      Und ich versuche Dir zu erklären, dass diese Eigenschaft nicht offensichtlich ist, wenn von Modularisierung gesprochen wird, und dass man dieses unterschiedliche Verhalten nur herausfindet, nachdem man darauf hereingefallen ist oder Dutzende widersprüchlichre Aussagen analysiert hat.

                                      Keine Ahnung, ich kenn keine vergleichbaren Programmiersprachen.
                                      Schade!

                                      Kennst du welche?

                                      Ohne unbescheiden zu sein:
                                      Die Dinosaurier Assembler (IBM und TR440), Algol, Fortran , PL1, Cobol, eine Zeit wo man mangels Rechnerzugang noch denken musste und nicht nach dem Motto "try and error" vorgehen konnte,
                                      dann C, C++, SAS (4-GL) am Host und PC,
                                      dann der komplette Schwenk zum PC mit Java, Javascript und, und, und...

                                      Im Voraus schon besten Dank für den zu erwartenden zynischen Ausdrucks der Bewunderung, den ich mir allerdings nicht mehr zumuten will.
                                      Tschau

                                      1. "Programme können modular aufgebaut werden. Wenn man aber ein package aus einem Programm in eine Datei auslagert, sind Variablen anders zu behandeln (weil dann der Gültigkeitsbereich der im package definierten my-Variablen plötzlich auf das file beschränkt wird)."

                                        Nichts ist da plötzlich, da ist exakt das Verhalten was dir hier die ganze Zeit versucht wird zu erklären.

                                        Und ich versuche Dir zu erklären, dass diese Eigenschaft nicht offensichtlich ist, wenn von Modularisierung gesprochen wird, und dass man dieses unterschiedliche Verhalten nur herausfindet, nachdem man darauf hereingefallen ist oder Dutzende widersprüchlichre Aussagen analysiert hat.

                                        Naja, du hast ein Buch genannt wo es anscheinend anders drin steht. Ansonsten sind diese Begrifflichkeiten soweit klar.
                                        ein Modul ist unter Perl eine .pm datei, packages sind keine Module, auch keine Klassen oder etwas ähnliches. das steht soweit auch in der Perldoku

                                        A package statement affects only dynamic variables--including those you've used local on--but not lexical variables, which are created with my.

                                        Kennst du welche?

                                        Ohne unbescheiden zu sein:
                                        Die Dinosaurier Assembler (IBM und TR440), Algol, Fortran , PL1, Cobol, eine Zeit wo man mangels Rechnerzugang noch denken musste und nicht nach dem Motto "try and error" vorgehen konnte,
                                        dann C, C++, SAS (4-GL) am Host und PC,
                                        dann der komplette Schwenk zum PC mit Java, Javascript und, und, und...

                                        Du irrst, der Großteil der Sprachen verfolgen ein anderes Konzept, wie Variabeln unter Perl deklariert werden hatte Siechfred schon, wie ich finde, ziemlich gut erklärt und bei JS ist es definitiv nicht so, dort ist es sogar noch eingeschränkter, lokale Variabel die mit var deklariert werden, sind nur innerhalb einer Funktion lokal, allerdings dort in allen Blöcken bekannt, also auch innerhalb von fremden scopes.

                                        Im Voraus schon besten Dank für den zu erwartenden zynischen Ausdrucks der Bewunderung, den ich mir allerdings nicht mehr zumuten will.

                                        Ich hab wirklich keine Ahnung was dein Problem ist, du hast eine Frage gestellt, die wir versuchen dir seit Tagen zu beantworten, stattdessen reitest du auf deiner Meinung herum, die eben bei Perl so nicht zutrifft, du hast einiges bekommen zum lesen wie das Konzept ist und denkst jetzt ich wollte mit dir darüber streiten?
                                        Mir ist es doch egal ob du es verstehst oder nicht, ich und Siechfred und Patrick wollten dir lediglich helfen das Konzept zu verstehen.

                                        Tschau

                                        Naja, es wird vieleicht ein anderen helfen es zu verstehen.

                                        Struppi.

                                      2. Und ich versuche Dir zu erklären, dass diese Eigenschaft nicht offensichtlich ist, wenn von Modularisierung gesprochen wird, und dass man dieses unterschiedliche Verhalten nur herausfindet, nachdem man darauf hereingefallen ist oder Dutzende widersprüchlichre Aussagen analysiert hat.

                                        Nochmal, wie gesagt es steht in der Doku, aber auch der Link von Siechfred ist da sehr eindeutig (ich hab den auch erst jetzt gelesen)
                                        http://perl.plover.com/FAQs/Namespaces.html#The_Current_Package

                                        my variables are not package variables. They're not part of a package, and they don't have package qualifiers. The current package has no effect on the way they're interpreted.

                                        und der Grund dafür

                                        The declaration my $x = 17 at the top creates a new lexical variable named x whose scope continues to the end of the file. This new meaning of $x overrides the default meaning, which was that $x meant the package variable $x in the current package.

                                        Mit my deklarierte Variabeln sind lokale Variabeln im scope (also in einem Block oder in einer Datei), willst du eine package Variabel deklarieren, dann musst du dies ohne my tun, den diese sind lokale Variabeln keine Variabeln im package.

                                        use strict;  
                                        package A;  
                                        no strict 'vars';  
                                        $var = 'x';  
                                        package main;  
                                        print $A::var;  
                                        
                                        

                                        Kennst du welche?

                                        Ohne unbescheiden zu sein:

                                        und ich bezweifle dass eine diese Sprachen diese, wenn man es beherrscht, tolle Konzept hat.

                                        Struppi.

                                      3. Hallo Connie!

                                        Und ich versuche Dir zu erklären, dass diese Eigenschaft nicht offensichtlich ist, wenn von Modularisierung gesprochen wird, und dass man dieses unterschiedliche Verhalten nur herausfindet, nachdem man darauf hereingefallen ist oder Dutzende widersprüchlichre Aussagen analysiert hat.

                                        Ich wollte schon diesbezüglich auf Dein früheres Posting antworten, dann war Struppi schneller, und seine Antworten sind - fachlich - richtig.

                                        Was Struppi vielleicht übersieht, ich sage deswegen nur »vielleicht«, weil Du im Gegensatz zu mir Programmiererfahrung zu haben scheinst (siehe Deine Auflistung) und somit eigentlich die besseren Voraussetzungen mitbringen müsstest, Dich in eine x-beliebige, andere Programmiersprache einzuarbeiten, was ich sagen will ist, es deckt sich in der Tat mit Deinen Aussagen, dass ein so wichtiger Part wie dieses in Perl nur so oberflächig behandelt wird. Ich kenne genauso wenig wie Struppi es hat anhören lassen das Buch, von dem Du zitiert hast, weil ich mich mit O'Reillys Bestseller wie dem Lama-Buch und dem Kamel-Book beschäftigt habe.

                                        Für mich als absoluter Programmier-Unerfahrener war das Lama Buch (Einführung in Perl) sehr hilfreich gewesen (mehr als 80% assimiliert) - vom Kamelbuch (Programmieren mit Perl) habe ich dagegen nur ca. 50% kapiert. Und im Grunde ist dieses Buch unnötig, ist es doch in weiten Teilen eine 1 zu 1 Übersetzung der Perldoc.

                                        Zu dem Thema (Gültigkeitsbereich von Variablen, Namensräume, Scopes) - aber leider zu vielen andern - ist es wirklich so, dass es zu Missverständnissen kommen kann, weil die Lehrbücher nicht wirklich alle Versuche abdecken können, die ein Anfänger sich mal ausdenkt. Das ist aber immer so, der Lehrer in der Schule ist auch manchmal überrascht, auf was für Fragen die Schüler kommen. Nur dass hier keine Pädagogen die Lehrbücher geschrieben haben, sondern Programmierer, und die sind - bei allem Respekt - ziemlich weit von der Realitätswelt und dem mangelnden Abstraktsionsvermögen eines Neulings entfernt.

                                        Du kannst aber Struppi keinen Vorwurf machen, er habe nicht versucht, Dir zu helfen. Im Gegenteil hat er Dir gesagt, wie lexikalische Variablen sich verhalten - wenn es anderswo nicht richtig erklärt ist, ist es nicht seine Schuld. Siechfreds Beitrag verdient aber ein mehrfaches "fachlich hilfreich", denn er ist mehr ins Detail gegangen, als alle Tutorials oder Bücher, die ich gelesen habe.

                                        Ja... mein Statement hilft Dir am Ende sicher auch nicht weiter, aber was soll ich noch sagen? Ich bin diesbezüglich selbst noch am ausprobieren, um das Ganze zu verstehen, wenn wir beide mal soweit sind, dann sollten wir uns zusammensetzen und unser eigenes Tutorial schreiben? ;)

                                        Viele Grüße aus Frankfurt/Main,
                                        Patrick

                                        --

                                        _ - jenseits vom delirium - _
                                        [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                                        Nichts ist unmöglich? Doch!
                                        Heute schon gegökt?
                                        1. Was Struppi vielleicht übersieht, ich sage deswegen nur »vielleicht«, weil Du im Gegensatz zu mir Programmiererfahrung zu haben scheinst (siehe Deine Auflistung) und somit eigentlich die besseren Voraussetzungen mitbringen müsstest, Dich in eine x-beliebige, andere Programmiersprache einzuarbeiten, was ich sagen will ist, es deckt sich in der Tat mit Deinen Aussagen, dass ein so wichtiger Part wie dieses in Perl nur so oberflächig behandelt wird.

                                          Naja, mir würde es in dem Punkt auch nicht anders gehen, ich hätte in dem Falle (also das mir etwas merkwürdig vorkommt) in Perldoc nachgeschaut und dort wird es zumindest genauso gesagt wie wir es hier mehrmals erklärt haben, was es dann genau mit lexikalischen Variabeln auf sich hat liesse sich auch erlesen.

                                          Jede Sprache hat halt ihr Konzept, wie z.b. das erwähnte Javascript, daß sich in dem Punkt von Perl unterschiedet, da es den Scope anders definiert

                                          function test() {  
                                           var x = 0;  
                                           if(1) {  
                                            var x = 2;  
                                           }  
                                           alert(x)  
                                          }  
                                          test()  
                                          
                                          

                                          gibt 2

                                          sub test {  
                                           my $x = 0;  
                                           if(1) {  
                                            my $x = 2;  
                                           }  
                                           print $x;  
                                          }  
                                          test()
                                          

                                          gibt 0

                                          und im Prinzip tritt das Verständnisproblem ja nur auf durch die Verwendung von my (was zu empfehlen ist), welches eine Variabel nicht an ein package bindet, sondern an einen Scope und aus irgendeinem Grund, will es Connie nicht wahr haben oder nicht verstehen, ich weiß es nicht.

                                          Für mich hat diese frage bisher noch nie eine Rolle gespielt, schwieriger fand ich den umgekehrten Weg, aus einem package heraus Variabeln oder Funktionen bekannt zu machen

                                          In meinen Auge ist daher das Ursprungsbeispiel hypothetisch. Ein package sollte, um Modular zu programmieren, in separaten Dateien verwendet werden und dort sollten natürlich auch keine Variabelndeklarationen im Namensraum von main erfolgen, daher tritt dieses Problem nie auf. Das ja nur eine Folge davon ist, dass eine Variabel im Namensraum main, mit my lexikalisch wurde und daher in allen packages in der Datei die Gleiche ist. Sowas macht keiner, der ein Perlprogramm schreibt.

                                          Struppi.

                                          1. Hi

                                            schönes Beispiel, aber zwo Anmerkungen:

                                            function test() {

                                            var x = 0;
                                            if(1) {
                                              var x = 2; //[2]
                                            }
                                            alert(x)
                                            }
                                            test()

                                            
                                            > gibt 2  
                                            >   
                                            > ~~~perl
                                            
                                            sub test {  
                                            
                                            >  my $x = 0;  
                                            >  if(1) {  
                                            >   my $x = 2; # [1]  
                                            >  }  
                                            >  print $x;  
                                            > }  
                                            > test()
                                            
                                            

                                            gibt 0

                                            [1] lässt man hier das my weg, kommt auch 2 raus.

                                            [2] mich wundert warum Javascript (zumindest im FF ausprobiert) hier nicht meckert... m.E. macht es keinen Sinn "var x" mehrmals innerhalb des gleichen Geltungsbereichs anzugeben, die Console sollte hier wenigstens eine Warnung ausgeben. Oder kann jemand hier einen Nutzen entdecken?

                                            bye
                                             Kurt

                                            und im Prinzip tritt das Verständnisproblem ja nur auf durch die Verwendung von my (was zu empfehlen ist), welches eine Variabel nicht an ein package bindet, sondern an einen Scope und aus irgendeinem Grund, will es Connie nicht wahr haben oder nicht verstehen, ich weiß es nicht.

                                            Für mich hat diese frage bisher noch nie eine Rolle gespielt, schwieriger fand ich den umgekehrten Weg, aus einem package heraus Variabeln oder Funktionen bekannt zu machen

                                            In meinen Auge ist daher das Ursprungsbeispiel hypothetisch. Ein package sollte, um Modular zu programmieren, in separaten Dateien verwendet werden und dort sollten natürlich auch keine Variabelndeklarationen im Namensraum von main erfolgen, daher tritt dieses Problem nie auf. Das ja nur eine Folge davon ist, dass eine Variabel im Namensraum main, mit my lexikalisch wurde und daher in allen packages in der Datei die Gleiche ist. Sowas macht keiner, der ein Perlprogramm schreibt.

                                            Struppi.

                                            1. function test() {

                                              var x = 0;
                                              if(1) {
                                                var x = 2; //[2]
                                              }
                                              alert(x)
                                              }
                                              test()

                                              
                                              > > gibt 2  
                                              > >   
                                              > > ~~~perl
                                              
                                              sub test {  
                                              
                                              > >  my $x = 0;  
                                              > >  if(1) {  
                                              > >   my $x = 2; # [1]  
                                              > >  }  
                                              > >  print $x;  
                                              > > }  
                                              > > test()
                                              
                                              

                                              gibt 0

                                              [1] lässt man hier das my weg, kommt auch 2 raus.

                                              Genau das wollte ich Connie damit vermitteln, my greift immer in einem Scope - hier im Block {} - ohne my ist es das äußere $x.

                                              [2] mich wundert warum Javascript (zumindest im FF ausprobiert) hier nicht meckert... m.E. macht es keinen Sinn "var x" mehrmals innerhalb des gleichen Geltungsbereichs anzugeben, die Console sollte hier wenigstens eine Warnung ausgeben. Oder kann jemand hier einen Nutzen entdecken?

                                              soweit ich weiß hat das Mozilla am Anfang auch gemacht, aber ich vermute mal, das sich zuviele Webdesigner beschwert hatten.

                                              Ich finde auch das:

                                              function eventFunktion(e) {  
                                              if(!e) var e = window.event;  
                                              }  
                                              
                                              

                                              grausam, wird aber auch nicht moniert.

                                              Struppi.

                                              1. Hi

                                                [1] lässt man hier das my weg, kommt auch 2 raus.

                                                Genau das wollte ich Connie damit vermitteln, my greift immer in einem Scope - hier im Block {} - ohne my ist es das äußere $x.

                                                auch mach dich doch frei von Connies Problemen, UNSER Problem ist es Perl auf einen Nenner zu bringen. Je besser wir es erklären können umso besser für UNS und das Archiv.

                                                das die My-Variable zwar in Unter-Blocks aber nicht in Unter-Subs eindringt ist ja auch etwas was man sich klar machen muss.

                                                Auch so eine nette Falle ist ja das foreach implizit die Schleifenvariable im schleifenkörper perl "local" lokalisiert... Damian Conway fordert ja deswegen auf immer sofort my zu nehmen, also

                                                foreach my $var () {}

                                                Ich finde auch das:

                                                function eventFunktion(e) {

                                                if(!e) var e = window.event;
                                                }

                                                
                                                >   
                                                > grausam, wird aber auch nicht moniert.  
                                                  
                                                naja ich finds gut, das ist wieder etwas perlish :) Auch in perl kannst du auf die globale Variable zugreifen bevor du sie lokalisierst.  
                                                  
                                                z.B. mit folgendem Einzeiler  
                                                  
                                                local $level=$level+1;  
                                                  
                                                kann ich die Rekursionstiefe von Funktionsaufrufen sauber erfassen. Keine Ahnung wie man das in Python basteln wollte.  
                                                  
                                                Bye  
                                                 Kurt  
                                                
                                                
                                                1. das die My-Variable zwar in Unter-Blocks aber nicht in Unter-Subs eindringt ist ja auch etwas was man sich klar machen muss.

                                                  Tut sie aber:

                                                  sub test  
                                                  {  
                                                   my $x = 2;  
                                                   sub untertest {  
                                                   print $x;  
                                                   }  
                                                   untertest();  
                                                  }
                                                  

                                                  Allerdings mit einer Warnung

                                                  Auch so eine nette Falle ist ja das foreach implizit die Schleifenvariable im schleifenkörper perl "local" lokalisiert... Damian Conway fordert ja deswegen auf immer sofort my zu nehmen, also

                                                  foreach my $var () {}

                                                  ohne my bricht das skript ab, wenn du strict verwendest.

                                                  Ich finde auch das:

                                                  function eventFunktion(e) {

                                                  if(!e) var e = window.event;
                                                  }

                                                  
                                                  > >   
                                                  > > grausam, wird aber auch nicht moniert.  
                                                  >   
                                                  > naja ich finds gut, das ist wieder etwas perlish :) Auch in perl kannst du auf die globale Variable zugreifen bevor du sie lokalisierst.  
                                                    
                                                  Davon rede ich nicht, mit geht es darum dass du e nicht mit var deklarieren musst, ich halte es sogar für falsch, da e explizit deklariert ist als Platzhalter für den Parameter, ansonsten müßte man ja immer schreiben:  
                                                    
                                                  ~~~javascript
                                                  function F(p1, p2) {  
                                                  var p1;  
                                                  var p2;  
                                                  }
                                                  

                                                  Struppi.

                                                  1. Hi

                                                    das die My-Variable zwar in Unter-Blocks aber nicht in Unter-Subs eindringt ist ja auch etwas was man sich klar machen muss.

                                                    Tut sie aber:

                                                    sub test

                                                    {
                                                    my $x = 2;
                                                    sub untertest {
                                                    print $x;
                                                    }
                                                    untertest();
                                                    }

                                                    
                                                    >   
                                                    > Allerdings mit einer Warnung  
                                                    >   
                                                      
                                                      
                                                    hehe ein sub im sub :) ich meinte eher  
                                                      
                                                    ~~~perl
                                                      
                                                    $x="global";  
                                                      
                                                    sub untertest {  
                                                      print $x;  
                                                     }  
                                                      
                                                    sub test  
                                                    {  
                                                     my $x = 2;  
                                                     untertest();  
                                                    }  
                                                      
                                                    test(); # ausgabe "global"  
                                                      
                                                    
                                                    

                                                    aber danke dein Beispiel macht das scoping von my wieder klarer! :)

                                                    Die Warnung kommt m.E. weil die Garbage Collection $x vernichtet wenn kein Bezug erhalten bleibt. Man könnte sagen Perl beschwert sich dass du kein Closure gebastelt hast:

                                                      
                                                      
                                                    use warnings;  
                                                      
                                                      
                                                    sub test  
                                                    {  
                                                     my $x = 2;  
                                                     return  sub {  
                                                      print $x++,"\n";  
                                                     }  
                                                    }  
                                                      
                                                    $sub_ref=test();  
                                                    $sub_ref->(); #2  
                                                    $sub_ref->(); #3  
                                                    $sub_ref->(); #4  
                                                      
                                                    
                                                    

                                                    Bye
                                                      Kurt

                                                    1. Hi

                                                      Die Warnung kommt m.E. weil die Garbage Collection $x vernichtet wenn kein Bezug erhalten bleibt. Man könnte sagen Perl beschwert sich dass du kein Closure gebastelt hast:

                                                      Leider nicht ganz korrekt, die Warnung
                                                      Variable "$x" will not stay shared at /tmp/tst.pl line 10 (#1)

                                                      bedeutet dass die Variable $x in test() und in untertest() nach der ersten initialisierung nicht mehr identisch sind, d.h. selbst wenn ich test() nochmal aufrufe und $x anders belege wird untertest() weiterhin 2 ausgeben.

                                                      Beispiel:

                                                        
                                                      use warnings;  
                                                      sub test  
                                                      {  
                                                       my $x = shift;  
                                                       sub untertest {  
                                                       print $x++;  
                                                       }  
                                                       untertest();  
                                                      }  
                                                        
                                                        
                                                      test(1);      #1  
                                                      untertest();  #2  
                                                      untertest();  #3  
                                                      test(0);      #4  
                                                      untertest()   #5  
                                                      
                                                      

                                                      Jesus ....

                                                      bye
                                                       Kurt

                                                      1. Hallo,
                                                        ich hoffe, dass meine Frage noch ankommt.

                                                        Leider nicht ganz korrekt, die Warnung
                                                        Variable "$x" will not stay shared at /tmp/tst.pl line 10 (#1)

                                                        bedeutet dass die Variable $x in test() und in untertest() nach der ersten initialisierung nicht mehr identisch sind,

                                                        Wie ist dies zu erklären?

                                                        d.h. selbst wenn ich test() nochmal aufrufe und $x anders belege wird untertest() weiterhin 2 ausgeben.

                                                        Beispiel:

                                                        use warnings;
                                                        sub test
                                                        {
                                                        my $x = shift;
                                                        sub untertest {
                                                        print $x++;
                                                        }
                                                        untertest();
                                                        }

                                                        test(1);      #1
                                                        untertest();  #2
                                                        untertest();  #3
                                                        test(0);      #4
                                                        untertest()   #5

                                                        
                                                        >   
                                                        
                                                        
                                                        1. ich hoffe, dass meine Frage noch ankommt.

                                                          Aber sicher doch, dauert nur manchmal ;)

                                                          Wie ist dies zu erklären?

                                                          Das habe ich mal vor einiger Zeit versucht zu erklären:
                                                          http://forum.de.selfhtml.org/archiv/2006/10/t139254/#m905031

                                                          Siechfred

                                                          --
                                                          Wir vom Moderatorenteam haben keinerlei Humor, von dem wir wüssten.
                                                          1. Hi

                                                            Das habe ich mal vor einiger Zeit versucht zu erklären:
                                                            http://forum.de.selfhtml.org/archiv/2006/10/t139254/#m905031

                                                            Im Code fehlt ein Semikolon!

                                                            so funktionierts:

                                                            sub foo {
                                                              my $var = shift;

                                                            my $bar = sub {
                                                                return $var *10;
                                                              };
                                                              return &$bar();
                                                            }

                                                            print foo(1);
                                                            print foo(2);

                                                            Bye
                                                             Kurt

                                                            1. Im Code fehlt ein Semikolon!

                                                              Ich weiß, es gibt halt doch noch aufmerksame Leser, die geposteten Code auch testen ;)

                                                              Siechfred

                                                              --
                                                              Wir vom Moderatorenteam haben keinerlei Humor, von dem wir wüssten.
                                                              1. Im Code fehlt ein Semikolon!

                                                                Ich weiß, es gibt halt doch noch aufmerksame Leser, die geposteten Code auch testen ;)

                                                                wenns sonst keiner tut ...

                                                                *fg*
                                                                 Kurt

                                                        2. Hi

                                                          Wie ist dies zu erklären?

                                                          Was genau intern abläuft kann ich dir nicht sagen, aber innerhalb einer Routine dynamisch eine andere zu definieren ist komplexe "Metaprogrammierung".

                                                          Grob gesprochen: Beim zwoten durchlauf von test() wird $x mit my neu deklariert, ist also nicht mehr mit dem $x des ersten Durchlaufs identisch.(Speicherstelle).

                                                          Das sub untertest() wird aber von perl NICHT redefiniert und bleibt an dem $x des ersten Durchlaufs von test() gebunden.

                                                          Deswegen die Warnung:
                                                          Variable "$x" will not stay shared at /tmp/tst.pl line 10 (#1)

                                                          Will man aber unbedingt dynamisch neue subs erzeugen, die an privaten Variablen eines äußeren Scopes gebunden sind (sogenannte Closures), sollte man das _anonym_ tun, statt einen konkreten Namen (hier unterstest() zu geben.

                                                            
                                                          use warnings;  
                                                          use strict;  
                                                            
                                                            
                                                          sub test  
                                                          {  
                                                           my $x = shift;  
                                                           print "\n";  
                                                           return  sub {  
                                                            print $x++," ";  
                                                           }  
                                                          }  
                                                            
                                                          my $sub_ref=test(0);  #Sub-Referenz auf neue Unterroutine erhalten  
                                                          $sub_ref->();  
                                                          $sub_ref->();  
                                                          $sub_ref->();  
                                                          # 0 1 2  
                                                            
                                                          $sub_ref=test(10);    #Sub-Referenz auf neue Unterroutine erhalten  
                                                          $sub_ref->();  
                                                          &$sub_ref();  #            andere Schreibweise  
                                                          &$sub_ref;    #            andere Schreibweise  
                                                          # 10 11 12  
                                                            
                                                            
                                                            
                                                          *unterstest=test(20); # sub_ref auf Namen legen  
                                                          unterstest();  
                                                          unterstest();  
                                                          unterstest();  
                                                          # 20 21 22  
                                                            
                                                            
                                                          {  
                                                            no warnings;          # Warnungen wg redefinition abschalten  
                                                            *unterstest=test(30); # erneut sub_ref auf Namen legen  
                                                          }  
                                                          unterstest();  
                                                          unterstest();  
                                                          unterstest();  
                                                          # 30 31 32  
                                                            
                                                            
                                                          *unterstest=test(40);   # erneut sub_ref auf Namen legen  
                                                          # Warnung:  
                                                          #     Subroutine unterstest redefined at /tmp/tst.pl line 45  
                                                          unterstest();  
                                                          unterstest();  
                                                          unterstest();  
                                                          # 40 41 42  
                                                            
                                                          
                                                          

                                                          Alles klar?

                                                          Bye
                                                           Kurt

                                                          1. Hi

                                                            hier mal ein anderer Ansatz wie man local eine Unterroutine redefiniert... SCNR :)

                                                              
                                                            sub test  
                                                            {  
                                                             my $x = shift;  
                                                             print "\n";  
                                                             return  sub {  
                                                              print $x++," ";  
                                                             }  
                                                            }  
                                                              
                                                              
                                                              
                                                            *unterstest=test(10); # sub_ref auf Namen legen  
                                                            unterstest();  
                                                            unterstest();  
                                                            unterstest();  
                                                            #10 11 12  
                                                              
                                                            {  
                                                              local *unterstest=test(20); # sub_ref auf Namen legen  
                                                              unterstest();  
                                                              unterstest();  
                                                              unterstest();  
                                                              #20 21 22  
                                                            }  
                                                              
                                                            unterstest();  
                                                            unterstest();  
                                                            unterstest();  
                                                            #13 14 15  
                                                              
                                                            
                                                            

                                                            bye
                                                              Kurt

        2. Unter kopieren verstehe ich die Neuanlage der Variablen in dem Package   m i t  dem Variablenwert

          Okay, vielleicht habe ich mich da unklar ausgedrückt. Der local-Operator legt eine Sicherungskopie *des Wertes* einer globalen Variable an, damit sie in dem betroffenen Block temporär manipuliert werden kann. Endet der Block, wird die globale Variable auf ihren gesicherten Wert zurückgesetzt. Innerhalb des Blocks wird weiterhin auf die eine globale Variable zugegriffen, aber nicht auf eine echte lokale Variable! Das ist der wesentliche Unterschied: Während my eine echte lokale Variable anlegt, speichert local lediglich den *Wert* einer globalen Variable, ohne eine neue zu erzeugen.

          Ich habe nochmal nachgelesen: Laut Perl-Kochbuch, Rezept 10.13, gibt es nur drei Fälle, in denen man local verwenden muss:

          1. Man muss einer globalen Variable einen temporären Wert geben.
          2. Man will ein lokales Datei- oder Verzeichnishandle bzw. eine lokale Funktion anlegen.
          3. Man will temporär nur ein Element eines Arrays oder Hashs verändern.

          In allen anderen Fällen gilt: "my statt local". Im Übrigen: Das strict-Pragma überwacht den Dynamic Scope nicht, das allein spricht schon für gegen local, wenn man es neben den o.g. Fällen anwendet.

          Was heißt quasi-lokal? Wenn die Variable nur in dem Block gültig ist und nicht wie die mit "our" definierte Variablen auch außerhalb, ist dies doch echt lokal - oder nicht?

          Nein, siehe hierzu:
          http://perldoc.perl.org/perlsub.html#Private-Variables-via-my()
          http://perldoc.perl.org/perlsub.html#Temporary-Values-via-local()

          Ist Block ein anderer Begriff für Namensraum, wenn nein was hat der Block mit Namespace und Scope zu tun?

          Ein Block ist ein Bündel von Anweisungen, eingeschlossen durch geschweifte Klammern.

          Nach aussen und nach innen ist mir unklar.

          Siehe Antwort von Patrick.

          Siechfred

      3. Hallo Siechfred!

        Vielen Dank für die ausführlichen Erläuterungen und ich denke ja,

        Dann will ich mal versuchen, etwas Licht ins Dunkel zu bringen.

        das ist Dir gelungen.

        Ich wollte gestern schon antworten, leider hat sich mein Schnupfen verschlimmert und ich war nicht in der Lage, klar zu denken und meine Fragen zusammen zu sammeln. Hoffentlich gelingt es mir heute.

        Den Gültigkeitsbereich lexikalischer Variable meine ich bereits so gut assimiliert zu haben. Auch der Unterschied zwischen local und my dürfte soweit klar sein.

        Bei Deinem Beispiel mit dem Einlesen der Datei in $input hätte ich aber erwartet, da $/ im Block ja undef ist (habe ich mit einer Abfrage überprüft), die ganze Datei in einer Zeile wiederzufinden. Dem ist aber nicht so. Allerdings habe ich sehr wohl den Unterschied gesehen: Kommentiere ich die local-Zeile aus, wird nur die erste Zeile ausgegeben.

        Das letzte Beispiel interpretiere ich so, dass es also nicht möglich ist, eine in einem Modul wie auch immer definierte Variable, sei es als Rückgabewert einer Funktion oder einfach so definiert, vor Überschreibung zu schützen (das war meine Frage als skoorB leM im spotlight-Forum, als hier noch zu war).

        Ich hatte im Kurztutorial von Eike Grothe, eine Möglichkeit gesehen, sich die Tabelle eines Packages ausgeben zu lassen. Also nehme ich mein Beispiel aus dem spotlight-Forum wieder:

          
        use strict;  
        use warnings;  
        my $foo = 'foo';  
        print $foo; # foo  
        print $main::foo; # Keine Ausgabe?  
        
        

        und stelle hiermit fest:

          
        foreach my $v (keys %main::) { print "main> $v\n" }  
        
        

        dass »foo« sehr wohl im Package main zu finden ist: In der längeren Liste:
        .
        .
        main> UNIVERSAL::
        main> foo
        main> $
        .
        .

        Warum keine Ausgabe bei $main::foo? Ist - wie von Doron angeregt - $foo mit our deklariert, ja da wird $main::foo ausgegeben...

        Viele Grüße aus Frankfurt/Main,
        Patrick

        --

        _ - jenseits vom delirium - _
        [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
        Nichts ist unmöglich? Doch!
        Heute schon gegökt?
        1. Hi

          dass »foo« sehr wohl im Package main zu finden ist: In der längeren Liste:

          ehm ... durch dein

          print $main::foo; # Keine Ausgabe?

          hast du $foo erst in main angelegt!!!

          ich zitiere:

          Name "main::foo" used only once: possible typo at /tmp/tst.pl line 6.
          Use of uninitialized value in print at /tmp/tst.pl line 6.

          Kommentiere die Zeile aus dann verschwindet $main::foo aus der Symboltabelle.

          Thats Perl!

          Bye
           Kurt

      4. Hi Siechfred,

        Sorry aber my-Variablen haben leider nichts mit Namespaces zu tun und kommen auch nicht in die Symboltabelle, da ist alleine der Scope entscheidend.

        Dein Code geht von der irrigen Annahme aus $bar::foo_loc würde überhaupt angelegt.

        Probier mal das folgende aus:

          
        use strict;  
        my $foo = 'declared in main';  
        $\="\n";  
          
        package bar;  
        $foo .= ' and modified in bar';  
        my $foo_loc = 'my foo_loc';  
        our $foo_glob = 'local in bar but visible outside';  
        print defined $bar::foo_loc ? $bar::foo_loc : 'undef';  # undef  
          
        package main;  
        # wir wollen keinen Scriptabbruch provozieren  
        no strict 'vars';  
          
          
        print defined $foo ? $foo : 'undef';  # declared in main and modified in bar  
        print defined $bar::foo_loc ? $bar::foo_loc : 'undef';  # undef  
        print defined $foo_loc ? $foo_loc : 'undef';  # undef  
        print defined $bar::foo_glob ? $bar::foo_glob : 'undef';  # local in bar but visible outside  
          
        
        

        Hier kann man sehr schön die Auswirkungen des lexikal scopes sehen. $foo ist im Namensraum 'main' deklariert und von da an im gesamten Script sichtbar, also auch im Package bar. Die Variable $foo_loc ist via my als lokal innerhalb des Packages bar deklariert mit der Besonderheit, dass sie außerhalb von bar nicht sichtbar ist, während $foo_glob zwar auch lokal in bar ist, aber durch die Deklaration via our nach außen sichtbar ist. Um auf $foo_glob außerhalb von bar zuzugreifen, notiert man den Namensraum davor (also $bar::foo_glob). Jede Manipulation an $foo_glob, auch außerhalb von bar, hat Auswirkungen auch innerhalb von bar:

        Ciao
         Kurt

        1. Ups,

          der Code stimmte die Kommentare allerdings nicht ... am ende in main liefert

          print defined $foo_loc ? $foo_loc : 'undef';

          eben die Ausgabe "my foo_loc"

          ich korrigiers mal im Listing

          use strict;
          my $foo = 'declared in main';
          $="\n";

          package bar;
          $foo .= ' and modified in bar';
          my $foo_loc = 'my foo_loc';
          our $foo_glob = 'local in bar but visible outside';
          print defined $bar::foo_loc ? $bar::foo_loc : 'undef';  # undef

          package main;

          wir wollen keinen Scriptabbruch provozieren

          no strict 'vars';

          print defined $foo ? $foo : 'undef';  # declared in main and modified in bar
          print defined $bar::foo_loc ? $bar::foo_loc : 'undef';  # undef
          print defined $foo_loc ? $foo_loc : 'undef';  # my foo_loc    <-HIER!!!
          print defined $bar::foo_glob ? $bar::foo_glob : 'undef';  # local in bar but visible outside

            
          Bye  
           Kurt
          
        2. Sorry aber my-Variablen haben leider nichts mit Namespaces zu tun und kommen auch nicht in die Symboltabelle, da ist alleine der Scope entscheidend.

          Ja, danke für die Korrektur - war ein Denkfehler meinerseits, da ich die scratchpads (Speicherort der lexikalischen Variablen) mit den internen symbol tables (Speicherort nicht-lexikalischer Variablen) gleichgesetzt habe, obwohl ich es eigentlich besser weiß.

          Mea maxima culpa.

          Siechfred

          --
          Wir vom Moderatorenteam haben keinerlei Humor, von dem wir wüssten.
          1. scratchpads (Speicherort der lexikalischen Variablen) [...] symbol tables (Speicherort nicht-lexikalischer Variablen)

            O Mann, ich bin vielleicht besch...! Also nochmal richtig:

            • Scratchpads sind Arrays, in denen die für den betroffenen Block deklarierten my-Variablen abgelegt sind.
            • Symbol tables sind Hashes, in denen alle innerhalb eines Namensraumes deklarierten Symbole außer den via my deklarierten Variablen gespeichert sind.

            Ich geh' jetzt mit meinem Weiberhaufen auf den Rummel, so!

            Siechfred

            --
            Wir vom Moderatorenteam haben keinerlei Humor, von dem wir wüssten.
            1. Hallo Siechfred!

              Ich geh' jetzt mit meinem Weiberhaufen auf den Rummel, so!

              Du hast lauter Mädchen? Hast Du Dich von einem Kumpel von mir beraten lassen (hat auch drei Mädels)? ;)

              Viele Grüße aus Frankfurt/Main,
              Patrick

              --

              _ - jenseits vom delirium - _
              [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
              Nichts ist unmöglich? Doch!
              Heute schon gegökt?
            2. Hi

              scratchpads (Speicherort der lexikalischen Variablen) [...] symbol tables (Speicherort nicht-lexikalischer Variablen)

              O Mann, ich bin vielleicht besch...! Also nochmal richtig:

              • Scratchpads sind Arrays, in denen die für den betroffenen Block deklarierten my-Variablen abgelegt sind.
              • Symbol tables sind Hashes, in denen alle innerhalb eines Namensraumes deklarierten Symbole außer den via my deklarierten Variablen gespeichert sind.

              ich muss jetzt grübeln, warum du dich korrigierst, es ist durchaus üblich my-Variablen als lexikalische zu bezeichnen ...???

              Gruß
               Kurt

              1. ich muss jetzt grübeln, warum du dich korrigierst, es ist durchaus üblich my-Variablen als lexikalische zu bezeichnen ...???

                Ich habe irgendwo mal gelesen, dass my und our als lexikalisch bezeichnet wurden, obwohl our ja nur am Rande was mit den lexikalischen Variablen zu tun hat (schließlich sind's ja eigentlich Packagevariablen). Darum hielt ich es für betonenswert, dass die Unterscheidung nur für my-Variablen gilt.

                Einverstanden?

                Siechfred

                --
                Wir vom Moderatorenteam haben keinerlei Humor, von dem wir wüssten.
                1. Hi

                  Ich habe irgendwo mal gelesen, dass my und our als lexikalisch bezeichnet wurden, obwohl our ja nur am Rande was mit den lexikalischen Variablen zu tun hat (schließlich sind's ja eigentlich Packagevariablen). Darum hielt ich es für betonenswert, dass die Unterscheidung nur für my-Variablen gilt.

                  Einverstanden?

                  jaaa ... diese "lexical" Terminologie ist auch wirklich nervig!

                  My und Our haben AFAIK einen "lexical scope", was bedeutet das eine our-deklaration nur innerhalb seines Blockes gilt. Statt "lexical variable" - was auch in den Perl-Fehlermeldungen erscheint würd ich lieber von "privaten Variablen" reden. (halt privatbesitz des lexical scopes)

                  Ich habe selbst auch diese Tage begriffen was "our" von einer ohne "use strict" undeklarierten Packagevariablen unterscheidet.

                  Im folgenden Beispiel erstrecken sich der scope der mit our deklarierten Variablen über mehrere package- Anweisungen. Deswegen ist es wichtig zu betonen das our einen lexical scope hat, noch wichtiger wäre die Leute würden gleich defensiv klammern. Bei "use vars" hingegen ist das Verhalten wie ohne strict.

                    
                  use strict;  
                  use warnings;  
                    
                  package drei;  
                  our ($x,$y);  
                    
                  package zwo;  
                  use vars qw{$x $y };  
                    
                  package main;  
                  our ($x);  
                  use vars qw { $y };  
                  ($x,$y)=("main","main");  
                    
                  { package zwo;  
                   $y="zwo";  
                   $x="zwo";  
                  }  
                    
                  { package drei;  
                   $y="drei";  
                   $x="drei";  
                  }  
                    
                  # hier wieder package main  
                    
                    
                  $\="\n";$,=",";  
                    
                  print def($x), def($y);             #: drei,drei  
                  print def($main::x), def($main::y); #: drei,undef  
                  print def($zwo::x), def($zwo::y);   #: undef,undef  
                  print def($drei::x), def($drei::y); #: undef,drei  
                    
                    
                    
                  sub def{  
                   # value or undef  
                   if (defined $_[0]) {  
                    return $_[0];  
                   }else {  
                    return "undef" ;  
                   }  
                  }  
                    
                  
                  

                  Tschau
                    Kurt

  2. Hallo Connie,

    die kurze (grobe) Antwort ist:

    du musst unterscheiden ob es sich um lexikalische Variablen oder Symboltabellenvariablen handelt, diese werden intern total unterschiedlich verwaltet!!!

    Erstere - mit "my" definiert - gelten nur innerhalb eines Blockes d.h innerhalb umschließender {} und haben keinen Namespace. Diese dringen auch nicht in eingebettete Blocks ein. Vergleichbar mit "var" in Javascript.

    Alle anderen sind an einem Namespace gebunden, der mittels "package" angegeben wird, default ist dabei "main::".
    Deren Symboltabellen können auch mit "typeglobs" umfassend manipuliert werden.

    Die Verwirrung entsteht historisch, weil es ursprünglich nur Namespaces gab und die lexikalischen Variablen später eingeführt wurden weil man mit "local" unzufrieden war.

    "local"  (auch lokalglobal genannnt) überschreibt eine *globale* Variable (also namespace!) bis zum Ende des lokalen Blocks und restauriert sie dann wieder, dadurch dringt sie auch - im gegensatz zu my - in eingebettete Blocks/Routinen ein, da es sich nur um eine temporär überschriebene globale variable handelt.

    Zu deinem Beispiel:
    ersetze my mit our!

    (our wurde eingeführt damit strict nicht meckert)

    #!/usr/bin/perl -w

    use strict;
    print "Content-type: text/html\n\n";
    my $var1 = "main";
    print "main:$var1<br>";

    package p1;
    my $var1 = "p1";
    print "p1:$var1<br>";

    package p2;
    my $var1 = "p2";
    print "p2:$var1<br>";

    package main;
    print "main:$var1<br>";

    
    >   
      
    bye  
     Kurt  
      
    PS: Perl ist leider keine Anfängersprache, sondern ein hochgezüchteter Alleskönner.
    
    1. Hi

      Erstere - mit "my" definiert - gelten nur innerhalb eines Blockes d.h innerhalb umschließender {} und haben keinen Namespace. Diese dringen auch nicht in eingebettete Blocks ein. Vergleichbar mit "var" in Javascript.

      ähem ... tja ... mit dem unterschied das Javascript-var in subblocks eindringt:

      https://forum.selfhtml.org/?t=159309&m=1037728

      Bye
       Kurt

    2. die kurze (grobe) Antwort ist:

      Deine Mühe in Ehren, aber wir haben das hier zigmal erklärt, vor allem Siechfred:
      https://forum.selfhtml.org/?t=159309&m=1036449
      https://forum.selfhtml.org/?t=159309&m=1036859

      Beide Postings erklären sehr sehr viel und zusätzlich gibt es noch Klasse Links. Aber Connie will das einfach nicht verstehen.

      https://forum.selfhtml.org/?t=159309&m=1037596 und folgende

      PS: Perl ist leider keine Anfängersprache, sondern ein hochgezüchteter Alleskönner.

      Connie ist eher ein Alleskönner, ich denke das Problem ist, dass das Konzept so in anderen Programmiersprachen nicht existiert. Namensräume sind getrennte Bereiche die nichts miteinander zu tun haben und lexikalische Variablen scheint es auch nur in Perl zu geben.

      Doch Connie will davon nichts Wissen und hält es für einen persönlichen Angriff das diese existieren und damit das Konzept der Namensräume zerstören, das aber in Perl nur eine untergeordnete Rolle spielt (in erster Linie kommen sie zum tragen bei der Verwendung von Modulen, die aber dadurch das sie i.d.R. in verschiedenen Dateien sind eben wie Namensräume wirken können).

      Struppi.

      1. Hi Struppi,

        Connies Agressionen sollte man ignorieren

        Im Archiv sollte einfach für alle knapp und deutlich gesagt werden:

        *** my definiert keine Packagevariablen. ***

        Sichfreds Erklärung führt m.E. zu weit. Um mit Perl frustarm zurechtzukommen braucht man einfache Regeln und Kenntnis der Historie.

        1. Am Anfang gabs nur globale Variablen.
        2. Dann kamen Namensräume durch Packages und  "local", bei dem Packagevariablen temporär überschrieben wurden.
        3. Und dann wollte man Lokalisierungs-Konzepte wie "var" aus JS auf Perl abbilden OHNE globale Variablen zu manipulieren und führte "my" ein, dass halt _keine_ Packagevariable definiert, aber einen "ähnlichen" Geltungsbereich wie local hat.

        Fast alle Gurus ärgern sich übrigens heute, dass sie damals "local" so irreführend benannt haben.

        Viele mächtige Verfahren aus der OOP, der Closures und AUOLOAD-Mechanismen in Perl sind ohne diese Feinheiten nicht verständlich.

        Bye
         Kurt

      2. Hallo!

        Beide Postings erklären sehr sehr viel und zusätzlich gibt es noch Klasse Links. Aber Connie will das einfach nicht verstehen.

        Wahrscheinlich weil sehr vieles unlogisch ist (siehe local ^ lokal aber dafür my (so quasi-lokal)).
        Anders kann man als Außenstehender und Perl-Laie die Diskussion nicht interpretieren.

        ... und Unlogik ist nun mal nicht logisch zu erklären.

        1. Zitat:

          Every programming language has a philosophy, and these days most of these philosophies have to do with the way the names of variables are managed. Details of which variables are visible to which parts of the program, and what names mean what, and when, are of prime importance. The details vary from somewhat baroque, in languages like Lisp, to extremely baroque, in languages like C++. Perl unfortunately, falls somewhere towards the rococo end of this scale.

          The problem with Perl isn't that it has no clearly-defined system of name management, but rather that it two systems, both working at once. Here's the Big Secret about Perl variables that most people learn too late: Perl has two completely separate, independent sets of variables. One is left over from Perl 4, and the other is new. The two sets of variables are called package variables' and lexical variables', and they have nothing to do with each other.

          1. Hi

            The problem with Perl isn't that it has no clearly-defined system of name management, but rather that it two systems, both working at once. Here's the Big Secret about Perl variables that most people learn too late: Perl has two completely separate, independent sets of variables. One is left over from Perl 4, and the other is new. The two sets of variables are called package variables' and lexical variables', and they have nothing to do with each other.

            schönes Zitat! :)

            Tja so ist das halt wenn eine Sprache alles können soll, in Perl6 sollen jetzt auch etliche Haskell-Konstrukte integriert werden, ein langer weg für ne Ersatzsprache für bash, sed und awk.

            Das ist so als ob man das Pentagon über Jahrhunderte mit Anbauten erweitert hätte... in der Mitte Wigwams, darum ein Pueblo, darum ein französisches Fort, dann klassizistische Colonaden, umgeben von 5-eckigen Stahlbeton in den gerade Laserkanonen eingebaut werden sollen.

            Bye
             Kurt

            PS: Der dazugehörige Artikel "Coping with Scoping" http://perl.plover.com/FAQs/Namespaces.html
            kann nicht oft genug verlinkt werden, hier werden wirklich alle Fragen beantwortet, sogar woher lexikalische Variablen ihren dusligen Namen haben.

            Zusammen mit "Seven Useful Uses of local" für Experten
            http://perl.plover.com/local.html

            "Revised rule of when to use my and when to use local:

            1. (Beginners and intermediate programmers.) Always use my; never use local unless you get an error when you try to use my.

            2. (Experts only.) Experts don't need me to tell them what the real rules are."

        2. Hi

          Wahrscheinlich weil sehr vieles unlogisch ist (siehe local ^ lokal aber dafür my (so quasi-lokal)).
          Anders kann man als Außenstehender und Perl-Laie die Diskussion nicht interpretieren.

          Perl ist nicht unlogisch sondern bestenfalls überfrachtet, weil es alles können will und die historische Terminologie nicht immer aufwärtskompatibel ist. ("local" hieße zb besser "save")

          Also man merke.

          1. Private Variablen werden mit "my" deklariert.

          2. Ansonsten sind es öffentliche Packagevariablen, und die sollten mit "our" deklariert werden.

          3. "local" betrifft nur das Laufzeitverhalten von Packagevariablen und sollte nur in begründeten Einzelfällen benutzt werden.

          4. Der Gültigkeitsbereich aller Deklarationen hängt vom Blockscope ab.

          5. Mit anderen Worten: Wer zu faul ist mit {} zu Klammern und My, Our und Package bunt mischt braucht sich, LOGISCHERWEISE, nicht zu wundern, wenns unübersichtlich wird.

          Wenn also jemand meint Javascript ist logischer, dann sollte er auch keine Packagevariablen nutzen, denn mit dem privaten "my" lässt sich das Verhalten von JS komplett abbilden.

          Bye
           Kurt

  3. Für alle Interessierten Mitleser:

    Ich habe, einer Anregung in diesem Thread folgend, versucht, das Ergebnis der Diskussion auch in Anlehnung an das mehrfach verlinkte "Coping with Scoping" zusammenzufassen:

    http://test.anaboe.net/namespace.html

    Kritik, Ergänzungen und Anregungen sind willkommen, evtl. wird das Ganze ja auch Bestandteil einer künftigen SELFHTML-Version, wer weiß.

    Siechfred

    --
    Wir vom Moderatorenteam haben keinerlei Humor, von dem wir wüssten.
    1. Hi Siechfred,

      ich kann leider momentan nicht viel Zeit investieren, (jetzt wo ich denke es  begriffen zu haben ;), aber ich denke du priorisierst falsch.

      Ein Anfänger sollte erst "my" und "our" begriffen haben, bevor er anfängt mehrere "package" in einem File oder "local" zu benutzen. Außerdem brauchst du "our" oder "use vars" wenn du unter "use strict" Packagevariablen nutzen willst. Die Symboltabelle braucht ein Anfänger erst zuletzt kennenzulernen.

      Auch "global" ist etwas missverständlich...folgendes Beispiel zeigt dass man mit "my" sehr wohl (File-)globale Variablen deklarieren kann, wenn der Gültigkeitsbereich/Scope auch das ganze File umfasst (hier $my1 und $my2). Die Unterscheidung zwischen privat und öffentlich ist m.E. die entscheidende. Die $my sind jetzt fürs File privat (!), die anderen könnte ich aber auch aus anderen Files manipulieren, weil öffentlich.

        
      use strict;  
        
      ($\,$,)=("\n",",");# Newline und Komma bei prints  
        
      use vars qw($vars1 $vars3);  
        
      my $my1="my1";  
      my $my3;  
        
      our $our1="our1";  
      our $our3;  
        
      $vars1="vars1";  
        
        
        
      sub print_globals {  
       print $my1,$my2,$my3;  
       print $our1,$our2,$our3;  
       print $vars1,$vars2,$vars3;  
        
      }  
        
      my $my2="my2";  
      $my3="my3";  
        
      our $our2="our2";  
      $our3="our3";  
        
      use vars qw($vars2);  
        
      $vars2="vars2";  
      $vars3="vars3";  
        
        
      print_globals();  
        
      # Ausgabe ohne use strict  
      #: my1,,my3  
      #: our1,our2,our3  
      #: vars1,vars2,vars3  
        
      # Ausgabe mit use strict  
      # Global symbol "$my2" requires explicit package name at /tmp/tst.pl line 17.  
      # Global symbol "$our2" requires explicit package name at /tmp/tst.pl line 18.  
      # Global symbol "$vars2" requires explicit package name at /tmp/tst.pl line 19.  
        
      
      

      Gruß
       Kurt

      1. Ein Anfänger sollte erst "my" und "our" begriffen haben, bevor er anfängt mehrere "package" in einem File oder "local" zu benutzen.

        Bei local stimmt ich dir zu, aber mehrere packages in einem File sind nicht ratsam. Ein package soll ja dazu dienen Modular zu arbeiten, dafür gibt es dann noch diverse andere Funktionen, vor allem use mit dem du solche Module einbinden kannst, aber nur wenn das package und die Datei gleich heißen (die Datei mit der Endung .pm), hast du mehrere packages in einem Modul hängen diese entweder zusammen (und nutzen dann auch evtl. gleiche Variabeln) oder dein ansatz ist falsch.

        Außerdem brauchst du "our" oder "use vars" wenn du unter "use strict" Packagevariablen nutzen willst.

        use var sollte vermieden werden.

        Auch "global" ist etwas missverständlich...folgendes Beispiel zeigt dass man mit "my" sehr wohl (File-)globale Variablen deklarieren kann,

        Mit my deklarierte Variabeln sind immer im ganzen File global wenn sie nicht in einem Block deklariert sind.

        use vars qw($vars1 $vars3);

        Dafür solltest du our verwenden.

        Ausgabe mit use strict

        Global symbol "$my2" requires explicit package name at /tmp/tst.pl line 17.

        Global symbol "$our2" requires explicit package name at /tmp/tst.pl line 18.

        Global symbol "$vars2" requires explicit package name at /tmp/tst.pl line 19.

        Wenn du die deklaration des Subs hinter der Variabelndeklaration plazierst, dann läuft das auch unter strict.

        und nochmal, globale Variabeln sind sehr sparsam zu verwenden, am besten zu vermeiden. Es gibt bessere Mechanismen

        Struppi.

        1. Hi

          Ein Anfänger sollte erst "my" und "our" begriffen haben, bevor er anfängt mehrere "package" in einem File oder "local" zu benutzen.

          Bei local stimmt ich dir zu, aber mehrere packages in einem File sind nicht ratsam.

          Bei OOP schon, man sollte halt die packages in Blöcke klammern!!!

          Aber wir sind uns einig dass man sich bei Deklarationen auf my und our beschränken sollte.

          Außerdem brauchst du "our" oder "use vars" wenn du unter "use strict" Packagevariablen nutzen willst.

          use var sollte vermieden werden.

          schon klar, aber es sollte auch klar sein warum: weil "our" den gleichen Gültigkeitbereich hat wie "my" d.h. Blockscopes respektiert. "use vars" gilt fürs ganze Package und ignoriert die Klammerungsebenen der Blocks.

          Auch "global" ist etwas missverständlich...folgendes Beispiel zeigt dass man mit "my" sehr wohl (File-)globale Variablen deklarieren kann,

          Mit my deklarierte Variabeln sind immer im ganzen File global wenn sie nicht in einem Block deklariert sind.

          Das ist ja klar! Schau dir die Antwort von Siechfred an, der begriff "global" sollte erstmal vermieden werden. Privat vs. Öffentlich sowie Blockbasierter Geltungsbereich (Blockscope) bringts auf den richtigen Nenner.

          use vars qw($vars1 $vars3);

          Dafür solltest du our verwenden.

          tatsächlich? :)

          Ausgabe mit use strict

          Global symbol "$my2" requires explicit package name at /tmp/tst.pl line 17.

          Global symbol "$our2" requires explicit package name at /tmp/tst.pl line 18.

          Global symbol "$vars2" requires explicit package name at /tmp/tst.pl line 19.

          Wenn du die deklaration des Subs hinter der Variabelndeklaration plazierst, dann läuft das auch unter strict.

          Schön das du meine Demo zu interpretieren verstehst. :)

          Bye Kurt

          1. Bei OOP schon, man sollte halt die packages in Blöcke klammern!!!

            Nein gerade bei OOP sollte man eben nicht mehrere Objekte in eine Datei packen, in Ausnamhefällen mal ein kleines (Hilfs)Objekt.

            Wenn du die deklaration des Subs hinter der Variabelndeklaration plazierst, dann läuft das auch unter strict.

            Schön das du meine Demo zu interpretieren verstehst. :)

            Naja, ich interpretiere das als falsches Demo, weil es einen anderen Efekt zeigt als es suggeriert, es sieht nämlich so aus als ob du keine lexikalischen Variabeln in subs verwenden kannst, wenn man use strict verwendet, was aber falsch ist.

            Wir diskutieren hier ja seit Tagen um Phänomene, die so gar nicht auftauchen sollten. Mehrere packages zumal noch im Hauptskript sind nicht sinnvoll, Funktionsdeklarationen werden üblicherweise hinter dem Hauptcode gestellt.

            Wie schon gesagt ich hab mich seit ich in Perl programmiere noch nie mit dem Thema so auseinander gesetzt, da die Probleme bei mir noch nie aufgetaucht sind.

            Bei einem halbwegs sauberen Stil stellen sich die ganzen Fragen gar nicht.

            Struppi.

            1. Sicht des Anfängers:

              Wir diskutieren hier ja seit Tagen um Phänomene, die so gar nicht auftauchen sollten. Mehrere packages zumal noch im Hauptskript sind nicht sinnvoll, Funktionsdeklarationen werden üblicherweise hinter dem Hauptcode gestellt.

              Du schreibst üblicherweise - aber wo steht diese Empfehlung bzw. wo steht, dass es andersherum verboten ist? Oder warum kommt keine Warnung (bereits zum Zeitpunkt der Interpretation des Quellcodes)?
              Gerade in den Erläuterungen der package Variablen werden immer mehrere packages im Programm verwendet, und es steht nirgendwo: "Nur zur Demo, im richtigen Leben nie mehrere packages in einer Datei (im Hauptscript)".

              Wie schon gesagt ich hab mich seit ich in Perl programmiere noch nie mit dem Thema so auseinander gesetzt, da die Probleme bei mir noch nie aufgetaucht sind.

              Bei Dir nicht, aber bei Anfängern und für die soll ja eine Beschreibung dienen.
              Für erfahrene PERLer ist natürlich keine großartige Beschreibung mehr nötig.

              1. Wir diskutieren hier ja seit Tagen um Phänomene, die so gar nicht auftauchen sollten. Mehrere packages zumal noch im Hauptskript sind nicht sinnvoll, Funktionsdeklarationen werden üblicherweise hinter dem Hauptcode gestellt.
                Du schreibst üblicherweise - aber wo steht diese Empfehlung bzw. wo steht, dass es andersherum verboten ist? Oder warum kommt keine Warnung (bereits zum Zeitpunkt der Interpretation des Quellcodes)?

                Es ist nicht verboten. Aber du hast recht, es ist schwer etwas über den Sinn von packages zu finden.

                Gerade in den Erläuterungen der package Variablen werden immer mehrere packages im Programm verwendet, und es steht nirgendwo: "Nur zur Demo, im richtigen Leben nie mehrere packages in einer Datei (im Hauptscript)".

                Du meinst die Erläuterung in selfhtml? Da hast du auf jeden Fall recht, das sollte da stehen. dort wird nur erklärt was ein Namesnraum ist, aber die Frage ist was soll man mit packages anfangen, wozu sollen "Namespaces" dienen?

                Wie schon gesagt ich hab mich seit ich in Perl programmiere noch nie mit dem Thema so auseinander gesetzt, da die Probleme bei mir noch nie aufgetaucht sind.
                Bei Dir nicht, aber bei Anfängern und für die soll ja eine Beschreibung dienen.
                Für erfahrene PERLer ist natürlich keine großartige Beschreibung mehr nötig.

                Wie schon gesagt ich wußte bis vor kurzem auch die Details nicht, daher fand ich die Diskussion und die Erläuterungen von Siechfred interessant. Aber ich bin auch als Anfänger nicht auf die Idee gekommen mehrere packages im Hauptmodul zu definieren.

                Struppi.

            2. Hi

              Nein gerade bei OOP sollte man eben nicht mehrere Objekte in eine Datei packen, in Ausnamhefällen mal ein kleines (Hilfs)Objekt.

              TIMTOWTDI

              "The same package declaration can be present in multiple files. Or multiple packages can be declared in one file. By convention, a package is usually assigned its own file and named package.pm or package.pl. Files with the suffix .pm are called Perl modules, and packages inside files with the suffix .pl are usually referred to as libraries."

              Advanced Perl Programming: 6.2 Packages and Files

              Ich nutze problemlos größere Klassenlibraries in einem File und habe auch einige solche Beispiele von Conway und Schwartz gesehen.

              Naja, ich interpretiere das als falsches Demo, weil es einen anderen Efekt zeigt als es suggeriert, es sieht nämlich so aus als ob du keine lexikalischen Variabeln in subs verwenden kannst, wenn man use strict verwendet, was aber falsch ist.

              Gut ich wollte auch demonstrieren,  dass es beim scope auch auf die Reihenfolge ankommt, war vielleicht ein überfrachtetes Demo...

              Strictness ändert nichts an der Variablenbelegung, sondern erzwingt nur vorherige Deklaration.

              Bei einem halbwegs sauberen Stil stellen sich die ganzen Fragen gar nicht.

              Welcher ist der saubere Stil in Perl?
              Woher nimmst du die Gewissheit ihn zu kennen?
              Wieso meinst du alle Möglichkeiten auszunutzen?

              Gruß
               Kurt

              1. Nein gerade bei OOP sollte man eben nicht mehrere Objekte in eine Datei packen, in Ausnamhefällen mal ein kleines (Hilfs)Objekt.

                TIMTOWTDI

                "The same package declaration can be present in multiple files. Or multiple packages can be declared in one file. By convention, a package is usually assigned its own file and named package.pm or package.pl. Files with the suffix .pm are called Perl modules, and packages inside files with the suffix .pl are usually referred to as libraries."

                Advanced Perl Programming: 6.2 Packages and Files

                Ich nutze problemlos größere Klassenlibraries in einem File und habe auch einige solche Beispiele von Conway und Schwartz gesehen.

                Libaries sind keine Objekte. Wie gesagt ich bestreite nicht das es geht, aber in dem Absatz wird schön beschrieben wie es sein sollte.
                Objekte => sollte ein package sein
                Libaries => können auch mehrere packages sein

                Gut ich wollte auch demonstrieren,  dass es beim scope auch auf die Reihenfolge ankommt, ...

                Das Beispiel hat etwas mit der Kompilierung zu tun, nichts mit dem Scope der wird in diesem Fall noch gar nicht geprüft

                Strictness ändert nichts an der Variablenbelegung, sondern erzwingt nur vorherige Deklaration.

                Bevor sie im Quelltext, der Übersetzt wird, verwendet wird

                Bei einem halbwegs sauberen Stil stellen sich die ganzen Fragen gar nicht.

                Welcher ist der saubere Stil in Perl?

                Das meiste dürfte hier beschrieben werden
                http://perldoc.perl.org/perlstyle.html
                http://perldoc.perl.org/perlobj.html
                http://perldoc.perl.org/perltoot.html
                http://perldoc.perl.org/perltooc.html
                http://perldoc.perl.org/perlbot.html

                Woher nimmst du die Gewissheit ihn zu kennen?
                Wieso meinst du alle Möglichkeiten auszunutzen?

                Mein ich das?

                Ich gehe nur den Tipps und Ratschlägen in den oben gennanten Docs nach und damit sind mir die hier genannten Probleme so noch nicht über den Weg gelaufen. Ich hatte durchaus schon Probleme mit packages und der Gültigkeit von Variabeln, aber immer im Zusammenhang mit unsauberer Programmierung (man ist ja auch Faul) und den daraus resultierenden Folgen.

                Struppi.

                1. Hi

                  Libaries sind keine Objekte. Wie gesagt ich bestreite nicht das es geht, aber in dem Absatz wird schön beschrieben wie es sein sollte.
                  Objekte => sollte ein package sein
                  Libaries => können auch mehrere packages sein

                  In dem Absatz ist gar nicht von Objekten die Rede.

                  Gut ich wollte auch demonstrieren,  dass es beim scope auch auf die Reihenfolge ankommt, ...

                  Das Beispiel hat etwas mit der Kompilierung zu tun, nichts mit dem Scope der wird in diesem Fall noch gar nicht geprüft

                  Natürlich! ...was verstehst du unter Scope!

                  Es geht um den Geltungsbereich der Deklaration.
                  Daraus ergibt sich der Speicherort der deklarierten Variablen.
                  Der Speicherort regelt was wir als global und lokal empfinden.

                  Und all das ergibt sich während der Kompilierung.

                  Alleine local wird "dynamic scoped" genannt, hängt aber vom Geltungsbereich einer globalen Variable ab, deren Speivherort während der Komilierung festgelegt wird.

                  Das meiste dürfte hier beschrieben werden
                  http://perldoc.perl.org/perltoot.html

                  Hier steht das das Modulfile nach der Klasse benannt
                  werden _sollte_, aber kein Modul-Import stattfindet (es also keine technischen Gründe dafür gibt)

                  http://perldoc.perl.org/perltooc.html

                  "There are sound reasons why we usually suggest a one-to-one mapping between files and packages and modules and classes. You don't have to stick to this suggestion if you really know what you're doing, but you're apt to confuse yourself otherwise, especially at first."

                  Die Diskussion hier geht vorwiegend um die Realisierung von Klassenvariablen (Package oder Privat) und ihren Geltungsbereich (file-scoped). Inhaltlich führt es diesen Thread nahtlos thematisch weiter, weil ohne die feinen Unterschiede von my und our würd man's nicht verstehen.

                  Allerdings braucht eine Klassenvariable nicht "filescoped" zu sein wenn man das Package in einen Block klammert.

                  Ich habe auch seitenweise solcher Beispiele in Damian Conway Büchern vorliegen.

                  Aber geschenkt ... beenden wir die Diskussion ich denke wir haben alle dazugelernt und jetzt stagniert es.

                  Bye
                   Kurt

                  1. In dem Absatz ist gar nicht von Objekten die Rede.

                    Ich hab von Objekten geredet und du hast mir den Absatz gezeigt.

                    Aber geschenkt ... beenden wir die Diskussion ich denke wir haben alle dazugelernt und jetzt stagniert es.

                    Ich weiß auch gar nicht worauf du hinaus willst.
                    Meine Aussage, das wenn man sauber programmiert, sich mit solchen Fragen nicht auseinadersetzen muss, ist meine Erfahrung. Auf Nachfragen hab ich dir gezeigt was ich gelesen habe. Da kannst du noch tagelang dran rummäkeln, es ist einfach so.

                    Wenn du es gerne anders machen willst, bitte, warum nicht. Ich finde es nur seltsam wenn ich das Objekt Yxz benutzen will aber das Modul Abc laden muss und globale Variabeln sind sowieso kein Thema.

                    Aber ich bin kein guter Programmierer und bin daher immer versucht möglichst viele Konventionen einzuhalten um nicht in Fallen zu laufen, die ich später nicht mehr überschaue.

                    Struppi.

      2. Hey Kurt.

        Erstmal Danke für's Feedback.

        Ein Anfänger sollte erst "my" und "our" begriffen haben, bevor er anfängt mehrere "package" in einem File oder "local" zu benutzen.

        Ein Perl-Anfänger muss sich m.E. folgende Grundregeln verinnerlichen:

        ad 1:
        Es gibt in Perl zwei völlig verschiedene Variablen-Konzeptionen: Packagevariablen und lexikalische Variablen.

        ad 2:
        Das Vermischen beider Konzepte birgt Gefahren, denen sich ein Anfänger nicht aussetzen sollte.

        ad 3:
        Ein Anfänger sollte stets den Lexical Scope verwenden und sein Tun vom strict-Pragma überwachen lassen.

        Außerdem brauchst du "our" oder "use vars" wenn du unter "use strict" Packagevariablen nutzen willst. Die Symboltabelle braucht ein Anfänger erst zuletzt kennenzulernen.

        "our" ist genauso wie Packagevariablen eine potentielle Fehlerquelle (schau Dir mein letztes Beispiel an) und sollte deshalb am Anfang vermieden werden. Und das vars-Pragma ist als überholt gekennzeichnet und sollte daher gerade Anfängern nicht mehr angetragen werden.

        Auch "global" ist etwas missverständlich.

        In welchem Zusammenhang? Unter "global" verstehe ich "öffentlich", und lexikalische Variablen können im technischen Sinne nicht öffentlich sein, sondern nur privat.

        folgendes Beispiel zeigt dass man mit "my" sehr wohl (File-)globale Variablen deklarieren kann, wenn der Gültigkeitsbereich/Scope auch das ganze File umfasst (hier $my1 und $my2).

        Das ist dann aber eben nicht global im Sinne von öffentlich (nach außen sichtbar), sondern nachwievor privat. Im Lexical Scope hat ein Script keine Fenster, im Global Scope schon :)

        Siechfred

        --
        Wir vom Moderatorenteam haben keinerlei Humor, von dem wir wüssten.
        1. Hi Siechfred
          Meine volle Zustimmung zu Deinen Ausführungen!
          Thomas

        2. Hi

          Auch "global" ist etwas missverständlich.

          »»

          In welchem Zusammenhang? Unter "global" verstehe ich "öffentlich", und lexikalische Variablen können im technischen Sinne nicht öffentlich sein, sondern nur privat.

          Es ist "etwas" missverständlich für Leute die auf Spachen gelernt haben, die nur 2 Gliederungsebenen kennen, also "Hauptprogramm" und "Unterprogramm". Für die sind "globale" Variablen Hauptprogramsvariablen, die man in einer Subroutine benutzen kann ohne sie vorher als Parameter beim Aufruf übergeben zu haben.

          Beliebig viele Gliederungsebenen mit privaten Variablen passt da aber schwer ins Konzept...

          Hier mal ein Beispiel wie man die gleiche Aufgabe mit Packages und Closures (gekapselte private Variablen) löst.

          Der entscheidende Unterschied ist, (neben der Eleganz) das man die Packagevariablen nicht sauber vor äußerem Zugriff schützen kann, weil öffentlich. Bei der Closurevariante kann ich AUSSCHLIESSLICH über die Routine init() auf die Variablen zugreifen.

          Es hat schon seinen Grund warum die Deklarationen "my" und "our" heißen.

            
          use strict;  
            
          #------------------------------------------------------  
          #        hier mit Closure privater Variablen  
          #------------------------------------------------------  
            
            
          { my $max;  
            my $i=0;  
            
            sub init {  
             ($max)=@_;  
             $i=0;  
            }  
            sub step {  
             if (++$i > $max) { $i=0 };  
             return $i;  
            }  
          }  
            
            
          init(3);  
          while (my $s=step()) {print $s;}            #: 1 2 3  
            
          init(2);  
          while (my $s=step()) {print $s;}            #: 1 2  
            
            
            
            
            
            
            
          #------------------------------------------------------  
          #  hier mit Package  
          #------------------------------------------------------  
            
          { package cycle;  
            our $max; # Packagevariablen nur in diesem Scope deklarieren  
            our $i=0;  
            
            sub init {  
             ($max)=@_;  
             $i=0;  
            }  
            
            sub step {  
             if (++$i > $max) { $i=0 };  
             return $i;  
            }  
            
            sub export {  
             # exportiere step() init() von cycle:: nach main::  
             *main::step=\&step;  
             *main::init=\&init;  
            }  
          }  
            
            
            
            
            
          # zugriff auf Packageroutinen  
          cycle::init(3);  
          while (my $s=cycle::step()) {print $s;}               #: 1 2 3  
            
          # kann die Variablen aber auch direkt  manipulieren, weil ffentlich  
          $cycle::max=2;  
          $cycle::i=0;  
          while (my $s=cycle::step()) {print $s;}               #: 1 2  
            
          # oder erst Packageroutinen importieren um Schreibarbeit zu sparen  
          # zugriff auf Packageroutinen  
          cycle::export;  
          init(4);  
          while (my $s=step()) {print $s;}                      #: 1 2 3 4  
            
          
          

          Gruß
          Kurt