2010-10-01 9 views
5

Soy un novato absoluto en Moose y hasta ahora he leído Moose y la mayor parte de Cookbook.¿Cómo puedo acceder a los atributos de solo lectura de los objetos Moose?

Hay algunas cosas que no entiendo. He creado el siguiente paquete:

package MyRange; 

use Moose; 
use namespace::autoclean; 

has [ 'start', 'end' ] => (
    is  => 'ro', 
    isa  => 'Int', 
    required => 1, 
); 

__PACKAGE__->meta->make_immutable; 

1; 

continuación:

use MyRange;  
my $br = MyRange->new(
    start    => 100, 
    end     => 180 
); 

Ahora puedo acceder a mis campos usando, por ejemplo, $br->{start}, pero también puedo modificarlos (aunque son de "solo lectura") usando, por ejemplo, $br->{start}=5000. También puedo agregar nuevas claves como $br->{xxx}=111.

¿E-mail perdiendo cualquier cosa? ¿El objeto no está protegido de alguna manera? ¿Cuál es el significado de ro?

Respuesta

14

Cuando dijo is => 'ro', le indicó a Moose que cree accesadores de solo lectura para usted, es decir, un método de lectura. Se llama a que a medida que

$br->start; 

o

$br->end; 

Ajuste de los atributos que utilice estos métodos dará lugar a una excepción:

$br->start(42); 

Si se hubiera usado is => 'rw', a continuación, lo anterior quiere trabajar y actualizar el valor del atributo.

Lo que está haciendo es acceso hash directo en el objeto, que viola la encapsulación y no debería ser necesario cuando se usa Moose.

El manual de Moose, es decir, todos los documentos del espacio de nombres Moose::Manual explican eso en detalle. Un buen punto de partida para preguntas como esta es probablemente Moose::Manual::Attributes.

+0

+1 ¡Gracias! Un seguimiento, si puedo: tengo algunos campos que no son necesarios. Si no están configurados, e intento acceder a esos valores 'undef' Me gustaría obtener un error. ¿Debo configurar un lector para cada uno de ellos? ¿O quizás para usar algún sub de tipo 'die' en' default'? –

+1

Es posible que desee crear una nueva pregunta para obtener una respuesta más detallada al respecto, pero: ¿Tiene un diseño donde inicialmente no se requieren valores, pero el usuario puede completarlos más tarde utilizando métodos de escritura y debe hacerlo antes de llamar alguna funcionalidad que lo usa? La mayoría de las veces, probablemente debas repensar tu diseño allí, pero en los raros casos en que tenga sentido, mi extensión 'MooseX :: LazyRequire' podría ser útil.Todo lo que hace es hacer un atributo requerido, pero diferir la excepción del tiempo de construcción hasta el momento en que se accede al attr. – rafl

+0

También tenga en cuenta que puede pedirle a Moose que genere métodos 'predicados' para usted. Aquellos que puede usar para verificar explícitamente si se ha establecido un valor para algún atributo a través de los métodos de constructor o escritor. Esto es especialmente útil para los atributos que no son necesarios y para los cuales 'undef' es un valor válido. – rafl

3

Cuando accede al atributo con $br->{start}, está evitando el acceso y está dirigiéndose directamente a la implementación de Moose subyacente. Puedes hacerlo, pero se supone que no debes hacerlo. Además, si Moose cambia la implementación, su código se romperá.

su lugar, debe tener acceso al atributo mediante el método de acceso:

my $start = $br->start; 

Cuando dice que el atributo es 'RO', significa que no se le permite cambiar el valor del atributo utilizando el descriptor de acceso:

$br->start(32); 
Cuestiones relacionadas