Alexander (HH): Getter/Setter

Beitrag lesen

Moin Moin!

wie lernen z.Z. absolute Basics in Perl

Ganz offenbar ist der Lehrer nicht so ganz auf dem Laufenden. Indirect Object Syntax ist etwas, was man sich besser gar nicht mehr angewöhnt. Deswegen scheinst Du auch einige Verständnisprobleme zu haben.

und bei mir scheitert es schon bei einem Variablenaufruf eines anderen Packages.

Du redest von Variablen und Packages, kommst aber andererseits mit OOP-Konstrukten an. Perl kann beides, aber es gibt dabei feine Unterschiede. Was willst Du?

#!perl -w

use strict;
package IDependencies;
my $requirementFulfilled;
package initialize;
sub new (){
my $self=shift;
my $newInst={};
bless($newInst,$self);
}

Da fehlt für meinen Geschmack ein return. Implizit gibt Perl den Wert des letzten Statements zurück, das ist bless, das wiederum gibt seinen ersten Parameter zurück.

Außerdem ist $self zwar kein reserviertes Wort wie z.B. print, aber es gibt eine sehr weit verbreitete Konvention, $self so zu benutzen wie this in Javascript und Java, nämlich als Objekt-Instanz.

In dieser Routine ist $self aber der Klassenname, nicht die Objekt-Instanz. Die steht in $newInst.

Besser:

  
sub new  
{  
    my $class=shift;  
    my $self=bless {},$class;  
    return $self;  
}  

Wenn Du neue Objekt aus bestehenden generieren willst, der Construktor also auch als Instanz-Methode aufrufbar sein soll, sieht das so aus:

  
sub new  
{  
    my $proto=shift;  
    my $class=ref($proto)||$proto;  
    my $self=bless {},$class;  
    return $self;  
}  

package Method;
use base 'initialize';
my $name;
sub IsFullfilled()
{
print $requirementFulfilled = 0;

}

Was geht denn hier ab?

Was macht $name da?

Warum liefert eine Funktion, von der man aufgrund ihres Namens annehmen sollte, dass sie einen boolschen Wert zurückliefert, nichts zurück? (Technisch gesehen liefert sie zurück, ob print funktioniert hat oder nicht.)

Und warum setzt die Funktion als Seiteneffekt die Variable $requirementFulfilled auf 0?

package Combinatorics;
use base 'initialize';

use base macht viel Theater um Dinge, die kaum jemand benutzt. use parent ist mit gleicher Syntax deutlich schlanker.

my %hashtable;

package main;

my $Method = new Method ->IsFullfilled();

Indirect Object Syntax. Pfui!

Du meinst:

my $Method=Method->new()->IsFullfilled();

Das ist mein bisheriger Code.

Durchaus verbesserungsfähig, siehe oben.

perlobj, perltoot, perlboot und perltooc hast Du gelesen und verstanden?

Am Ende soll in einer Hash-Table als Key die Instanz einer Method stehen und als Value entweder eine Instanz einer anderen Method, nichts oder aber erneut ein Hash-Table in dem widerrum das selbe stehen kann.

Nun hab ich ein gewaltiges Problem im package main auf die Variable von Combinatorics zuzugreifen und Einträge zu ändern.

Nochmal: Willst Du OOP oder willst Du prozedural arbeiten?

In reinem OOP solltest Du in den einzelnen Klassen überhaupt keine Variablen rumfliegen haben, sondern mit Objekt-Attributen arbeiten.

Wenn Du kein OOP haben willst, kannst Du aus Packages heraus Variablen exportieren, siehe Exporter. Die am meisten überlesene Stelle in der Exporter-Dokumentation ist leider Exporting without inheriting from Exporter, denn das Erben vom Exporter hat viele unerwünschte Seiteneffekte.

Notwendiger Code in Packages, die etwas exportieren sollen:

  
use Exporter qw( import );  
our @EXPORT_OK=( ... );  

(Kein @ISA, kein require. Das ist prähistorischer Cargo Cult, der in neuem Code nichts mehr verloren hat.)

Testweise hab ich das Script erweitert:

package combinatorics;
%hashtable = (Teststring=>"Teststring",Teststring2 =>"Teststring2");
print "$hashtable{'Teststring'}Teststring  $hashtable{'Teststring2'} Teststring2";


>   
> Funktioniert auch tadellos,  
  
Glaub ich bei aktivem strict nicht so ganz ...  
  

> aber:  
>   
> Ich will ja in meiner Main auf den Hash zugreifen und ihn ändern können.  
  
Warum fummelst Du dann mit OOP herum?  
  

> und im Prinzip etwas schreiben wie:  
>   
> package main;  
>   
> my $Method = new Method;  
> my $2Method = new Method;  
  
$2Method ist kein gültiger Name.  
  
Und gewöhn Dir die Indirect Object Notation besser gleich wieder ab, auch wenn sie hübsch nach C++/C#/Java aussieht, macht sie Perl mehr Arbeit und Dir auf Dauer nur Ärger.  
  
my $Method=Method->new();  
my $Method2=Method->new();  
  

> my $combinatorics = new Combinatorics;  
  
$combinatorics ist eine Instanz von Combinatorics.  
  

> $combinatorics::%hashtable = ($Method=>$2Method)  
  
Was soll das werden?  
  
Wenn Du auf die (per our oder use vars deklarierte) Variable %hashtable im Package Combinatorics zugreifen willst, geht das so:  
  
`%Combinatorics::hashtable=(...)`{:.language-perl}  
  
Das widerspricht aber jedem Ansatz von OOP und wird Dir auf lange Sicht nur Ärger machen.  
  
  
Wenn Du einen Accessor stricken willst, pack den ins Package Combinatorics und lasse den auf die Variable zugreifen, die entspricht dann am ehesten einem Klassen-Attribut.  
  
  
~~~perl
  
package Combinatorics;  
  
use strict;  
use warnings;  
  
my %hashtable;  
  
# ...  
  
sub set_hashtable  
{  
    my $self=shift;  
    %hashtable=(@_);  
    return $self;  
}  
  
# ...  

Falls es irgendjemandem helfen sollte mein Problem zu verstehen;
In C# würd ich,um das selbe zu realisieren, schreiben:

public class Combinatorics {

Dictionary <initialize,initialize> hashtable = new Dictionary <initialize,initialize>();

}
Method method = new Method();
Method 2method = new Method();

Ich glaube nicht, dass in C# 2method ein gültiger Name ist.

Combinatorics combinatorics = new Combinatorics();

combinatorics.hashtable.Add(method,2method)

Hast Du mal versucht, das zu compilieren?

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".