Slaughter: Perl Array in Instanz füllen und auslesen

Hallo,

ich möchte eine Klasse programmieren, die pro Instanz ein "Child"-Array enthält. Dieses Array möchte ich möglichst geschickt füllen($action="add") und auslesen($action="get"). Leider sind meine Kenntnisse, der OOP unter Perl momentan nicht so besonders. Den folgenden Code habe ich aktuell geschrieben, aber irgendwie kann ich nicht auf das Array in der Instanz $pp1 zugreifen. Was mache ich falsch?

  
{  
  package Parkplatz;  
  
  sub new  
  {  
    my $class=shift;  
    my $self={};  
    bless $self,$class;  
    $self->Childs("new");  
  }  
  
  sub Childs  
  {  
    my $self=shift;  
    my $action=shift;  
    my $child=shift;  
  
    my @childs;  
    if ( $action eq "new" )  
    {  
      @childs=();  
    }  
    elsif( $action eq "add" )  
    {  
      push(@childs,$child);  
    }  
    elsif( $action eq "get" )  
    {  
      @childs;  
    }  
  }  
}  
  
  my $pp1=Parkplatz->new();  
  $pp1->Childs("add","test1");  
  my @test=$pp1->Childs("get");  
  print test[0];  

Danke im Voraus

Slaughter

  1. Was mache ich falsch?

    Wie lautet die Fehlermeldung?

    Struppi.

    1. Wie lautet die Fehlermeldung?

      FM:
      Can't call method "Childs" without a package or object reference at D:\testoop.pl line 39.

      Gruß

      Slaughter

      1. Wie lautet die Fehlermeldung?

        FM:
        Can't call method "Childs" without a package or object reference at D:\testoop.pl line 39.

        Naja, die ist doch Aussagekräftig, was ist jetzt das Problem?

        Struppi.

        1. Wie lautet die Fehlermeldung?

          FM:
          Can't call method "Childs" without a package or object reference at D:\testoop.pl line 39.

          Naja, die ist doch Aussagekräftig, was ist jetzt das Problem?

          Struppi.

          Das Problem ist, dass ich nicht weiss, wie ich ein Array in einer Instanz über die Methode Childs befüllen kann, mit der FM kann ich leider nichts anfangen, da ich aus meiner Sicht die Objekt Referenz in $pp1 befindet und ich die Methode Childs darüber aufrufe.

          Gruß

          Slaughter

          1. Struppi.

            Bitte zitiere nur das worauf du antwortest, Danke.

            Das Problem ist, dass ich nicht weiss, wie ich ein Array in einer Instanz über die Methode Childs befüllen kann, mit der FM kann ich leider nichts anfangen, da ich aus meiner Sicht die Objekt Referenz in $pp1 befindet und ich die Methode Childs darüber aufrufe.

            Nein $ppl ist kein Objekt, deine Funktion new gibt kein Objekt zurück, sondern den Rückgabewert des Aufrufs der Funktion Childs (übrigens sollten Funktionen nicht mit Großbuchstaben anfangen, damit kennzeichnest du package Namen)

            Struppi.

  2. ich möchte eine Klasse programmieren, die pro Instanz ein "Child"-Array enthält. Dieses Array möchte ich möglichst geschickt füllen($action="add") und auslesen($action="get"). Leider sind meine Kenntnisse, der OOP unter Perl momentan nicht so besonders. Den folgenden Code habe ich aktuell geschrieben, aber irgendwie kann ich nicht auf das Array in der Instanz $pp1 zugreifen. Was mache ich falsch?

    Dein @child ist nur innerhalb der Sub child gültig, damit bekommst Du bei jedem Aufruf ein "frisches" Array.

    Entweder Du machst die Variable zur Objekteigenschaft:

    package Parkplatz;  
      
    sub new {  
       my $class = shift;  
       my $self = { child => [] };  
       bless $self, $class;  
    }  
      
    sub AddChild {  
      my $self = shift;  
      my $par = shift;  
      push @{$self->{child}}, $child;  
    }  
      
    sub GetChild {  
      my $self = shift;  
      return $self->{child};  
    }
    

    Oder Du machst eine private Variable draus:

    package Parkplatz;  
      
    my @child = ();  
      
    sub new {  
       my $class = shift;  
       bless {}, $class;  
    }  
      
    sub AddChild {  
      my $self = shift;  
      my $par = shift;  
      push @child, $par;  
    }  
      
    sub GetChild {  
      return @child;  
    }
    

    Der Aufruf sähe dann so aus:

    Variante 1:

    my $pp1 = Parkplatz->new();  
    $pp1->AddChild('test1');  
    print $pp1->{child}->[0];
    

    Variante 2:

    my $pp1 = Parkplatz->new();  
    $pp1->AddChild('test1');  
    my @test = $pp1->GetChildren();  
    print $test->[0];
    

    Was Du einsetzt, hängt von dem ab, was Du da eigentlich genau vorhast.

    Siechfred

    --
    Chancengleichheit bedeutet nicht, dass jeder einen Apfel pflücken kann, sondern dass der Zwerg eine Leiter bekommt.
    1. Was Du einsetzt, hängt von dem ab, was Du da eigentlich genau vorhast.

      Siechfred

      Danke, ich werde mir das mal in Ruhe ansehen.

      Slaughter

      1. Danke, ich werde mir das mal in Ruhe ansehen.

        Tu das und frag halt nach, wenn was unklar ist.

        Am Rande: Dein Fehler war, dass Du nach dem Blessen noch eine Operation ausgeführt hast. Eine Sub gibt ohne explizites return das Ergebnis eben jener letzten Operation zurück. In Deinem Fall sollte es also so gehen:

        sub new {  
          my $class=shift;  
          my $self={};  
          my $obj = bless $self,$class;  
          # weiter Operationen  
          return $obj;  
        }
        

        Das Problem mit @child würde aber bestehen bleiben.

        Siechfred

        --
        Chancengleichheit bedeutet nicht, dass jeder einen Apfel pflücken kann, sondern dass der Zwerg eine Leiter bekommt.
        1. In Deinem Fall sollte es also so gehen:

          tut es, aber...

          sub new {

          my $class=shift;
            my $self={};
            my $obj = bless $self,$class;
            # weiter Operationen
            return $obj;
          }

            
          Einmal umständlich.  
           ~~~perl
          sub new {  
             my $self= bless{}, shift;  
             # weiter Operationen  
             return $self;  
           }
          

          und er muss aufpassen, falls das Objekt von einem Objekt erzeugt werden soll, also so:

            my $pp1=Parkplatz->new();  
            my $pp2=$pp1->new();  
          
          

          Dann funktioniert das nicht. Daher ist der flexibelste Weg ein Objekt zu erzeugen so:

            sub new {  
              my $self = bless{}, ref $_[0] || $_[0];  
              # tu was  
              return $self;  
            }  
            
          
          

          Struppi.

          1. Daher ist der flexibelste Weg ein Objekt zu erzeugen so:

            Du hast Recht, aber so lange ich Slaughters Wissensstand nicht kenne, meine ich, dass man den zweiten nicht vor dem ersten Schritt machen sollte :)

            Siechfred

            --
            Chancengleichheit bedeutet nicht, dass jeder einen Apfel pflücken kann, sondern dass der Zwerg eine Leiter bekommt.
            1. Daher ist der flexibelste Weg ein Objekt zu erzeugen so:

              Du hast Recht, aber so lange ich Slaughters Wissensstand nicht kenne, meine ich, dass man den zweiten nicht vor dem ersten Schritt machen sollte :)

              Der erste Schritt wäre ja eigentlich gewesen erstmal auf Perldoc hizuweisen. Aber ich hab's ja auch versäumt, also hier mal ein bischen Lektüre für Slaughter:
              http://perldoc.perl.org/perltooc.html
              http://perldoc.perl.org/perlbot.html
              und ncoh
              http://perldoc.perl.org/perlstyle.html (wegen den Großbuchstaben)

              Vieles davon findet sich auch als deutsche Übersetzung in der PerlCommunity

              Struppi.

              1. Hallo,

                danke, ich werde mir die Infos durchlesen um meinen OOP unter Perl Wissensstand zu erhöhen.

                Gruß

                Slaughter