Perl 如何在Moo或Moose中动态创建缺少的属性?
我们有一个如下的示例代码。是否可以捕获包FooBar中调用的所有缺失属性并动态创建它?这有点像PHP test.plPerl 如何在Moo或Moose中动态创建缺少的属性?,perl,oop,moose,moo,Perl,Oop,Moose,Moo,我们有一个如下的示例代码。是否可以捕获包FooBar中调用的所有缺失属性并动态创建它?这有点像PHP test.pl package Person; use feature qw(say); use Moo; has name => (is => "ro"); my $p = Person->new(name => "John"); say $p->name; # The missing attribute method will be dynamicall
package Person;
use feature qw(say);
use Moo;
has name => (is => "ro");
my $p = Person->new(name => "John");
say $p->name;
# The missing attribute method will be dynamically created when
# invoked even it's not declared in Person.
say $p->lalala;
使用和元编程是可能的,问题仍然是为什么 可能有更好的方法使用参数化角色,但我只是想快速演示如何使用参数化角色。我会在评论中拒绝这样的代码(我希望至少有评论解释为什么需要自动加载)
更新:之前,我的代码更复杂,因为它回答了@simbabque对问题的评论:它显示了如何将属性添加到实例中,而不是整个类。?您的示例中没有
$fb
变量。请回答您的问题并提供工作代码,或者在您的情况下,提供产生您正在谈论的错误的代码,而不是其他内容。@choroba您可以通过自动加载安装方法,但实际上并不是一个完整的属性。如果该属性已经在类中定义,我们可以绕过谓词,但我不确定这有什么好处。当然,我们可以在运行时通过元层修改类,并添加一个属性(如果这样做的话,不使用类型或任何东西),作为读写属性,但这将泄漏到该类的每个对象中。听起来不是个好主意。@simbabque很好。示例代码已更新。为什么要创建新类?另外,goto
应用于隐藏调用堆栈中的自动加载。@ikegami:因为我不想更改原始类的行为。此外,我没有得到您声明的输出,而是在串联(.)或者a.pl第19行的字符串。@ikegami:什么Perl和Moose版本?我现在在5.18.2上观看Moose2.2009。@ikegami:另外,我以前没有注意到OP想要改变全班同学的行为。我简化了答复。
$ perl test.pl
John
Can't locate object method "lalala" via package "Test" at test.pl line 13.
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
{ package MyObj;
use Moose;
sub AUTOLOAD {
my ($self) = @_;
( my $method = our $AUTOLOAD ) =~ s/.*:://;
(ref $self)->meta->add_attribute($method, is => 'rw');
goto &$method
}
}
say 'MyObj'->can('lalala'); # No, it can't.
my $o = 'MyObj'->new;
$o->lalala(12); # Attribute created.
say $o->lalala; # 12.