1

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

测试.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.
4

1 回答 1

2

可以使用AUTOLOAD和元编程,问题仍然是Why

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

#!/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 对问题的评论:它展示了如何将属性添加到实例,而不是整个类。

于 2018-06-04T15:27:44.877 回答