perl attributes moose

Accesadores de Perl Moose generados sobre la marcha



attributes (1)

Creo que cambiar los métodos de lectura y escritura de este tipo requiere un nivel insalubre de locura. Si lo desea, eche un vistazo al código fuente de Class :: MOP :: Method :: Accessor , que se usa debajo del capó para crear los accesors.

En cambio, sugiero simplemente sobrescribir (o adjuntar) la funcionalidad a los lectores generados por Moose utilizando un modificador de método around . Para que funcione con subclases, puede usar Class :: Method :: Modifiers en lugar de Moose around .

package Foo::Subclass; use Moose; extends ''Foo''; package Foo; use Moose; package main; require Class::Method::Modifiers; # no import because it would overwrite Moose my @Fields = qw( af sdaf gdsg ewwq fsf ); # pretend that we have 100 fields # Imagine that this is a tied hash with 100 fields my %Data = map { $_ => rand } @Fields; my $class = ''Foo::Subclass''; foreach my $Key (@Fields) { $class->meta->add_attribute( $Key => { is => ''rw'', isa => ''Str'', lazy => 0, required => 0, } ); Class::Method::Modifiers::around( "${class}::$Key", sub { my $orig = shift; my $self = shift; $self->$orig(@_); # just so Moose is up to speed # writer $Data{$Key} = $_[0] if @_; return $Data{$Key}; }); }

Y luego ejecuta una prueba.

package main; use Data::Printer; use v5.10; my $foo = Test->new; say $foo->sdaf; $foo->sdaf(''foobar''); say $foo->sdaf; p %Data; p $foo;

Aquí está el STDOUT / STDERR de mi máquina.

{ af 0.972962507120432, ewwq 0.959195914302605, fsf 0.719139421719849, gdsg 0.140205658312095, sdaf "foobar" } Foo::Subclass { Parents Foo Linear @ISA Foo::Subclass, Foo, Moose::Object public methods (6) : af, ewwq, fsf, gdsg, meta, sdaf private methods (0) internals: { sdaf "foobar" } } 0.885114977459551 foobar

Como puede ver, Moose realmente no sabe acerca de los valores dentro del hash, pero si usa los accessors, los leerá y escribirá. El objeto Moose se llenará lentamente con nuevos valores cuando use el escritor, pero de lo contrario los valores dentro del objeto Moose realmente no importan.

Vea el siguiente fragmento de código de Perl que se basa en Moose:

$BusinessClass->meta->add_attribute($Key => { is => $rorw, isa => $MooseType, lazy => 0, required => 0, reader => sub { $_[0]->ORM->{$Key} }, writer => sub { $_[0]->ORM->newVal($Key, $_[1]) }, predicate => "has_$Key", });

Recibo el error:

bad accessor/reader/writer/predicate/clearer format, must be a HASH ref at /usr/local/lib/perl5/site_perl/mach/5.20/Class/MOP/Class.pm line 899

La razón del error es clara: el lector y el escritor deben ser nombres de cadena de funciones.

Pero, ¿qué hacer en este caso específico? No quiero crear una nueva función para cada uno de los cien campos ORM (el atributo ORM aquí es un hash vinculado). Así que no puedo pasar una cadena aquí, necesito un cierre.

Por lo tanto, mis necesidades de codificación resultaron en una contradicción. No se que hacer.

Lo anterior fue un fragmento de código real. Ahora presento un ejemplo mínimo:

#!/usr/bin/perl my @Fields = qw( af sdaf gdsg ewwq fsf ); # pretend that we have 100 fields # Imagine that this is a tied hash with 100 fields my %Data = map { $_ => rand } @Fields; package Test; use Moose; foreach my $Key (@Fields) { __PACKAGE__->meta->add_attribute($Key => { is => ''rw'', isa => ''Str'', lazy => 0, required => 0, reader => sub { $Data{$Key} }, writer => sub { $Data{$Key} = $_[1] }, }); }

Ejecutarlo da como resultado:

$ ./test.pl bad accessor/reader/writer/predicate/clearer format, must be a HASH ref at /usr/lib/i386-linux-gnu/perl5/5.22/Class/MOP/Class.pm line 899 Class::MOP::Class::try {...} at /usr/share/perl5/Try/Tiny.pm line 92 eval {...} at /usr/share/perl5/Try/Tiny.pm line 83 Try::Tiny::try(''CODE(0x9dc6cec)'', ''Try::Tiny::Catch=REF(0x9ea0c60)'') called at /usr/lib/i386-linux-gnu/perl5/5.22/Class/MOP/Class.pm line 904 Class::MOP::Class::_post_add_attribute(''Moose::Meta::Class=HASH(0x9dc13f4)'', ''Moose::Meta::Attribute=HASH(0x9dc6b5c)'') called at /usr/lib/i386-linux-gnu/perl5/5.22/Class/MOP/Mixin/HasAttributes.pm line 39 Class::MOP::Mixin::HasAttributes::add_attribute(''Moose::Meta::Class=HASH(0x9dc13f4)'', ''Moose::Meta::Attribute=HASH(0x9dc6b5c)'') called at /usr/lib/i386-linux-gnu/perl5/5.22/Moose/Meta/Class.pm line 572 Moose::Meta::Class::add_attribute(''Moose::Meta::Class=HASH(0x9dc13f4)'', ''af'', ''HASH(0x9ea13a4)'') called at test.pl line 18

No sé qué hacer (cómo crear accesos "dinámicos" (similares a los cierres), sin escribir una función individual para cada uno de los 100 campos?)