Thread Perl OOP (12 answers)
Opened by sid burn at 2006-09-21 19:24

sid burn
 2006-09-22 12:52
#70143 #70143
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Quote
also mir kommt dein aufwand übertrieben vor.

Mir auch. ;)
Quote
du möchtest dir die arbeit sparen, add_* methoden zu schreiben, musst
aber letztendlich doch für jede attribut-klasse so eine methode schreiben,
und jetzt sagst du, du möchtest dir sparen, die accessor-methoden
zu schreiben. da hätte ich zuerst angefagen zu sparen, und da
gibt es auch schon lange module für, die dir das abnehmen (eben z.B.
CPAN:Class::Accessor). und wenn du es selbst machst,
solltest du auch nicht eval nehmen (ich vermute, du meintest
string-eval), sondern das ist in der regel für sowas unnötig. methoden
kannst du einfach mit *$subname = sub { my ($self) ... }
anlegen.

Das habe ich so schon Implementiert. Also die Methoden über Typeglobs angelegt anstatt String eval. Mit eval() meinte ich eher Generell eine Möglichkeit der Automatischen Code Generierung.

Quote
wie gesagt, dein ansatz kommt mir sehr kompliziert vor, und ich habe auch noch nicht begriffen, was du dir dadurch letzendlich sparst.

Sparen tue ich dadurch nichts. Ich habe meine Unterschiedlichen Attribute. Als erstes werden diese Attribute nicht direkt abgespeichert, sondern später aus einer Datenbank ausgelesen. Dafür möchte ich eine Klasse schreiben um das anlegen und das ändern der Werte über eine Klasse zu machen.

Zum anderen kommt es z.B. vor das ich das Attribut "duration" habe, das die zeit enthält wann der benutzer abläuft. In der Datenbank steht natürlich ein Datum. Um jetzt ein Tag hinzuzufügen möchte ich "$user->duration->add(1)" z.B. schreiben. Den 1 Tag drauf zu rechnen macht dann die Methode.

Zum anderen Möchte ich bei normaler Verwendung die duration Lesen/Schreiben wie sonst auch, also so als wenn es eben keine Klasse wäre. Zum anderen wäre es blöd wenn "name" als Attribut implementiert ist also "$user->name" zum setzen und lesen funktioniert. Und ich bei "duration" ständig "duration->get" oder "duration->set" schreibe. Das wirkt irgendwie nicht mehr intuitiv und konsistent.

Allerdings sollte "add" ja nicht mit "user" oder sonstigen Attributen Funktionieren, sondern nur mit "duration". Zum anderen sieht es aber unnatürlich aus wenn ich "$user->add(1)" schreibe. Hier fehlt irgendwie der Bezug zu "duration". Und "duration_add" finde ich unpraktisch.

Zum anderen finde ich gehört die add Methode halt zu Duration, und nicht in eine allgemeine Klasse.

Quote
zudem finde ich, dass ein attribut nur dann selbst ein objekt sein
sollte, wenn es mehr als nureine zahl oder ein string ist. eben
wenn es selbst attribute hat. aus einfachen zahlen-attributen objekte zu
machen, hat auch noch den nachteil, dass es alles langsamer macht.
ein einziger zugriff muss nun plötzlich 2 methoden aufrufen statt einer.

Genau das meinte ich mit "Verschwendung von Klassen". Da teile ich genauer deine Meinung. Deswegen noch meine Frage wie ich es anders machen könnte. Class::Accessor muss ich mir nochmal anschauen, denke aber letztendlich das es letztendlich das selbe macht was ich nachbaue.

Bisher sieht mein Code so aus:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
{ package user;
{ #start lexical scope
my @class_attributes = qw/ name password /;

no strict 'refs';
for my $attribute ( @class_attributes ) {
# Create new Package with Overload
eval 'package '.__PACKAGE__.'::'.$attribute.';'.'use overload \'""\' => \&get;';
# Create method new for new package
*{__PACKAGE__.'::'.$attribute.'::'.'new'} = sub {
die "Not enough Paramters" if @_ < 2;
bless \$_[1], $_[0];
};
# Create method set/get for new package
*{__PACKAGE__.'::'.$attribute.'::'.'get'} = sub { return ${$_[0]} };
*{__PACKAGE__.'::'.$attribute.'::'.'set'} = sub { ${$_[0]} = $_[1] };

# Create Methods in this package to Call the Classes
*{$attribute} = sub {
my $self = shift;
if (@_) { $self->{$attribute}->set(@_) }
else { $self->{$attribute} }
};
}
} #end lexical scope

sub new {
my $self = bless {}, shift;
my %options = @_;
$self->{name} = user::name->new ( $options{name} );
$self->{password} = user::password->new( $options{password} );
return $self;
}
}

my $paul = user->new;
$paul->name("Paulchen");
$paul->password("123456");

my $anne = new user;
$anne->name("anne");
$anne->password("654321");

print $paul->name, "\n", $paul->password, "\n";
print "\n";
print $anne->name, "\n", $anne->password, "\n";


Bisher klappt das ganze wenn ich alles in einer Datei packe, versuche ich aber das package "user" in einem Modul zu packen klappt es nicht mehr. Ich denke es gibt da anscheind Probleme mit Laufzeit/Runtime Kompilation.

EDIT:
Das mit dem Modul klappt doch, und es gab keine Probleme mit der Laufzeit/Kompilierzeit. Hatte nur etwas zusätzliches implementiert, und die Hälfte dabei vergessen. :blush:\n\n

<!--EDIT|sid burn|1158917164-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de

View full thread Perl OOP