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

Adriano Ferreira a.r.ferreira em gmail.com
Terça Janeiro 8 08:00:03 PST 2008


On Jan 8, 2008 10:43 AM, Alceu R. de Freitas Jr.
<glasswalk3r em yahoo.com.br> 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.

Pelo que eu entendi das suas necessidades, acho que o Class::Accessor
pode fazer o que você quer com alguma ajudinha.

> > 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.

Aqui vale lembrar que para fazer o Class::Accessor lhe dar getters e
setters separados segundo o PBP (Perl Best Practices), basta usar

use base qw( Class::Accessor );
__PACKAGE__->follow_best_practices();
__PACKAGE__->mk_accessors( qw( sibling ... ) );

Mas isto é digressão e você provavelmente leu isto na documentação
(http://search.cpan.org/perldoc?Class::Accessor).

> 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
>
> }

Acho que uma das formas possíveis de fazer isto é prestar atenção
nesta recomendação:

"Modifying the behavior of the accessor

Rather than actually modifying the accessor itself, it is much more
sensible to simply override the two key methods which the accessor
calls. Namely set() and get().
"

Assim acho que, sobrepondo o método set(), com um código similar a

# mapa dos atributos dependentes para aqueles de que eles dependem
my %DEPENDENT_FIELDS = (
      attribute => [ qw(sibling) ],
      #sibling não tem dependencias, portanto não é incluído aqui
);

sub set {
   my ($self, $k, $v) = @_;
   for my $dep ( @{$DEPENDENT_FIELDS{$k}} ) {
        die "$dep deve ser definido antes de $k" unless defined
$self->get($dep);
   }
   return $self->SUPER::set( $k, $v );
}

Provavelmente alguma coisa parecida pode ser adaptada para suas necessidades.

Saudações,
Adriano Ferreira

> []'s
>
>
> Alceu Rodrigues de Freitas Junior
> --------------------------------------
> glasswalk3r em yahoo.com.br
> http://www.imortais.cjb.net
> -----------------------------------------------------------------------
> A well-used door needs no oil on its hinges.
> A swift-flowing stream does not grow stagnant.
> Neither sound nor thoughts can travel through a vacuum.
> Software rots if not used.
> These are great mysteries -- The Tao Of Programming, 5.1
>
>
>       Abra sua conta no Yahoo! Mail, o único sem limite de espaço para armazenamento!
> http://br.mail.yahoo.com/
> _______________________________________________
>
> Cascavel-pm mailing list
> Cascavel-pm em pm.org
> http://mail.pm.org/mailman/listinfo/cascavel-pm
>


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