opi: Datenstrukturen über Sockets

Hallo zusammen,

kann man über Internet Domain Sockets auch Datenstrukturen übertragen?

Ich erzeuge mit IO::Socket::INET eine Client-Server Verbindung.
Nun möchte ich vom Server zum Client beispielsweise eine
Datenstruktur übergeben. In meinem Fall wäre das eine Hashreferenz
mit weiteren Referenzen auf Hashes und Arrays.

Ich weiß, dass diese Struktur im Speicher liegt, aber gibt es
hier vielleicht eine Möglichkeit, die Daten so auszugeben, dass
der Client die Datenstruktur mit

server: print $client $data;
client: my $data = <$server>;

erkennt und auch so wieder im Speicher ablegt? Oder bin ich dazu
gezwungen, die Daten in $data mit einer Schleife zu Bearbeiten?

Darüber hinaus wüßte ich gerne noch etwas anderes.

Ich habe mir eine Subfunktion gebastelt, der ich als Argument einen
Hash übergebe, damit die Subfunktion weiß, was genau Sie machen soll.

Der Hash ist sehr simple und in der Subfunktion wird nur nach der
Existenz bestimmter Schlüssel gesucht. Existiert ein bestimmter
Schlüssel - der Wert des Schlüssels ist vollkommen unwichtig -
wird etwas weiteres angestoßen. Hier ein Beispiel:

my $hash = {
   "key1" => 1,
   "key2" => 1,
   "key3" => 1,
}

An dieser Stelle meine Frage: gibt es eine andere Möglichkeit,
einen Schlüssel zu erzeugen? So zu sagen das Gegenteil von delete?

my $r = func($hash);

sub func {
   my $q = shift;
   my $r = {};
   if (defined $q->{key1}) {
       $r->{key1} = { func_key1() };
   }
   if (defined $q->{key2}) {
       $r->{key2} = { func_key2() };
   }
   if (defined $q->{key3}) {
       $r->{key3} = [ func_key3() ];
   }
   return $r;
}

Jetzt weiß ich nicht, ob das die übliche Art ist, um bestimmte
Ereignisse anzustoßen oder ob es "bessere" Methoden gibt. Vielleicht
scheint ein Hash hierfür vollkommen fehl am Platze.

Für Hilfe wäre ich echt dankbar.

Bis dann.

Greez,
opi

--
Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|
  1. Hi,

    Darüber hinaus wüßte ich gerne noch etwas anderes.

    Ich habe mir eine Subfunktion gebastelt, der ich als Argument einen
    Hash übergebe, damit die Subfunktion weiß, was genau Sie machen soll.

    Warum nicht einen einfachen String nehmen?

    sub auswahl {
    sub1() if $aktion eq "Sub1";
    sub2() if $aktion eq "Sub2";
    sub3() if $aktion eq "Sub3";
    ende() if $aktion eq "Ende";
    }

    Nur so als Ansatz, lässt sich sicher in einer Sub abhandeln!

    • Steffen
    1. Hallo,

      Warum nicht einen einfachen String nehmen?

      sub auswahl {
      sub1() if $aktion eq "Sub1";
      sub2() if $aktion eq "Sub2";
      sub3() if $aktion eq "Sub3";
      ende() if $aktion eq "Ende";
      }

      der Ansatz ist nicht schlecht, aber was mache ich , wenn ich
      eventuell gerne Sub1 und Sub3 und noch ein paar andere Dinge
      ausführen und alles zusammen in einen Hash packen möchte. Aber
      in den Skalar $aktion passt leider nur ein Wert.

      Stell es dir wie ein Programm vor, dem du zur Ausführung die
      Argumente skript.pl -d -u -b mitgibst, weil du unterschiedliche
      Tätigkeiten oder ausgaben erwartest.

      Greez,
      opi

      --
      Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|
  2. kann man über Internet Domain Sockets auch Datenstrukturen übertragen?

    Nicht direkt nehme ich an (ich kenn mich mit Sockets nicht aus)

    Ich erzeuge mit IO::Socket::INET eine Client-Server Verbindung.
    Nun möchte ich vom Server zum Client beispielsweise eine
    Datenstruktur übergeben. In meinem Fall wäre das eine Hashreferenz
    mit weiteren Referenzen auf Hashes und Arrays.

    ....Oder bin ich dazu
    gezwungen, die Daten in $data mit einer Schleife zu Bearbeiten?

    Nein, use Data::Dumper.

    Darüber hinaus wüßte ich gerne noch etwas anderes.

    Ich habe mir eine Subfunktion gebastelt, der ich als Argument einen
    Hash übergebe, damit die Subfunktion weiß, was genau Sie machen soll.

    Der Hash ist sehr simple und in der Subfunktion wird nur nach der
    Existenz bestimmter Schlüssel gesucht. Existiert ein bestimmter
    Schlüssel - der Wert des Schlüssels ist vollkommen unwichtig -
    wird etwas weiteres angestoßen. Hier ein Beispiel:

    my $hash = {
       "key1" => 1,
       "key2" => 1,
       "key3" => 1,
    }

    Du kannst auch Funktionsreferenzen als Werte übergeben.

    my $hash = {
        "key1" => &func_1,
        "key2" => &func_2,
        "key3" => &func_3,
    }

    und dann:
    my $r = func($hash);

    sub func {
    my $q = shift;
    my $r = {};
    foreach(keys %$q)
    {
    $r->{$_} = &{ $q->{$_} }() if $q->{$_};
    }
    return $r;
    }

    Wobei natürlich die Funktionen dann Referenzen zurückgeben müssen auch keine Listen.

    Struppi.

    1. Ach hallo Struppi, nabend!

      kann man über Internet Domain Sockets auch Datenstrukturen übertragen?

      Nicht direkt nehme ich an (ich kenn mich mit Sockets nicht aus)

      Schade das Rolf Rost nicht anwesend ist, der wüßte das glaube ich.
      Dann muss ich wohl nochmal googlen, obwohl ich mir jetzt schon
      sicher bin, dass dies nicht klappen wird! Schade!

      Nein, use Data::Dumper.

      Könnte ich mit dem Modul die Struktur einen Hashes auseinander
      nehmen? Die Daten müssten vom Client wieder zusammen gesetzt
      werden können. Ein Beispiel:

      der Hash

      my $hash = {
         "key1" => "value1",
         "key2" => "value2",
         "key3" => "value3",
         "key4" => {
            "xkey1" => "xvalue1",
            "xkey2" => "xvalue2",
         },
         "key5" => [ 1,2,3,4,5 ],
      };

      die Ausgabe zum Client

      print "key1:value1\n";
      print "key2:value2\n";
      print "key3:value3\n";
      print "key4:xkey1:xvalue1\n";
      print "key4:xkey2:xvalue2\n";
      print "key5#1,2,3,4,5\n";

      Irgendwie soetwas! Ich weiß, ist kein leichtes unterfangen, aber ich
      bin bestimmt nicht der erste, der vor diesem Problem steht.

      Oder ich muss dem Client ganz genaue Anweisung geben, damit er weiß,
      wann ein Hashkey erfolgt, wann ein Array und wann ein Value.

      Um etwas genauer zu sein... genau den Hash, den ich mit der unten
      stehenden Funktion zusammen setze, muss an den Client übertragen
      werden...

      Du kannst auch Funktionsreferenzen als Werte übergeben.

      my $hash = {
          "key1" => &func_1,
          "key2" => &func_2,
          "key3" => &func_3,
      }

      und dann:
      my $r = func($hash);

      sub func {
      my $q = shift;
      my $r = {};
      foreach(keys %$q)
      {
      $r->{$_} = &{ $q->{$_} }() if $q->{$_};
      }
      return $r;
      }

      Genau das ist es!!! SELFHTML - hier werden sie geholfen :-)

      Greez,
      opi

      --
      Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|
      1. kann man über Internet Domain Sockets auch Datenstrukturen übertragen?

        Nicht direkt nehme ich an (ich kenn mich mit Sockets nicht aus)

        Schade das Rolf Rost nicht anwesend ist, der wüßte das glaube ich.
        Dann muss ich wohl nochmal googlen, obwohl ich mir jetzt schon
        sicher bin, dass dies nicht klappen wird! Schade!

        Ich eigentlich auch

        Nein, use Data::Dumper.

        Könnte ich mit dem Modul die Struktur einen Hashes auseinander
        nehmen? Die Daten müssten vom Client wieder zusammen gesetzt
        werden können. Ein Beispiel:

        Ja.

        der Hash

        my $hash = {
           "key1" => "value1",
           "key2" => "value2",
           "key3" => "value3",
           "key4" => {
              "xkey1" => "xvalue1",
              "xkey2" => "xvalue2",
           },
           "key5" => [ 1,2,3,4,5 ],
        };

        use Data::Dumper;

        print Dumper $hash;

        Hier ist das Problem, dass das Modul eine lesbare Ausgabe erzeugt, du willst wvtl. aber lieber eine kompakte Struktur, dazu setzt du $Data::Dumper::Indent  auf 0.

        use Data::Dumper;
        $Data::Dumper::Indent = 0;

        print Dumper $hash;

        Die Ausgabe kannst du dann mit eval wieder zurückwandeln, wobei die Struktur dann in $VAR1 ist.

        my $x =  Dumper $hash;
        my $VAR1;
        eval($x);

        print Dumper $VAR1;

        Struppi.

        1. Hallo,

          use Data::Dumper;

          print Dumper $hash;

          Hier ist das Problem, dass das Modul eine lesbare Ausgabe erzeugt, du willst wvtl. aber lieber eine kompakte Struktur, dazu setzt du $Data::Dumper::Indent  auf 0.

          use Data::Dumper;
          $Data::Dumper::Indent = 0;

          print Dumper $hash;

          Die Ausgabe kannst du dann mit eval wieder zurückwandeln, wobei die Struktur dann in $VAR1 ist.

          my $x =  Dumper $hash;
          my $VAR1;
          eval($x);

          print Dumper $VAR1;

          obwohl ich es nicht so mit Modulen habe, werde ich das morgen
          ausprobieren und gegebenfalls einsetzen! Danke für deine Hilfe!

          Wie schaut das eigentlich mit deinem selbst gebastelten Module
          oder einer Subfunktion... vor ein paar Tagen hattest du darüber
          geschrieben. Es handelte sich da wohl irgendwie um DBI.

          Magst du mir das mal per eMail zuschicken oder ist das (C)
          copyright?

          Greez,
          opi

          --
          Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|
          1. Wie schaut das eigentlich mit deinem selbst gebastelten Module
            oder einer Subfunktion... vor ein paar Tagen hattest du darüber
            geschrieben. Es handelte sich da wohl irgendwie um DBI.

            Jaja, ich erinner mich. Bei den ganzen Fachleuten hier ist mein Mut sowas zu posten nur begrenzt ;-=

            Das Ding ist relativ Tricky und ist eine Art weiterentwicklung von fields (auch ein Modul).

            Ich weiß nicht ob andere sowas gebrauchen können. Die Idee dahinter ist einmal:
            Der Zugriff auf Datenfelder nur über Funkionen, d.h. auch bei einem nicht existierenden Feld gibt es einen Fehler.

            Gleichzeitig prüft diese Modul, welche Felder geändert wurden sodass sich beim Speichern in eine DB nur die Felder übertragen werden, die wirklich geändert wurden.

            Ein kurzes Beispiel:

            Du hast ein Tabelle mit den Feldern: id name text datum

            Das ganze würde dann bei mir so aussehen:~~~perl

            #------------------------------------------------------------------------------
            package einDatensatz;
            #------------------------------------------------------------------------------
            use strict;
            use debug;
            use base qw/myObj/; # <- Das ist das Modul

            einDatensatz->setFunc( [qw/id name text datum/] );

            Hier werden die Funktionen erzeugt

            sub load
            {
                my $self = shift;
                my $id = shift || return;

            my $data = DB::fetch( 'Tabelle',  '*', 'id = ' . DB::quote( $id ) );
                $self->setData( $data) ;

            }
            sub save
            {
                my $self = shift;
                if($self->id)
                {
                    DB::insert('Tabelle', $self->getData() );
                    $self->id( DB::last_id );
                }
                else
                {
                    DB::update('Tabelle', $self->getChange(), 'id=' . $self->id ) if $self->getChange();
                }
            }

            1;

            Anmerkung: DB:: ist noch so ein Hilfsmodul für mySQL Routinen  
              
            setData() setzt die Wert der Felder, der Parameter ist ein Hash oder eine Referenz auf eines.  
              
            getData() liefert alle Felder und Werte als Hash Referenz zurück  
              
            getChange() liefert nur die geänderten Felder zurück.  
              
              
            
            > Magst du mir das mal per eMail zuschicken oder ist das (C)  
            > copyright?  
              
            Bei mir - kein C - Wenn du es glaubst gebrauchen zu können?  
              
              
            Struppi.
            
            -- 
            [Javascript ist toll](http://javascript.jstruebig.de/)
            
            1. [code lang=perl]

              sub save
              {
                  my $self = shift;
                  if($self->id)

              Nicht so wichtig da nur ein Beispiel, aber natürlich unless $self->id

              Struppi.

            2. Hallo,

              ach so etwas hast du gemacht. Ich dachte du hättest einen
              brauchbaren Ersatz für das DBI-Modul. Ich darf das Modul
              nämlich aus bestimmten Gründen im Unternehmen nicht verwenden
              und muss mir was eigenes basteln (deshalb auch meine kleine
              Abneigung gegen Module... nur so nebenbei).

              Greez,
              opi

              --
              Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|
              1. ach so etwas hast du gemacht. Ich dachte du hättest einen
                brauchbaren Ersatz für das DBI-Modul. Ich darf das Modul
                nämlich aus bestimmten Gründen im Unternehmen nicht verwenden

                Das müssen aber gute Gründe sein, da DBI die Schnittstelle ist, die eigentlich überall eingesetzt und beschrieben wird wird.

                und muss mir was eigenes basteln (deshalb auch meine kleine
                Abneigung gegen Module... nur so nebenbei).

                Gerade bei DBI dürfte das sicher lange dauern, das ist ein Modul das seit zehn Jahren entwickelt wird.

                Wobei genauer seit 13:
                ANCIENT HISTORY
                12th Oct 1994: First public release of the DBI module. (for Perl 5.000-beta-3h)

                19th Sep 1994: DBperl project renamed to DBI.

                29th Sep 1992: DBperl project started.

                Struppi.

                1. Hallo,

                  ach so etwas hast du gemacht. Ich dachte du hättest einen
                  brauchbaren Ersatz für das DBI-Modul. Ich darf das Modul
                  nämlich aus bestimmten Gründen im Unternehmen nicht verwenden

                  Das müssen aber gute Gründe sein, da DBI die Schnittstelle ist, die eigentlich überall eingesetzt und beschrieben wird wird.

                  DBI ist in der SLES8 Version für unsere Architektur nicht vorhanden,
                  somit besteht also kein Support, falls wir DBI installieren und
                  unsere Jobs damit ausstatten und etwas schief läuft. Das ist ein
                  sehr trifftiger Grund für manchen Chef. In der SLES9 Version soll
                  das Modul standardmäßig enthalten sein, aber Oracle 9 ist nicht
                  für SLES9 zertifiziert. Also... selfmade! Wie schon so oft!

                  Gerade bei DBI dürfte das sicher lange dauern, das ist ein Modul das seit zehn Jahren entwickelt wird.

                  Nun, ich hatte nicht vor, das Modul neu zu schreiben, denn dafür
                  reichen meine Kenntnisse noch nicht aus! Ein sqlplus << tuts aber
                  auch, denn selbst hier kann ich Ein- und Ausgabekanal auf eine Pipe
                  lenken und über einen ganzen Job hinweg eine Session aufrecht
                  erhalten.

                  Greez,
                  opi

                  --
                  Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|