如何在Moo或Moose中动态创建缺失的属性?

时间:2018-06-04 15:02:44

标签: perl oop moose moo

我们有一个示例代码,如下所示。是否可以捕获在包FooBar中调用的所有缺少的属性并动态创建它?这就像PHP的__call

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 dynamically created when 
# invoked even it's not declared in Person.
say $p->lalala;
$ perl test.pl
John
Can't locate object method "lalala" via package "Test" at test.pl line 13.

1 个答案:

答案 0 :(得分:2)

可以使用AUTOLOAD和元编程,问题仍然是为什么

使用参数化角色可能有更好的方法,但我只是想快速展示如何做到这一点。我会在评论中拒绝这样的代码(我希望至少有一条评论解释为什么需要自动加载)。

#!/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.

更新:以前,我的代码更复杂,因为它回复了@ simbabque对问题的评论:它显示了如何将属性添加到实例,而不是整个类。