perl - ¿En qué se diferencian los roles y las características de los alces?
moose (2)
Esta es la única diferencia en cómo Moose usa los términos "Rasgo" y "Rol". La documentación y las API de Moose a menudo usan el término "rasgos" como "Roles aplicados a las metaclases". En su respuesta revisada, su primer ejemplo aplica el rol a MyApp::User
metaclase del MyApp::User
través de -traits
, el segundo ejemplo lo aplica a la clase.
Si cambias tu primer ejemplo a:
package MyApp::Meta::Class::Trait::HasTable;
use Moose::Role;
sub foo { warn ''foo'' }
package Moose::Meta::Class::Custom::Trait::HasTable;
sub register_implementation { ''MyApp::Meta::Class::Trait::HasTable'' }
package MyApp::User;
use Moose -traits => ''HasTable'';
__PACKAGE__->meta->foo();
Verá " foo at [script]. line 3.
" Que es exactamente lo que se supone que debe hacer.
ACTUALIZACIÓN: Al parecer no estoy exactamente correcto aquí. Los rasgos son roles aplicados a instancias. El -traits
aplica HasTable a la instancia de metaclase para MyApp :: User. He actualizado los documentos relevantes de Moose.
He escrito un conjunto de clases e interfaces que se implementan en Moose también usando roles. Lo que estoy teniendo problemas para entender es las diferencias exactas en el uso y la implementación de los rasgos de Moose frente a los roles.
La documentación de Moose establece:
Es importante entender que los roles y rasgos son lo mismo. Un rol puede ser usado como un rasgo, y un rasgo es un rol. Lo único que distingue a los dos es que un rasgo se empaqueta de una manera que le permite a Moose resolver un nombre corto a un nombre de clase. En otras palabras, con un rasgo, la persona que llama puede referirse a él con un nombre corto como "Big", y Moose lo resolverá a una clase como MooseX :: Embiggen :: Meta :: Attribute :: Role :: Big.
Tengo entendido que los rasgos y roles son "los mismos". Sin embargo, al implementar una prueba básica de la idea utilizando el use Moose -traits ''Foo''
no parece hacer lo que yo esperaría. Seguramente debo estar perdiendo algo aquí.
Este primer ejemplo falla con "No se puede localizar el método de objeto ''foo''"
package MyApp::Meta::Class::Trait::HasTable;
use Moose::Role;
sub foo { warn ''foo'' }
package Moose::Meta::Class::Custom::Trait::HasTable;
sub register_implementation { ''MyApp::Meta::Class::Trait::HasTable'' }
package MyApp::User;
use Moose -traits => ''HasTable'';
__PACKAGE__->foo(); #Can''t locate object method ''foo''
Comparado con este (que funciona):
package MyApp::Meta::Class::Trait::HasTable;
use Moose::Role;
sub foo { warn ''foo'' }
package Moose::Meta::Class::Custom::Trait::HasTable;
sub register_implementation { ''MyApp::Meta::Class::Trait::HasTable'' }
package MyApp::User;
use Moose;
with ''MyApp::Meta::Class::Trait::HasTable'';
__PACKAGE__->foo(); #foo
No define un paquete ''x :: Foo'' con ningún rol. Extraído directamente de la documentation , vemos que register_implementation
devuelve el nombre de un paquete realmente definido:
package MyApp::Meta::Class::Trait::HasTable;
use Moose::Role;
has table => (
is => ''rw'',
isa => ''Str'',
);
package Moose::Meta::Class::Custom::Trait::HasTable;
sub register_implementation { ''MyApp::Meta::Class::Trait::HasTable'' }
package MyApp::User;
use Moose -traits => ''HasTable'';
__PACKAGE__->meta->table(''User'');
El "atajo" se logra cuando Moose busca "Moose::Meta::Class::Trait::$trait_name"
(cuando se le llama en un "contexto de clase"), no solo devolviendo un nombre más corto.