[Perl] Objekte dynamisch benennen

Dieses Thema im Forum "Ruby, php, Perl, Python ..." wurde erstellt von biont, 09.07.2009.

  1. biont

    biont Grünschnabel

    Dabei seit:
    09.07.2009
    Beiträge:
    4
    Zustimmungen:
    0
    Guten Morgen zusammen,

    ich hole mir aus einem XML file zu beliebig vielen "Signalen" meine Eigenschaften und möchte sie in der selben Anzahl von Objekten einer Klasse speichern, die alle Eigenschaften aufnimmt und Zugriffsmethoden dazu bereitstellt (inklusive Wertebereichsüberprüfung uns Plausibilitätsprüfung).

    Ausschnitt aus XML:
    Code:
    ...
    <SIGNAL>
      <EIGENSCHAFT1>xyz</EIGENSCHAFT1>
      <EIGENSCHAFT2>klm</EIGENSCHAFT2>
      <EIGENSCHAFT3>abc</EIGENSCHAFT3>
    </SIGNAL>
    <SIGNAL>
    ...
    Das Muster sollte damit klar sein.

    Aber jetzt zu meinem Problem: ich kann problemlos eine Instanz/Objekt aus meiner Klasse erstellen und befüllen. Aber wie kann ich den Namen des Objektes dynamisch aus einem String erstellen und dann auch mit Hilfe des Strings darauf zugreifen?

    Beispiel (Constructor ist new(); eigenschaft1() ist die Zugriffsmethode auf die gleichnamige, klasseneigene Variable und liefert den Wert der Variablen zurück):
    Code:
    # funktioniert
    my $name = "blabla"; # Daten aus xml
    my $obj1 = ClassName->new();
    $obj1->eigenschaft1(name);
    print $obj1->eigenschaft1."\n";
    
    # funktioniert nicht
    my $test = "tralala";
    my ${$test} = ClassName->new();
    ${$test}->eigenschaft1(name); # soll die gleiche Wirkung haben, wie nächste Zeile
    $tralala->eigenschaft1(name);
    
    Klar funktioniert der letzte Teil so nicht, aber ich habe einfach keine Idee (mehr), wie ich eine unbekannte Anzahl an Objekten durch-benamen kann und dann auch gezielt Aufrufe zu gestalten.

    Einen Tipp, wie mein Ansatz doch funktionieren könnte, oder wie "man" das in Perl eben "richtig" macht, wüsste ich sehr zu schätzen.

    Danke schonmal vorab...
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 bytepool, 09.07.2009
    Zuletzt bearbeitet: 09.07.2009
    bytepool

    bytepool Code Monkey

    Dabei seit:
    12.07.2003
    Beiträge:
    791
    Zustimmungen:
    0
    Ort:
    /home/sweden/göteborg
    Hi,

    mit anderen Worten, du versuchst metaprogramming in Perl. Ich kenne Perl auch nicht gut genug um zu wissen wie das funktionieren koennte, aber eventuell findest etwas, wenn du mal nach metaprogramming in Verband mit Perl suchst.

    Edit:
    Och, google sagt dass Perl aehnlich wie die Bash eval kennt:
    Code:
    #!/usr/bin/perl
    
    my $foo = "bar";
    my $bar = 0;
    eval "\${$foo} = 20";
    print "$bar \n";
    
    So einfach kann das sein. ;)

    Edit2:
    Mhh, ja, oder auch nicht. ;)
    Das funktioniert irgendwie nicht, wenn $bar erst in eval definiert wird. Naja, vielleicht wissen da die Perl Juenger hier mehr drueber.

    Edit3:
    So, ich glaub ich habs jetzt.
    Code:
    #!/usr/bin/perl
    
    use strict;
    
    package hallo;
    $hallo::foo = "bar";
    
    eval {$hallo::{$hallo::foo} = 40;}; warn $@ if $@;
    eval {print "$hallo::{$hallo::foo} \n";}; warn $@ if $@;
    
    Perl ist schon ne komische Sprache.

    mfg,
    bytepool
     
  4. #3 biont, 09.07.2009
    Zuletzt bearbeitet: 09.07.2009
    biont

    biont Grünschnabel

    Dabei seit:
    09.07.2009
    Beiträge:
    4
    Zustimmungen:
    0
    Hallo,

    danke für den Tipp! Unter http://de.wikipedia.org/wiki/Reflection_%28Programmierung%29#Beispiel_in_Perl lernt man, dass diese Programmiermethode "reflection" genannt wird.

    Und in dem Beispiel machen die auch fast genau das, wonach ich suche. Nur leider scheint es lediglich für Zugriffe ohne Variablentypkennzeichnung ($,%,@) zu funktionieren. Sprich, für alle Methodenaufrufe und Direktzugriffe von Klassen.

    Code:
    # funktioniert
    $class = "ClassName";
    $method = "eigenschaft1";
    my $obj3 = $class->new(); # same as: my $obj3 = ClassName->new();
    $obj3->$method; # same as: $obj3->eigenschaft1;
    
    Ich glaube für den fehlenden Teil (Ersetzen des Objektnamens in der Deklaration und im Aufruf/Zugriff) brauchen wir (oder nur ich) einen der Perlgötter...

    *weitergrübel*


    Edit:
    Danke Bytepool, während ich meinen Teil schrieb kam schon Dein Edit3... ;-)

    Edit2: Und so geht das mit den Objekten (getestet, funktioniert)
    Code:
    my $test = "tralala";
    eval {$main::{$test} = ClassName->new();};
        # Objekt "$tralala" erstellen
    eval {$main::{$test}->name(objekt1);};
        # Methode setzt "name" von $tralala ...
    eval {print "\$$test->name ";};
        # (Nur Ausgabe)
    my $rets = eval {return $main::{$test}->extSPN;};
        # ...oder gibt "name" aus, wenn leer aufgerufen
    print "$rets \n";
        # Ausgabe ist dann: > $tralala->name objekt1
    
    
    $test = "trululu";
        # ändert namensgebenden string
    eval {$main::{$test} = ClassName->new();};
        # erstellt neues Objekt "$trululu"
    eval {$main::{$test}->name(objekt2);};
        # setzt namen von $trululu auf "objekt2"
    eval {print "\$$test->name ";};
        # lediglich Ausgabe
    $rets = eval {return $main::{$test}->name;};
        # Ausgabe $trululu->name
    print "$rets \n";
        # Ausgabe ist dann: > $trululu->name objekt2
    
    
    $test = "tralala";
        # zurücksetzen, damit wir schauen können, ob
        # das Objekt2 namens $tralala auch wirklich
        # noch existiert!
    eval {print "\$$test->name ";};
        # Ausgabe...
    $rets = eval {return $main::{$test}->name;};
        # ... des Namens
    print "$rets \n";
        # Ausgabe ist dann : > $tralala->name objekt1
    
    Jetzt müsste ich nur noch herausbekommen, wie man den Weg über den Packagenamen vermeidet...
     
  5. biont

    biont Grünschnabel

    Dabei seit:
    09.07.2009
    Beiträge:
    4
    Zustimmungen:
    0
    Der von mir derzeit eleganteste Weg mit einer dynamischen Anzahl von Objekten umzugehen, sieht nun so aus:

    Code:
    use ClassName
    
    my @objekte;
    my $cnt = 0;
    my $ziel = 3;
    
    while ($objectsAvailable) {
       $objekte[$cnt] = ClassName->new();
       $cnt++;
       }
    
    $objekte[$ziel]->name("lalala");
    print "Name of Obj \$ziel ($ziel): ".$objekte[$ziel]->name."\n";
    
    Damit kann ich zwar nicht, wie ursprünglich gewünscht, die Objekte mit einem beliebigen Namen ansprechen, aber doch wenigstens *gezielt* und in Schleifen über die Gesamtzahl.
     
  6. reneeb

    reneeb Grünschnabel

    Dabei seit:
    17.07.2009
    Beiträge:
    3
    Zustimmungen:
    0
    Der Hash wäre dann wohl die bessere Datenstruktur:

    Code:
    use ClassName
    
    my %objekte;
    my $cnt = 0;
    
    while ($objectsAvailable) {
       $objekte{ "Objekt" . $cnt } = ClassName->new();
       $cnt++;
    }
    
    $objekte{Objekt3}->name("lalala");
    print "Name of Objekt3: " . $objekte{Objekt3}->name . "\n";
     
Thema:

[Perl] Objekte dynamisch benennen

Die Seite wird geladen...

[Perl] Objekte dynamisch benennen - Ähnliche Themen

  1. [PERL] Objekte an Threads.

    [PERL] Objekte an Threads.: Hi... Mein Problem sieht wie folgt aus: Ich habe ein Object erstellt mittels bless() und möchte dieses Objekt an 2 Threads übergeben, nun...
  2. [Perl] Perl OO Methodenaufruf in anderem Objekt

    [Perl] Perl OO Methodenaufruf in anderem Objekt: Hallo, Ich bin dabei in Perl ein Pokerspiel zu programmieren, hänge aber momentan an einem Problem, wo ich nicht weiterkomme. Ich habe die...
  3. [Perl] Check auf Referenz...Hash

    [Perl] Check auf Referenz...Hash: Hallo! Mal ne kleine Frage. Gibt es ein Funktion mit der ich checken kann, ob in einem Hash der Value eine Referenz auf einen weiter Hash...
  4. [Perl]: Mehr als ein Objekt auf einmal instanziieren

    [Perl]: Mehr als ein Objekt auf einmal instanziieren: Hallo zusammen, ich benutze zurzeit Net::FTPSSL zum Aufbau einer FTP Connection. Mein Problem ist, wenn ich z.B. eine Verbindung zu 5...
  5. [Perl] Script zum ändern der Signatur in vB-Boards

    [Perl] Script zum ändern der Signatur in vB-Boards: Hallo, folgendes Script funktioniert beim gulli:board , aber leider nicht hier: #!/usr/bin/perl use LWP::UserAgent; $agent = new...