[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