Knut (nicht der Eisbär): externe Daten einbinden

Hi,
ich habe ein Hash, das ich in mehreren Perl-Programmen verwenden will.
Wie muss ich das Hash definieren (Dateityp), und wie kann ich es in die Perl-Programme einbinden?
Danke Euch
Knut

  1. Wie muss ich das Hash definieren (Dateityp), und wie kann ich es in die Perl-Programme einbinden?

    Mit den Funktionen fürs Dateisystem?
    http://perldoc.perl.org/
    http://perldoc.perl.org/functions/open.html
    http://perldoc.perl.org/functions/print.html
    http://perldoc.perl.org/functions/read.html
    http://perldoc.perl.org/functions/close.html

    1. Mit den Funktionen fürs Dateisystem?

      Ach Du lieber Schwan, da muß ich ja noch tiefer in Perl eintauchen?
      Ich hatte gehofft, es gebe so etwas einfaches wie in vielen anderen Sprachen (copy, include, ....)!

      1. Hi,

        Ich hatte gehofft, es gebe so etwas einfaches wie in vielen anderen Sprachen (copy, include, ....)!

        in Perl gibt es use.

        mfG,
        steckl

        1. Hi,

          in Perl gibt es use.

          Habe es damit probiert und probiert und probiert, aber ich komme nicht zurecht.
          Dabei ist es bestimmt ein trivialer Fehler.
          In der nachfolgenden 1. Variante enthält $erg den korrekten Wert aus dem Hash.
          In der 2. Variante nach Auslagerung des Hash, bleibt $erg unbesetzt.

          Variante 1:

            
          #!/usr/bin/perl -w  
          use strict;  
          use CGI;  
          use CGI::Carp qw(fatalsToBrowser);  
            
          ......  
            
          my $s = "zb";  
          my $erg;  
          my %Zuordnung = (  
                             "ar"     => "autoradio",  
                             "zb"     => "zahnbürste",  
                             "xy"     => "aaaaaa"  
                            );  
            
          $erg = $Zuordnung{"$s"};  
          
          

          Variante 2:

            
          #!/usr/bin/perl -w  
          use strict;  
          use CGI;  
          use CGI::Carp qw(fatalsToBrowser);  
            
          ......  
          my %Zuordnung;  
          use Zuordnung;  
          my $s = "zb";  
          my $erg;  
            
          $erg = $Zuordnung{"$s"};  
          
          

          Programm Zuordnung.pm (im gleichen Verzeichnis wie zugehöriges Hauptprogramm):

            
          package Zuordnung;  
          use strict;  
          my %Zuordnung = (  
                             "ar"     => "autoradio",  
                             "zb"     => "zahnbürste",  
                             "xy"     => "aaaaaa"  
                            );  
          
          
          1. Dabei ist es bestimmt ein trivialer Fehler.

            Nö, ist es nicht.

            Variante 2:

            #!/usr/bin/perl -w
            use strict;
            use CGI;
            use CGI::Carp qw(fatalsToBrowser);

            ......
            my %Zuordnung;
            use Zuordnung;
            my $s = "zb";
            my $erg;

            $erg = $Zuordnung{"$s"};

            
            >   
            > Programm Zuordnung.pm (im gleichen Verzeichnis wie zugehöriges Hauptprogramm):  
            >   
            > ~~~perl
              
            
            > package Zuordnung;  
            > use strict;  
            > my %Zuordnung = (  
            >                    "ar"     => "autoradio",  
            >                    "zb"     => "zahnbürste",  
            >                    "xy"     => "aaaaaa"  
            >                   );  
            > 
            
            

            Wenn du mit packages arbeiten willst muss du den Hash exportieren oder du kannst ihn auch überall mit our deklarieren.

            Struppi.

            --
            Javascript ist toll (Perl auch!)
            1. Wenn du mit packages arbeiten willst muss du den Hash exportieren oder du kannst ihn auch überall mit our deklarieren.

              Oha, das klingt ja kompliziert (für ein Greenhorn).
              Und jetzt noch weitere Vorschläge von batooh.

              Also

              • Variante "King^Lully": open/read/print/close
              • Variante "Struppi":    do
              • Variante "steckl":     use
                   mit notwendigen Ergänzungen von "struppi": Export oder our
              • Varianten von batooh:  require  (do, use)
                Welches ist wohl der empfehlenswerte Weg für mein Problem?
              1. Hallo.

                Welches ist wohl der empfehlenswerte Weg für mein Problem?

                Also, wenn du vor hast, nur das eine Hash unter den Programmen zu teilen, und es möglichst einfach gehen soll, würde ich dir die Variante mit der do-Funktion empfehlen.

                Möchtest du später evtl. noch weitere Skalare, Arrays oder Hashs zwischen den Programmen teilen, und soll dies ohne großen Aufwand erfolgen, sind require und use deine Freunde. Der Nachteil von require ist hierbei, dass du jeweils den Namensraum der Variable mit angeben musst. Bei der Verwendung von use im Verbindung mit Exporter fällt dieser Nachteil weg.

                Zusammenfassend kann also folgendes festgehalten werden:

                • do ist eine einfache und schnelle Lösung, die aber keine Erweiterungsmöglichkeiten bietet.

                • require ist etwas aufwändiger als do, kann aber einfacher erweitert werden, Nachteil sind die längeren Variablennamen wegen des eigenen Namensraums.

                • use ist die aufwändigste Lösung, sehr gut erweiterbar und sieht durch den Export der Variablen auch noch hübsch aus.

                Kurz: do, wenn es schnell gehen soll, use, wenn es gut werden soll und require, wenn es irgendwas dazwischen sein soll.

                Schöne Grüße.

                1. Hallo,
                  Euch allen vielen Dank.
                  Mit Hilfe Eurer Informationen habe ich die use-Version gewählt und sie läuft (obwohl ich nicht verstehe, warum  -  ich betrachte halt das Ganze als Black-Box)
                  Schönen Tag noch
                  Knut (nicht der Eisbär)

                  1. Mit Hilfe Eurer Informationen habe ich die use-Version gewählt und sie läuft (obwohl ich nicht verstehe, warum  -  ich betrachte halt das Ganze als Black-Box)

                    ohne Exporter? Dann machst du was falsch.

                    Struppi.

                    --
                    Javascript ist toll (Perl auch!)
                    1. Hallo,

                      ohne Exporter? Dann machst du was falsch.

                      Exporter ist dabei:

                      package hash;
                      use strict;
                      use warnings;
                      use Exporter;
                      our @ISA = qw(Exporter);
                      our @EXPORT = qw(%hash);
                      our %hash = ( keyA => 'valueA',
                                    keyB => 'valueB',
                                    keyC => 'valueC',
                                   );
                      1;

                      Jetzt noch eine Frage. Mich wundert, dass das Modul hash.pm (in der cgi-bin) auch dann verwendet wird, wenn ich ihm keinerlei Berechtigungen gebe. Beim Perl-Programm ist das  nicht so.
                      Ist dies normal?

                      1. Exporter ist dabei:

                        dann ist ja alles i.O. ;-)

                        our %hash = ( keyA => 'valueA',
                                      keyB => 'valueB',
                                      keyC => 'valueC',
                                     );
                        1;

                        Ob hier our (statt my) nötig ist weiß ich nicht.

                        Jetzt noch eine Frage. Mich wundert, dass das Modul hash.pm (in der cgi-bin) auch dann verwendet wird, wenn ich ihm keinerlei Berechtigungen gebe. Beim Perl-Programm ist das  nicht so.
                        Ist dies normal?

                        Ja, Module werden ja nicht ausgeführt (im Prinzip schon, aber nicht in Bezug auf die Rechte) sondern eingebunden und müssen daher einfach nur in einem Pfad innerhalb von @INC liegen

                        Struppi.

                        --
                        Javascript ist toll (Perl auch!)
                        1. Ob hier our (statt my) nötig ist weiß ich nicht.

                          Selbstverständlich, denn my deklariert eine Variable als lokal, sodass sie nur im umschließenden Block (hier innerhalb des Packages) gültig ist (lexikalische Variable). Somit steht sie nicht zum Export in einen anderen Namensraum zur Verfügung. Variablen, die via our deklariert werden, sind zwar auch lexikalisch, aber nicht nur innerhalb des umgebenden Blocks, sondern im gesamten Package. Deshalb sind sie über die Grenzen eines Namensraumes hinweg sichtbar und werden per Default exportiert.

                          Letztlich ist jede Variable, die du deklarierst, zunächst global, es sei denn, du schränkst ihre Gültigkeit mittels my auf den umgebenden Block ein. Wenn du dann aus den bekannten guten Gründen das strict-Pragma verwendest, bist du gezwungen, für jede Variable den Gültigkeitsbereich festzulegen (also my bzw. our). Ohne das Pragma ist das Verhalten wie eingangs beschrieben:

                          {  
                            my $local_foo = "I'm local";  
                            $global_foo = "I'm global";  
                          }  
                            
                          print ($local_foo ? "$local_foo\n" : "not declared\n");  
                          print ($global_foo ? $global_foo : 'not declared');
                          

                          Nur wenn du use strict schreibst, musst du $global_foo mittels our deklarieren. Gleichzeitig bist du in meinem kleinen Beispiel gezwungen, den Namensraum mit anzugeben, solange sich das Script im strict-Modus befindet:

                          use strict;  
                            
                          {  
                            my $local_foo = "I'm local";  
                            our $global_foo = "I'm global";  
                          }  
                            
                          # strict für Variablen ausschalten, sonst gibt's  
                          # einen Fehler in der Abfrage nach $local_foo  
                          no strict 'vars';  
                          print ($local_foo ? "$local_foo\n" : "not declared\n");  
                          print ($global_foo ? $global_foo : 'not declared');
                          

                          Man könnte das jetzt bis zum Erbrechen weiterspielen, aber ich denke, dass das Grundprinzip klar ist. Eine gute, wenn auch schon etwas ältere Abhandlung zum Thema ist (falls du sie noch nicht kennen solltest) Coping with scoping.

                          Siechfred

                          --
                          Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
                          1. Ob hier our (statt my) nötig ist weiß ich nicht.

                            Selbstverständlich, denn ...

                            Danke, ich war mir nur nicht sicher, da ich sowas selten benutze und immer wieder durcheinander komme. Aber jetzt dürfte es allen (auch mir) klar sein ;-)

                            Struppi.

                            --
                            Javascript ist toll (Perl auch!)
              2. Welches ist wohl der empfehlenswerte Weg für mein Problem?

                Der empfehlenswerte Weg für dein Problem ist vermutlich (da du den Verwendungszweck des ganzen bisher verheimlicht hast) Config::File oder ein ähnliches Modul wie z.b. Config::IniFile

                Struppi.

                --
                Javascript ist toll (Perl auch!)
    2. Wie muss ich das Hash definieren (Dateityp), und wie kann ich es in die Perl-Programme einbinden?

      Mit den Funktionen fürs Dateisystem?
      http://perldoc.perl.org/
      http://perldoc.perl.org/functions/open.html
      http://perldoc.perl.org/functions/print.html
      http://perldoc.perl.org/functions/read.html
      http://perldoc.perl.org/functions/close.html

      Naja, Perl biete dafür einfacher Varianten, z.b. http://perldoc.perl.org/functions/do.html

      Struppi.

      --
      Javascript ist toll (Perl auch!)
  2. ich habe ein Hash, das ich in mehreren Perl-Programmen verwenden will.
    Wie muss ich das Hash definieren (Dateityp), und wie kann ich es in die Perl-Programme einbinden?

    Kommt drauf an ob du mit packages arbeitest oder ohne und ob dein Programm strict ist oder nicht.

    Am einfachsten geht es wenn du den Hash voll qualifiziert ansprichst, also mit dem Namensraum. In den meisten Fällen dürfte das $main sein.

    Aber schön ist sowas nicht (auch wenn ich das selber - ich vermute du brauchst das für eine Konfigurationsvariabel - hin und wieder mache)

    Es gibt aber noch mehr Möglichkeiten.

    Struppi.

    --
    Javascript ist toll (Perl auch!)
  3. Hallo.

    ich habe ein Hash, das ich in mehreren Perl-Programmen verwenden will.
    Wie muss ich das Hash definieren (Dateityp), und wie kann ich es in die Perl-Programme einbinden?

    Die vermutlich einfachste Methode dürfte folgende sein.

    Du legst dein Hash in einer einfachen Textdatei ab:

    hash.txt

    keyA => 'valueA',  
    keyB => 'valueB',  
    keyC => 'valueC',
    

    ========

    In deinen Programmen kannst du das Hash dann mit der do-Funktion einbinden:

    script.pl

    my %hash = do 'hash.txt';

    Informationen zur do-Funktion findest du hier: http://perldoc.perl.org/functions/do.html

    Alternativ kannst du das Hash natürlich auch mittels require einbinden, das würde in etwa wie folgt aussehen.

    Das Hash wird in einem kleinen Modul hinterlegt:

    hash.pm

    package hash;  
      
    use strict;  
    use warnings;  
      
    our %hash = ( keyA => 'valueA',  
                  keyB => 'valueB',  
                  keyC => 'valueC',  
                 );  
      
    1;
    

    =======

    Anschließend wird das Hash im Programm wie folgt eingebunden und angesprochen:

    script.pl

    require 'hash.pm'; # oder require hash;  
    print $hash::hash{'keyA'};
    

    =========

    Hierbei muss der Namensraum/Packagename gefolgt von zwei Doppelpunkten vor dem Namen des Hashs stehen (hier "hash::"). Weitere Hinweise unter http://perldoc.perl.org/functions/require.html

    Die Einbindung mittels use dürfte die sauberste Variante sein, ist dafür aber auch ein klein wenig aufwendiger, vor allem, wenn du das Hash in den Namensraum deines Programms exportieren möchtest.

    Das kleine Modul wird jetzt schon etwas größer:

    hash.pm

    package hash;  
      
    use strict;  
    use warnings;  
      
    use Exporter;  
    our @ISA = qw(Exporter);  
    our @EXPORT = qw(%hash);  
      
    our %hash = ( keyA => 'valueA',  
                  keyB => 'valueB',  
                  keyC => 'valueC',  
                 );  
      
    1;
    

    =======

    Der Packagename muss hierbei mit dem der Datei übereinstimmen. Das Modul Exporter dient zum Export des Hashs in den Namensraum deines Programms.

    Die Einbindung kann wie folgt geschehen:

    script.pl

    use hash;
    print $hash{'keyA'};

    Informationen zu use gibt es hier: http://perldoc.perl.org/functions/use.html

    Das dürften die drei (Haupt-)Möglichkeiten sein, um das Hash in deine bestehenden Programme einzubinden.

    Schöne Grüße.