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
#!/usr/bin/perl use warnings; use strict; { package Lamp; use warnings; use strict; sub new { my $classname = shift; my $self = {status => "off"}; return bless($self, $classname); } sub switchOn { my $self = shift; print "Click. Light.\n"; $self->{status} = "on"; } sub switchOff { my $self = shift; print "Click. Darkness.\n"; $self->{status} = "off"; } sub printStatus { my $self = shift; print "The lamp is " . $self->{status} . " now.\n"; } } my $lamp = Lamp -> new(); $lamp -> printStatus(); $lamp -> switchOn(); $lamp -> printStatus(); $lamp -> switchOff(); $lamp -> printStatus(); print $lamp->{status}."\n";
2012-02-21T15:20:23 hlubenow6. Setzt ihr überhaupt viel OOP mit Perl ein
2012-02-21T15:20:23 hlubenow1. Ist
wirklich die richtige Notation, um an die Attribute heranzukommen oder gibt es noch eine einfachere, kürzere?
Quote2. Wie erhält man von außerhalb Zugriff auf $classname? Wieso erhält das überhaupt einen Wert? Wenn ich Lamp->new() aufrufe, übergebe ich doch gar kein Argument.
Lamp->new
Quote3. Könnte man die geschweiften Klammern um das Package auch weglassen?
Quote4. Arbeitet man bei diesem $self wirklich mit einer Referenz auf einen anonymen Hash? Scheint mir ebenfalls eine recht komplizierte Kontstruktion.
Quote5. Oder gibt es vielleicht überhaupt einen Weg, das alles besser zu schreiben?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use v6;
class Lamp {
has $.status = 'off';
method switchOn { say "Click. Light."; $!status = 'on' }
method switchOff { say "Click. Darkness."; $!status = 'off' }
method printStatus { say "The lamp is $!status now" }
}
my $lamp = $lamp.new;
$lamp.printStatus;
$lamp.switchOn;
$lamp.printStatus;
$lamp.switchOff;
$lamp.printStatus;
say $lamp.status;
Quote6. Setzt ihr viel OOP mit Perl ein oder kommt ihr meist ohne aus?
Schreibt ihr z.B. Tk-Anwendungen objektorientiert oder eher nicht?
2012-02-21T15:33:20 moritz2012-02-21T15:20:23 hlubenow1. Ist
wirklich die richtige Notation, um an die Attribute heranzukommen oder gibt es noch eine einfachere, kürzere?
Innerhalb der Klasse ist das richtig. Von ausserhalb sollte man gar nicht auf Attribute zugreifen, sondern nur Methoden aufrufen.
Quotedenn wenn du vererbung hast, würdest du somit an der erbenden klasse vorbei das attribut direkt aufrufen.
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
package Foo; use strict; use warnings; sub new{ my $class = shift; return bless {foo => 123}, $class; } # public sub foo{ my $self = shift; return $self->{foo}; } package Foo::Bar; use strict; use warnings; @Foo::Bar::ISA = qw(Foo); # Overload sub new{ my $class = shift; return bless {}, $class; } package main; use strict; use warnings; use Data::Dumper; my $foo = Foo->new; my $bar = Foo::Bar->new; print Dumper $foo, $bar; print $bar->foo; # Use of uninitialized value ...
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
package A; sub new { my ($class, %args) = @_; bless \%args, $class; } sub foo { return shift->{foo} } sub printFoo { my ($self) = @_; # hier wirdleider direkt auf foo zugegriffen statt über den accessor! my $foo = $self->{foo}; say "foo is $foo"; } package B; @ISA = qw/ A /; sub foo { my ($self) = @_; return $self->foo() + 1 } package main; my $B = B->new( foo => 23 ); $B->printFoo;
Quoteda printFoo aus klasse A sich aber nicht an die accesors hält, bekomme ich die ausgabe 23.
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
package A; sub new { my ($class, %args) = @_; bless \%args, $class; } # access foo sub _foo { return shift->{foo}; } sub printFoo { my $self = shift; return $self->_foo; } package B; @B::ISA = qw/ A /; # access foo OVERLOAD sub _foo { return shift->{foo} + 1; } package main; my $ob = B->new( foo => 23 ); print $ob->printFoo; # A: 23, B: 24
2012-02-21T17:48:35 rostiQuoteda printFoo aus klasse A sich aber nicht an die accesors hält, bekomme ich die ausgabe 23.
Bei mir funktioniert das mit Accessor einwandfrei, ohne printFoo() überschreiben zu müssen.
QuoteIch habe Klassen in denen sehr, sehr viele Methoden notiert sind, unvorstellbar, für jeden Attributzugriff einen extra Accessor haben zu müssen.
Quoteda schreibe ich ja, dass es eben NICHT funktioniert, wenn man direkt auf das attribut zugreift.
2012-02-21T15:36:54 pq2012-02-21T15:33:20 moritzInnerhalb der Klasse ist das richtig. Von ausserhalb sollte man gar nicht auf Attribute zugreifen, sondern nur Methoden aufrufen.
sehe ich anders. auch innerhalb der klasse ist der aufruf von accessormethoden sauberer, ausser in den accessors selber.
denn wenn du vererbung hast, würdest du somit an der erbenden klasse vorbei das attribut direkt aufrufen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#!/usr/bin/perl package main; use strict; use warnings; use Data::Dumper; my $foo = Foo->new; print Dumper $foo; # $VAR1 = bless( [], 'Foo' ); package Foo; use strict; use warnings; sub new{ my $class = shift; return bless [], $class; } 1;
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#!/usr/bin/perl use warnings; use strict; package Konto; sub new { my $classname = shift; my $nummer = shift; my $name = shift; my $self = {nummer => $nummer, name => $name, sollsum => 0, habensum => 0, buchungen => [], saldo => 0, saldoisin => ""}; return bless($self, $classname); } sub bucheSoll { my $self = shift; my $soll = shift; my $bsatz = shift; $self->{sollsum} += $soll; push(@{$self->{buchungen}}, $bsatz); } sub bucheHaben { my $self = shift; my $haben = shift; my $bsatz = shift; $self->{habensum} += $haben; push(@{$self->{buchungen}}, $bsatz); } sub calcSaldo { my $self = shift; if ($self->{sollsum} > $self->{habensum}) { $self->{saldo} = $self->{sollsum} - $self->{habensum}; $self->{saldoisin} = "soll"; } elsif ($self->{sollsum} < $self->{habensum}) { $self->{saldo} = $self->{habensum} - $self->{sollsum}; $self->{saldoisin} = "haben"; } else { $self->{saldo} = 0; $self->{saldoisin} = "0"; } } sub clear { my $self = shift; $self->{sollsum} = 0; $self->{habensum} = 0; $self->{buchungen} = []; $self->{saldo} = 0; $self->{saldoisin} = ""; } package main; my $bankkonto = Konto -> new(1200, "Bank"); $bankkonto -> bucheHaben(13.36, "01.03.2011;X123;Telefonkosten;13,36;4920;1200"); $bankkonto -> bucheHaben(2.54, "01.03.2011;X123;VSt. Telefonkosten;2,54;1577;1200"); $bankkonto -> calcSaldo(); print "Saldo: $bankkonto->{saldo}\n"; print "Soll oder Haben: $bankkonto->{saldoisin}\n";
$bankkonto -> bucheHaben(13.36, "01.03.2011;X123;Telefonkosten;13,36;4920;1200");
$ob->method(date => '1.1.1970', cost => 123);
1 2 3 4 5 6 7
sub method{ my $self = shift; my %args = ( date => undef, cost => undef, @_); }
2012-02-22T09:33:51 rosti
iab sf $self->{