roger: Hash anlegen und abfragen

Hallo,

ich möchte ein bestehendes Programm verändern in dem ich das Hash "erweitere"
Aktuell sieht es so aus

  
my %SET = ( type => 'D',  
	      db => 80,  
	    byte => 33,  
	     bit => 4,  
	   setze => 1,  
	    text => 'EIN',  
	   farbe => 'orange')  

Nun soll alles erweitert werden. Ich dachte nun an diese Variante

my %SET = ( type0 => 'D',  
	      db0 => 80,  
	    byte0 => 33,  
	     bit0 => 4,  
	   setze0 => 1,  
	    text0 => 'EIN',  
	   farbe0 => 'orange',  
  
	    type1 => 'D',  
	      db1 => 80,  
	    byte1 => 33,  
	     bit1 => 5,  
	   setze1 => 1,  
	    text1 => 'AUS',  
	   farbe1 => 'green',  
	  
	    type2 => 'D',  
	      db2 => 80,  
	    byte2 => 33,  
	     bit2 => 5,  
	   setze2 => 1,  
	    text2 => 'AUS',  
	   farbe2 => 'green',  
	   );

Dies würde ich dann mit einer Schleife abfragen, ob
1. überhaupt vorhanden (..0 ist immer vorhanden)

Oder sollte ich ein 2. dimensionales Hash erstellen, wenn ja, wie würde so etwas aussehen und wie könnte ich dieses abfragen.

Vielleicht kann ich auch mein Hash auf ein Array legen. So nach dem Motto

daten[0].type
daten[1].type

Fragen über Fragen :-)

Für mich geht erst einmal um Tips wie ich es am einfachsten erstellen und auch abfragen kann. Hier habe ich überhaupt keine Ahnung/Vorstellung. Natürlich will ich das Rad nicht neu erfinden und eine Insellösung erstellen.

Gruß
       roger

  1. hi,

    ich möchte ein bestehendes Programm verändern in dem ich das Hash "erweitere"

    Annahme: Du möchtest den Basishash behalten und Erweiterungen bei Bedarf sozusagen drüberbügeln, so dass im Basishash vorhandene Schlüssel-Werte-Paare entweder erhalten oder überschrieben werden, das geht so

    %reshash = (%basehash, %advhash);

    Hotti

    PS: Wenn jemand das Rad neu erfunden hat, dann waren es PHP'ler mit array_merge() was dasselbe macht.

    1. Hallo,

      PHP pah... bin aus alter Perl Schule :-)

      Ich habe es vermutlich unzureichend erklärt.

      Im Script wird das Hash einmalig manuell (Handeingabe) gefüllt. (Script ist mehrfach im Einsatz)
      Früher benötigte ich nur einen "Datensatz/Hash" um eine HTML Seite zu erstellen,
      jetzt gibt es mehrere Auswahlkriterien die es nötig macht, mehr als einen Hash (Datensatz) zu erstellen.
      Wie gesagt das Hash wird manuell erstellt.

      Je länger ich überlege ist ein Array das mein Hash enthält das einfachste, wie gesagt denke ich.

      Wie müsste ich das erstellen/Initialisieren ??

        
        
      my @data =  "type => 'D', db => 80", "type => 'D', db => 80", "type => 'D', db => 80";  
        
      
      

      Hier habe ich einmal geraten, aber so ähnlich sollte es doch gehen ??

      Ich habe hier bei Goggle nicht's gefunden, da Google immer nur Array in Hash findet, jedoch nicht Hash im Array.
      Bei dieser Variante (Hash in Array) könnte ich eine foreach Schleife über das Array laufen lassen... wäre für mich super "OK"

      data[$i].type oder ähnlich.

      Gruss
             roger

      1. hi,

        Ich habe hier bei Goggle nicht's gefunden, da Google immer nur Array in Hash findet, jedoch nicht Hash im Array.

        wie wärs mit Hash in Hash?

          
        $hoh = ( foo => {}, bar => {}, baz => {});  
        
        

        Genauer: Der Hash ist ein Hash mit (namentlichen) Hash-Referenzen.

        Deine Aufgabenstellung habe ich leider auch nicht verstanden.

        Ansonsten, Array mit Hash-Referenzen:

          
        @ar = ({},{},{});  
        
        

        Genauer: Die Array-Elemente sind Hash-Referenzen.

        Und noch was: Schlüssel im Hash sind immer Scalare. Die Werte auch. Referenzen sind auch Scalare. Mit diesem Hintergrundwissen, kannst Du alle erdenklichen Datenstrukturen aushecken.

        Vermutlich suchst Du nach einer passenden Datenstruktur. Beschreib einfach mal, unabhängig von Perl, was Du brauchst, was gemacht werden soll.

        Horst Haschie

        1. Hallo,

          Ansonsten, Array mit Hash-Referenzen:

          @ar = ({},{},{});

          
          > Genauer: Die Array-Elemente sind Hash-Referenzen.  
          >   
            
          Genau das ist was ich wollte.  
            
          ~~~perl
            
            
          my @data = (  
          	    { type => 'D', db => 80 usw.},  
          	    { type => 'M', db => 81 usw.},  
          	    { type => 'A', db => 82 usw.}  
          	   );  
            
          
          

          Nun die Frage: wie greife ich auf z.B. Array[1] zu

          $data[1]{'type'}

          Beschreib einfach mal, unabhängig von Perl, was Du brauchst, was gemacht werden soll.

          Das Script ist immer gleich bis auf die Hashparameter.
          Mit den Hashparametern werden individuelle HTML-Seiten erzeugt.
          Pro Array Eintrag werden <Input type="radio"...> in der generierten HTML-Seite erzeugt. d.h. 3 Hash im Array ... 3 x <input type="radio"...>

          Wird eine Auswahl am Radio getroffen und der "senden button" betätigt werden die restlichen Hashdaten des ausgewählten Arrays an den Webserver/Perlscript gesendet, der weitere Aktionen damit erstellt.

          Ich hoffe ich habe es nun besser erklärt.

          Danke
                 roger

          1. hi,

            Nun die Frage: wie greife ich auf z.B. Array[1] zu

            $data[1]{'type'}

            Ganz genau.

            Beschreib einfach mal, unabhängig von Perl, was Du brauchst, was gemacht werden soll.

            Das Script ist immer gleich bis auf die Hashparameter.
            Mit den Hashparametern werden individuelle HTML-Seiten erzeugt.
            Pro Array Eintrag werden <Input type="radio"...> in der generierten HTML-Seite erzeugt. d.h. 3 Hash im Array ... 3 x <input type="radio"...>

            Das würde ich rumdrehen. Also einen Hash mit Arrays dazu verwenden, weil, für radio-Buttons bietet sich ein Array an. Array's haben jedoch wiederum den Nachteil, dass die einzelnen Elemente über einen Index laufen [0..$n-1] und somit nicht namentlich adressierbar sind.

            Wegen einer (gewünschten) namentlichen Adressierbarkeit sind Hashes wiederum freundlicher in der Handhabe.

            Wird eine Auswahl am Radio getroffen und der "senden button" betätigt werden die restlichen Hashdaten des ausgewählten Arrays an den Webserver/Perlscript gesendet, der weitere Aktionen damit erstellt.

            Ich hoffe ich habe es nun besser erklärt.

            Wir kommen der Sache näher ;)

            Ok, wir haben

              
                <input type="radio" name="foo" value="asdf">  
                <input type="radio" name="foo" value="qwertz">  
                <input type="radio" name="foo" value="yxcv">  
              
                <input type="radio" name="bar" value="asdf">  
                <input type="radio" name="bar" value="qwertz">  
                <input type="radio" name="bar" value="yxcv">  
              
              
            
            

            Hierzu könnte folg. datenstruktur passen:

              
            %cfg = (  
               foo => [qw(asdf qwertz yxcv)],  
               bar => [qw(asdf qwertz yxcv)],  
            );  
            
            

            D.h., für die radio-Buttons brauchst Du nur eine Liste mit Werten. In der Struktur s.o. als Array-Referenz notiert. Die Schlüssel 'foo', 'bar', ... sind dann für verschiedene Seiten zuständig.

            Horst

            --
            Zuständigkeiten klären, Ruhe bewahren.
            1. Hallo,

              erst einmal danke für deine Mühe und die schnelle Hilfe.

              So ... ich probiere schon herum und habe mein Array aus Hash erzeugt.

              @SET

              print "$SET[0]{'text'}\n";  funktioniert

              foreach (@SET)  
              { print "$_{'text'}\n"; }
              

              funktioniert nicht... warum ??

              Es kommt keine Fehlermeldung, jedoch auch kein Inhalt der Hashvariable.

              Gruss
                         roger

              1. Hallo,

                ich habe es selbst gefunden, learning bei searching.
                Es muss so lauten.

                  
                  
                foreach (@SET) { print "$_->{'text'}\n"; }
                

                Gruss
                           roger

                1. hi,

                    
                  foreach (@SET) { print "$_->{'text'}\n"; }  
                  
                  

                  Ok, jetzt weiß ich auch, wie Dein Array aufgebaut ist. Die richtige Datenstruktur wirst Du letztendlich selbst finden, nochn Tipp

                    
                  use strict;  
                  use warnings;  
                  
                  

                  (kein Witz, ich kenne tatsächlich Entwickler, die sich als professionell bezeichnen und ohne strict und ohne warnings tonnenweise Code fabrizieren).

                  und auch den hier

                    
                  use Data::Dumper;  
                     print Dumper \@SET;  
                  
                  

                  fleißig nutzen ;)

                  Wenn Du ein paarmal mit Referenzen gearbeitet hast, ist das dann wie Radfahren. Ab 5.10 gibts neue Features, auch fürs Pragma warnings, da kannst Du z.B. bestimmte Warungen in den Status einer Exception erheben und somit gleich beim Entwickeln feststellen, wo's noch klemmt, die meisten Fälle sind nicht initialisierte Variablen.

                  Viel Spaß mit Perl,
                  leider interessierts heute keine Sau mehr, das Perl.

                  Horst Perlhuhn

                  --
                  Wenn Perl tot ist, bin ich das praktisch auch.
                  1. Hallo,

                    gestern habe ich mir noch eine Nachtschicht gegeben.... funktioniert alles Prima.

                    nochn Tipp

                    use strict;
                    use warnings;

                    
                    >   
                    
                    Selbsredend, somit bin ich schon einmal gezwungen Variablen zu deklarieren. Nein... das ist Selbstverständlich, genauso  
                      
                    `use CGI::Carp qw (fatalsToBrowser);`{:.language-perl}  
                      
                    
                    > und auch den hier  
                    > ~~~perl
                      
                    
                    > use Data::Dumper;  
                    >    print Dumper \@SET;  
                    > 
                    
                    

                    fleißig nutzen ;)

                    Hier bin ich etwas sparsam... weiß auch nicht warum.

                    leider interessierts heute keine Sau mehr, das Perl.

                    Hey, hey ... bin ich "keine" Sau" :-)

                    Gruß
                              roger

                    1. hi,

                      use CGI::Carp qw (fatalsToBrowser);

                      Das ist gut, es geht zu verbessern ;)

                      use Data::Dumper;
                         print Dumper @SET;

                      Hier bin ich etwas sparsam... weiß auch nicht warum.

                      Wir wissen, dass der Dumper Ressourcen frisst. Ich entwickle auf einer ziemlich alten Kiste, da macht sich bereits ein use Data::Dumper; als Bremse bemerkbar, von daher ist auch nicht gut, solch Zeile in einem Script, was produktiv gehen soll, stehen zu lassen. Unschätzbar jedoch ist der Dumper beim Entwickeln selbst und zum Debuggen.

                      Dafür habe ich eine Methode:

                        
                           $self->dd(\%ENV); # dum and die  
                      
                      

                      wobei diese Methode außerhalb vom regulären Code steht, also in einer externen Datei notiert ist, die dann nur auf Anforderung mit AUTOLOAD kompiliert wird. Erst dann wird der Data::Dumper eingebunden, ansonsten bleibt der draußen.

                      Wenn Du beim Entwickeln flott voran kommen willst, setze alles, was das Ausgabeergebnis zusammenbaut in einen try- bzw. eval-Block. Da kannst Du nach herzenslust Exceptions schmeißen und siehst gleich im Browser, was da geht (Content-Type: text/plain).

                      In einem meiner letzten Jobs hatte ich einen Fehler zu suchen. Die Entwickler der Firma, allesamt sehr von sich eingenommen, hatten schon ans Debuggen gedacht, die praktischen Möglichkeiten, wie z.B. Logging einschalten u.ä., erwiesen sich jedoch als sehr unbrauchbar.

                      Um dem Fehler auf die Spur zu kommen, habe ich die main sozusagen aufgebockt, zunächst, um die zahllos wild verstreuten print-Anweisungen zu erfassen, habe ich ganz oben STDOUT in einen Puffer umgeleitet (perldoc -f select) und dann den ganzen Code in einen eval-Block gesetzt. Nach 2..3 gezielt geworfenen Exceptions, deren Ausgabe der Dumper gleich im Browser zeigte, hatte ich den Fehler innerhalb weniger Minuten, den Andere nach Tagen nicht gefunden haben.

                      leider interessierts heute keine Sau mehr, das Perl.

                      Z.Z. bin ich arbeitslos, wenn ich jedoch an meine Jobs der letzten Jahre denke, bin ich froh, dass ich draußen bin und mich nicht mit irgendwelchem Scheiß-Code befassen muss, wo nicht einmal ein use strict; eingeschaltet werden kann, weil dann gleich gar nichts mehr geht. Oft war ich froh, nach Feierabend an meiner alten Kiste zu sitzen und, auch auf diese Erfahrungen (!) aufbauend, an meinem eigenen Framework weiterzumachen. Was da mitterlweile entstanden ist, davon träumt so mancher Entwickler, das haben mir ehemalige Kollegen ganz offenherzig zugestanden. Es braucht jedoch ein bischen Auszeit für solche Dinge, Zeit, die im produktiven Umfeld absolut nicht vorhanden ist.

                      Deswegen wirst Du oftmals einen Legacy-Code vorfinden, der eine einzige Flickenschusterei und im Grunde genommen Schrott ist, wo Zeiten zum Entwickeln neuer Features oder zur Programmpflege potentiell ins Unermessliche steigen und kein Kunde der Welt gewillt ist, dafür nur einen Cent auszugeben. Der Trümmerberg, der da an Arbeit übrig bleibt, ist ein Tummelplatz für Studenten und für schlechtbezahlte Entwickler. Profis mit Erfahrung sind heute gar nicht mehr gefragt.

                      Achja, PHP, privat ein paar Jahre, beruflich ein halbes Jahr hatte ichs damit. Was mir da als Framework hingestellt wurde, sah vom Aufbau her gar nicht so aus, funktionierte auch nicht so wie gewünscht, hatte Programmstrukturen, die mich an meine Anfänge mit Perl (1997) erinnerten, nur, dass es unglaublich zahllos und planlos verstreute include 'xy.php'; gab, zwischendrin war da auch mal ein require 'config.php'; zu sehen und ansonsten ein Code, der vor lauter spitzen Klammern gar nicht mehr als Solches erkennbar war. Immerhin habe ich über dreißig verschiedene Cookies gezählt, nachdem ich mir eines der Spitzenprodukte mal angeschaut hatte.

                      Nutze die Zeit, lerne aus Fehlern, dann darfst Du such welche machen.
                      Horst

  2. ahh, verstehe,

      
      
    my %SET = (  
        '0' => {  
            type => 'D',  
            db => 80,  
            byte => 33,  
             bit => 4,  
            setze => 1,  
            text => 'EIN',  
            farbe => 'orange',  
        },  
        '1' => {  
            type => 'D',  
            db => 80,  
            byte => 33,  
             bit => 4,  
            setze => 1,  
            text => 'EIN',  
            farbe => 'orange',  
        },  
      
    );  
      
      
      
    
    

    Wäre eine Möglichkeit.

    Horst

  3. Ich würde dir gerne "Modern Perl - The Book" empfehlen, zu finden hier:
    http://perl-tutotial.org/
    Da lernst du ein paar moderne Grundlagen.

    Zu Datenstrukturen und Referenzen:
    http://perldoc.perl.org/perlreftut.html
    http://perldoc.perl.org/perldsc.html
    http://perldoc.perl.org/perllol.html
    Damit du das nächste mal gleich weisst, wo du nachschauen musst.

    1. Ich würde dir gerne "Modern Perl - The Book" empfehlen, zu finden hier:
      http://perl-tutotial.org/

      misst, vertippt. so muss es heissen:
      http://perl-tutorial.org/