初始化Moose类的CodeRef字段

Sri*_*ini 5 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;
Run Code Online (Sandbox Code Playgroud)

我正在初始化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";
Run Code Online (Sandbox Code Playgroud)

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

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

dus*_*uff 10

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

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

$user->check->()
Run Code Online (Sandbox Code Playgroud)


sim*_*que 7

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

package Person;

use Moose;

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

然后像这样称呼它

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";
Run Code Online (Sandbox Code Playgroud)

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