2009-02-18 5 views
7

Moose::Manual::Attributes estados:¿Por qué el constructor de Moose toma un valor de cadena?

Como alternativa al uso de una referencia subrutina [por defecto], en su lugar puede suministrar un método constructor para su atributo: ... Esto tiene varias ventajas. En primer lugar, mueve un trozo de código a su propio método con nombre, lo que mejora la legibilidad y la organización del código.

lo tanto, su atributo podría definir un valor predeterminado de esta manera:

has attr => (
    is => 'ro', 
    builder => 'subroutine' 
); 
sub subroutine { 
    # figure out and return default value 
} 

No entiendo por qué esto tiene que ser separado de forma predeterminada. ¿No podría simplemente pasar una referencia a una subrutina con nombre?

has attr => (
    is => 'ro', 
    default => \&subroutine 
); 

Y ¿no sería mejor práctica de programación, ya que tiene la garantía de no hacer referencia accidentalmente a una subrutina que no existe? Se estaría refiriendo al método con una referencia lógica en lugar de una referencia simbólica.

Respuesta

14

Cuando el constructor se llama, esto sucede:

$object->$builder 

Si constructor es una cadena (digamos build_attr), los usuarios pueden escribir su propio método build_attr en una subclase y que se llamará. Esto hace que el valor predeterminado sea extensible a través de un simple mecanismo de método con nombre.

Si se trata de una referencia a una subrutina, la referencia se toma en el paquete de la clase original, lo que significa que no se puede anular de la misma manera.

10

No es una referencia "simbólica". El constructor es un método nombre. Eso significa que es heredable y composable desde un rol. Si pasa una referencia de subrutina, esa referencia debe existir en el mismo paquete (o estar completamente calificado).

Estoy bastante seguro de que explico esto en el manual. ¿No está claro?

+0

Bueno, sé que no es una referencia en el sentido de Perl; Estaba pensando que una mejor práctica de programación sería pasar una referencia real a una subrutina con nombre, por las razones que mencioné. Sin embargo, tienes razón; el resto del manual muestra por qué es deseable ... – skiphoppy

+1

Tenga en cuenta el párrafo que comienza "Esto tiene varias ventajas. Primero ..."; tal vez ayudaría mover parte de la siguiente sección hasta allí para dar seguimiento, de modo que el párrafo brinde más que solo esa ventaja, un poco antes para aquellos que se lo estén preguntando. – skiphoppy

7

Subclassing.

constructor especifica un nombre de método a llamar, por lo

package Something; 
use Moose; 

extends 'YourClass'; 

sub subroutine { <some other default> } 

tendría algo :: subrutina llamada para un constructor de 'subrutina', mientras que si se ha utilizado el estilo subref entonces el YourClass :: subrutina sería llamado en su lugar porque ha hecho una referencia directa a la subrutina en lugar de dejarla pasar por el envío del método.

Cuestiones relacionadas