uso para imagenes emplea ejemplo como atributos atributo agregar perl moose

perl - para - En Moose, ¿cómo modifico un atributo cada vez que se establece?



en html, el atributo alt se emplea para (4)

Si tiene un atributo que debe modificarse cada vez que se establece, ¿hay alguna manera ingeniosa de hacerlo sin tener que escribir el elemento de acceso usted mismo y mezclarlo directamente con el contenido de $self , como se hace en este ejemplo?

package Foo; use Moose; has ''bar'' => ( isa => ''Str'', reader => ''get_bar'', ); sub set_bar { my ($self, $bar) = @_; $self->{bar} = "modified: $bar"; }

Consideré trigger , pero parecía requerir el mismo enfoque.

¿Trabajar directamente con la referencia de hash en $self considera una mala práctica en Moose o me preocupa que no haya un problema?


Creo que usar la referencia hash está bien dentro de un trigger como este:

package Foo; use Moose; has ''bar'' => ( isa => ''Str'', is => ''rw'', trigger => sub { $_[0]->{bar} = "modified: $_[1]" }, );

El disparador también se dispara cuando la barra arg pasa con el constructor. Esto no sucederá si define su propio método set_bar o con un modificador de método.

Re: referencia de hash: generalmente creo que es mejor atenerse a los definidores / captadores de atributos, a menos que (como con el activador anterior) no haya una alternativa fácil.

Por cierto, puede encontrar este post reciente sobre desencadenantes por nada muy interesante.


No estoy seguro de qué tipo de modificación necesita, pero es posible que pueda lograr lo que necesita utilizando la coacción de tipo:

package Foo; use Moose; use Moose::Util::TypeConstraints; subtype ''ModStr'' => as ''Str'' => where { /^modified: /}; coerce ''ModStr'' => from ''Str'' => via { "modified: $_" }; has ''bar'' => ( isa => ''ModStr'', is => ''rw'', coerce => 1, );

Si utiliza este enfoque, no se modificarán todos los valores. Cualquier cosa que pase la validación como ModStr será utilizada directamente:

my $f = Foo->new(); $f->bar(''modified: bar''); # Set without modification

Esta debilidad podría estar bien o podría hacer que este enfoque sea inutilizable. En las circunstancias adecuadas, incluso podría ser una ventaja.


Puede utilizar el modificador de método ''alrededor''. Algo como esto:

has ''bar'' => ( isa => ''Str'', reader => ''get_bar'', writer => ''set_bar'' ); around ''set_bar'' => sub { my ($next, $self, $bar) = @_; $self->$next( "Modified: $bar" ); };

Y sí, trabajar directamente con los valores de hash se considera una mala práctica.

Además, por favor no asuma que la opción que presenté es necesariamente la correcta. El uso de subtipos y la coerción será la solución correcta la mayor parte del tiempo; si piensa en su parámetro en términos de un tipo que posiblemente pueda reutilizarse en su aplicación, el diseño del mismo será mucho mejor que el tipo de modificaciones arbitrarias que se pueden utilizar. hecho usando ''alrededor''. Ver respuesta de @daotoad.


Si tratar con el hash directamente le causa preocupación, puede especificar un escritor alternativo y luego usarlo desde su propio escritor "público" con el nombre apropiado.

package Foo; use Moose; has ''bar'' => ( isa => ''Str'', reader => ''get_bar'', writer => ''_set_bar'', ); sub set_bar { my $self = shift; my @args = @_; # play with args; return $self->_set_bar(@args); }

Esto, o los factores desencadenantes, me parecerían un buen enfoque dependiendo de cuándo y cómo necesita manipular los argumentos.

(descargo de responsabilidad: código no probado escrito desde la memoria, explorando SO en una netbook con acceso de borde inestable)