He tenido este requisito exacto varias veces en el pasado, y hoy en día que en realidad tenía que hacerlo desde la metaclase, que significaba que no pellizcar BUILD permitido. De todas formas me sentí que sería bueno compartir ya que básicamente hace exactamente lo éter mencionado:
'Esto permitiría marcar atributos "esto es vago, porque depende en otros valores de atributos para ser construido, pero quiero . que sea empujado antes de acabados de construcción "'
sin embargo, derp derp no tengo ni idea de cómo hacer un módulo CPAN así que aquí tiene algunos códigos: https://gist.github.com/TiMBuS/5787018
Poner lo anterior en Late.pm y entonces puedes usar i t gusta así:
package Thing;
use Moose;
use Late;
has 'foo' => (
is => 'ro',
default => sub {print "setting foo to 10\n"; 10},
);
has 'bar' => (
is => 'ro',
default => sub {print 'late bar being set to ', $_[0]->foo*2, "\n"; $_[0]->foo*2},
late => 1,
);
#If you want..
__PACKAGE__->meta->make_immutable;
1;
package main;
Thing->new();
#`bar` will be initialized to 20 right now, and always after `foo`.
#You can even set `foo` to 'lazy' or 'late' and it will still work.
¿No deberías estar usando 'default' para eso? Pensé que el objetivo de 'vago' era posponer la creación del valor del atributo hasta el primer uso. Si necesita que todos los atributos se configuren en la construcción del objeto, 'default' parece más útil. O bien, puede proporcionar su propio método 'BUILD'. –
Este es un modismo bastante común y hay algunas razones decentes para ello. – hobbs
Básicamente, puede hacer todo el trabajo en 'BUILD' en su lugar, pero es mejor tener un método por atributo. Y si va a tener un método por atributo para calcular el valor, entonces bien podría ser un generador. Pero si un constructor va a acceder a otros atributos, entonces el atributo creado debe ser flojo para asegurarse de que se haya inicializado. Y no hay una opción de atributo "vago, sino solo * un poco * holgazán" :) – hobbs