[Cascavel-pm] métodos de acesso mais sofisticados (era: acessórios de alteração mais sofisticados)

Luis Motta Campos luismottacampos em yahoo.co.uk
Quarta Janeiro 9 02:00:18 PST 2008


Alceu R. de Freitas Jr. wrote:
> --- Luis Motta Campos <luismottacampos em yahoo.co.uk>
> escreveu:
> 
>> O que exatamente você quer fazer que o
>> Class::Accessor não te oferece
>> pronto, Alceu?
> 
> Talvez ele ofereça... mas eu ainda não descobri como.
> 
>> Eu ainda não entendi o que os teus métodos de acesso
>> tem de especiais.
>> Pode ser distração minha, também...
> 
> Ou meus emails andam confusos demais... De qualquer
> forma, vamos para um exemplo que é mais fácil.
> 
> Quando eu criei módulos para acessar recurso pacotes
> DTS, eu encapsulei o objeto fornecido via COM através
> do módulo Win32::OLE. Até então eu só utilizava
> métodos de leitura (get_) para ler os atributos.
> 
> Agora resolvi ir mais longe e oferecer métodos para
> alterar esses atributos. Mas aí tenho um problema de
> sincronização, eu tenho que alterar ambos os objetos
> (o da classe DTS e o objeto obtido via COM).
> 
> O objeto via COM é referenciado por um atributo
> "oculto" chamado _sibling. Eu só conseguiria alterar
> um atributo e sincronizar o valor entre os dois
> objetos se esse atributo _sibling estiver disponível.
> Se eu fosse escrever isso na mão, eu teria um trabalho
> chato para fazer.
> 
> Eu imagino algo assim:
> 
> sub set_attribute {
> 
>     my $self = shift;
>     my $attrib = shift;
>     my $value = shift;
> 
>     die "não consigo configurar nada sem _sibling"
> unless (defined($self->{_sibling}));
> 
>     #restante do código viria aqui
> 
> }

Parece que você interrompeu isso bruscamente.

Você está no caminho certo; precisa construir um método genérico capaz
de, dado o nome de um atributo e o valor que se deseja atribuir, realize
a alteração.

Mas isso é apenas metade do seu problema. Você tem de gerar os métodos
de acesso, depois.

De qualquer forma, se você conseguir construir uma lista de atributos
interessantes (talvez consultando o tal "_sibling"?), pode usar o
Class::Accessor para criar os teus métodos de acesso.

Para que os teus métodos de acesso façam o que você espera, você precisa
sobrecarregar os métodos Class::Accessor::get() e
Class::Accessor::set(), para que eles saibam o que alterar e como (no
caso do set()) e o que consultar e como devolver valores (no caso do get()).

Assim, ao invés de implementar set_attribute(), você precisa implementar
set(), na sua classe, e garantir as chamadas necessárias para o
Class::Accessor:

#!perl
use strict;
use warnings;

use base qw( Class::Accessor );
__PACKAGE__->mk_accessors( @Lista_De_Atributos_Calculada_Pelo_Alceu );

=pod

=head2 B<C<get($key)>>
=head2 B<C<get(@keys)>>

Métodos de acesso usados pelo C<Class::Accessor> para gerar
automaticamente os métodos de acesso de cada atributo.

C<get($key)> lê e devolve um valor do atributo cujo nome é C<$key>.

C<get(@keys)> lê e devolve os valores dos atributos cujos nomes estão
listados em C<@keys>.

=cut

sub get {
  # você já escreveu este método, provavelmente,
  # é o teu método de leitura de atributos.
}

=pod

=head2 B<C<set($key, $value)>>
=head2 B<C<set($key, @values)>>

Métodos de acesso usados pelo C<Class::Accessor> para gerar
automaticamente os métodos de acesso de cada atributo.

C<set($key, $value)> guarda o valor C<$value> no atributo nomeado por
C<$key>.

C<set($key, @values)> guarda B<todos> os valores passados em C<@values>
no atributo nomeado por C<$key>.

=cut

sub set {
  # Este é possivelmente o método que você
  # começou a me escrever lá em cima, no começo deste email.
}

__END__

Espero que isso ajude.
Se você precisar de mais ajuda, por favor não se sinta constrangido - é
muito difícil eu ter uma oportunidade de ajudar você,

-- 
Luis Motta Campos (a.k.a. Monsieur Champs) is a software engineer,
Perl fanatic evangelist, and amateur {cook, photographer}



Mais detalhes sobre a lista de discussão Cascavel-pm