Leser: 41
1
2
3
4
5
# Erwarte eine ArrayRef zur Page 3
$ob->{PGE} = 3;
my $arrayref = $ob->method or die $ob->{ERR};
# affected Rows in $ob->{ROWS}
# Gesamt-Anzahl der Seiten in $ob->{PGS}
2011-03-24T09:09:32 reneeAußerhalb der Klasse ändere ich *NIE* Objektinterna. Das widerspricht der Kapselung, die man mit Objektorientierung auch erreichen will. Außerdem ist bei direkten Zugriffen auf den Hash immer die "Gefahr" der Typos da. Deswegen lege ich in Klassen eine API fest, über die auf die Objektinterna zugegriffen wird.
Wenn ich die Möglichkeit habe, verwende ich Moose. Da ist das Festlegen von Attributen extrem einfach...
2011-03-24T09:52:11 rostiWie kann ich verhindern, dass Attribute an der API vorbei verändert werden?
2011-03-24T09:56:20 pqwer selber in dem objekt rummanipuliert, was nicht dokumentiert ist, hat halt selber schuld.
2011-03-24T09:09:32 reneeAußerhalb der Klasse ändere ich *NIE* Objektinterna. Das widerspricht der Kapselung, die man mit Objektorientierung auch erreichen will. Außerdem ist bei direkten Zugriffen auf den Hash immer die "Gefahr" der Typos da. Deswegen lege ich in Klassen eine API fest, über die auf die Objektinterna zugegriffen wird.
2011-03-24T09:09:32 reneeAußerhalb der Klasse ändere ich *NIE* Objektinterna. Das widerspricht der Kapselung, die man mit Objektorientierung auch erreichen will.
1 2 3 4 5 6 7 8 9 10 11
package InternaTest; # boilerplate sub new { my $self = bless {}, shift; $self->{flasch} = 0; return $self; } 1;
1 2 3 4 5 6
use InternaTest; my $obj = InternaTest->new; if ( $self->{flasch} ) { print "test\n"; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
package InternaTest; # boilerplate sub new { my $self = bless {}, shift; $self->is_false( 0 ); return $self; } sub is_false { my ($self,$value) = @_; $self->{flasch} = $value if @_ == 2; return $self->{flasch}; } 1;
1 2 3 4 5 6
use InternaTest; my $obj = InternaTest->new; if ( $self->is_false ) { print "test\n"; }
2011-03-28T12:41:56 reneeJa, wenn Du - aus welchen Gründen auch immer - etwas an den Objektinterna änderst, weißt Du nicht, wo Du überall Code anpassen musst. Selbst wenn Du es weißt, musst Du es an unnötig vielen Stellen anpassen.
Wenn Du Methoden hast, die die Interna verstecken, dann musst Du nur die Methoden an sich anpassen, aber nicht die Aufrufe etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
sub param { my $self=shift; my $name=shift; if(@_) { my $val=shift; my $method="set_$name"; #croak("use method $method(<value>)") if($self->can($method)); $self->$method($val) if($self->can($method)); return 0 unless(exists($self->{$name})); $self->{$name}=$val; return 1; } my $method="get_$name"; #croak("use method $method(<value>)") if($self->can($method)); $self->$method() if($self->can($method)); return undef unless(exists($self->{$name})); return $self->{$name}; }
2011-03-24T08:52:23 rostiHi,
den eigenen Stil zu finden ist ein langer Weg und manchmal auch eine Sackgasse.
$u->insert($anz); # $u ist eine Instanz von Shop.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
# meta-method insert/update
sub insert{
my $self = shift;
my $anz = shift or return;
my $url = $self->{URL};
return if defined $self->{COKNA}; # Cookie nicht angenommen
my $dbo = myBase::Warenkorb->new or do{
$self->{body} .= qq(<p>Kein Zugriff auf DB</p>);
return;
}; # exception {RaiseError}
$dbo->insert(sid => $self->{SID}, url => $url, anz => $anz);
}
1
2
3
4
5
6
sub insert{
my $self = shift;
$self->{ANZ} = shift; # zugriff interna, ok
my $dbo = Shop::Warenkorb->new; # inherit from Shop
$dbo->insert; # keine Parameter
}