初始化Moose类的CodeRef字段

时间:2018-02-20 19:35:01

标签: perl moose

我有一个驼鹿班Person

 package Person;

  use Moose;

  has 'first_name' => (
      is  => 'rw',
      isa => 'Str',
  );

  has 'last_name' => (
      is  => 'rw', 
      isa => 'Str',
  );

  has 'check' => (
      is => 'rw',
      isa => 'CodeRef',
  );

  no Moose;
  __PACKAGE__->meta->make_immutable;

我正在另一个文件中初始化一个新的Person对象

use Person;

my $user = Person->new(
    first_name => 'Example',
    last_name  => 'User',
    check => sub {
        print "yo yo\n";
    },
  ); 

print "here\n";
$user->check();
print "here\n";

两个here调试语句正在打印,但子例程中的调试消息不是。

我想知道将函数传递给构造函数的正确方法,以便我可以将匿名子例程传递给对象。

2 个答案:

答案 0 :(得分:10)

$user->check()相当于$user->check。它只返回check属性的值(即coderef)而不对其做任何事情 - 就像任何其他访问者一样。此属性包含coderef的事实不会改变它。

如果要检索coderef,然后调用它,则需要另一个箭头:

$user->check->()

答案 1 :(得分:6)

另一种方法是使用由Moose::Meta::Attribute::Native::Trait::Code实现的特征Code,然后使用不同的名称定义句柄

package Person;

use Moose;

has 'check' => (
    is      => 'rw',
    isa     => 'CodeRef',
    traits  => ['Code'],
    handles => {
        run_check => 'execute',
    },
);

然后像这样称呼它

my $user = Person->new(
    first_name => 'Example',
    last_name  => 'User',
    check      => sub {
        print "yo yo\n";
    },
);

print "here\n";
$user->run_check;
print "here\n";

这允许您将代码引用的访问者与其实现的功能分开。