[Triangulo-pm] [Perl - Intermediário] #1 Acessores
Adriano Ferreira
aferreira em shopzilla.com
Sábado Maio 17 15:56:22 PDT 2008
[Perl - Intermediário] #1 Acessores
Programação Orientada a Objeto em Perl é algo poderoso, embora cheio de
idiossincracias (como "objetos são referências abençoadas"). A forma
como classes são criadas (com "packages") e métodos são escritos (com
"subs") tem uma série de vantagens e desvantagens.
Uma das coisas mais comuns é criar *setters* e *getters* para os
atributos de um objeto, como uma representação de "CD" que deve ter
atributos como "id", "title", "artist". Para criar estes métodos, a
forma tradicional é decidir pela representação de um objeto como um
*hash ref* e escrever:
# CD.pm
package CD;
sub new {
my $proto = shift;
my $class = ref $proto || $proto;
my $obj = bless {@_}, $class;
return $obj;
}
sub id {
my $self = shift;
if (@_) { $self->{id} = shift; }
$self->{id};
}
sub title {
my $self = shift;
if (@_) { $self->{title} = shift; }
$self->{title};
}
sub artist {
my $self = shift;
if (@_) { $self->{artist} = shift; }
$self->{artist};
}
"the truth at the end of the package";
onde os acessores funcionam simultaneamente como "setters" e "getters"
(o que é comum em muita programação Perl) e se usa desta forma:
use CD;
my $cd1 = CD->new();
$cd1->id(1);
$cd1->title('Born Again');
$cd1->artist('Black Sabbath');
# perceba que esta apenas é uma ilustração
# didática e ingênua:
# o objeto pode ser criado
# e as variáveis automaticamente
# preenchidas simultaneamente
# por um comando como:
#
# $cd1 = CD->new( id => 1, title => 'Born Again', artist =>
'Black Sabath' );
print "title: ", $cd1->title, "\n";
# imprime "title: Black Sabbath\n"
Obviamente que o código acima é claramente redundante e chato. Se Perl é
deste jeito, talvez programar em Java tenha mais *sex appeal*. Pelo
menos lá, eu nem tenho de ficar referenciando o objeto sobre o qual o
método foi invocado (o *$self*).
package namespace.too.long.for.seemingly.respectful.java.code.CD;
private int id;
private String title;
private String artist;
# getters
int get_id() { return id; }
int get_title() { return title; }
int get_artist() { return artist; }
# setters
void set_id( int id ) {
this.id = id;
}
void set_title( String title ) {
this.title = title;
}
void set_artist( String artist ) {
this.artist = artist;
}
Pensando bem, Java é uma meleca com estas declarações todas, e tipos,
etc. (A frase "é uma meleca" não foi muito técnica e talvez deva ser
substituída por algo como "é tão prolixo quanto". Mas no fim, é uma
embolação que "meleca" até define bem.)
Mas não precisa ser assim. (Estou falando do código Perl. Para o Java,
você pode usar o Eclipse para fazer o serviço sujo e repetir todo este
código para você.) Usar "Class::Accessor" é uma alternativa (entre
tantas outras) e o nosso código anterior se reduz a:
# CD.pm
package CD;
use base qw( Class::Accessor );
BEGIN {
__PACKAGE__->mk_accessors(qw( id title artist ));
}
42; # the truth at the end of the package
O mesmo código ilustrado antes para ser usado para construir instâncias
de "CD" continua válido. Nenhuma repetição desnecessária e os acessores
são automaticamente criados para você (inclusive poupando-o de
inconvenientes com erros de nomes de variáveis e tal).
Triangulo-pm, 2008-05-17 19:50
Mais detalhes sobre a lista de discussão Triangulo-pm