Moose - 导入的函数不算作角色方法?

时间:2011-09-09 16:27:47

标签: perl roles moose

我有一个角色声明它需要一个方法(requires)。 我正在尝试通过在类的符号表中直接定义它来安装该方法。 但是,在某些情况下它可以正常工作,而在其他情况下则不然。

在下文中,WORKS表示没有报告错误,不工作意味着我收到错误:'arole' requires the method 'finddepth' to be implemented by 'aclass'

package arole;

use Moose::Role;

requires 'finddepth';

package anexporter;

sub import {
  no strict 'refs';
  *{ "aclass::finddepth" } = sub {};
}

package anexporter2;
sub import {
  eval "sub aclass::finddepth {}";
}

package aclass;

use Moose;

# WORKS:
# sub finddepth { }

# WORKS:
# BEGIN { *{finddepth} = sub {} };

# DOESN'T WORK:
# use File::Find qw(finddepth);

# DOESN'T WORK:
# BEGIN { anexporter->import };

# WORKS:
# BEGIN { no strict 'refs'; *{ "aclass::finddepth" } = sub { }};

# WORKS:
# BEGIN { anexporter2->import };

with 'arole';

1;

2 个答案:

答案 0 :(得分:3)

问题在于,Moose非常努力地追踪方法的来源,以便本地包中未定义的任何内容都不会被意外地视为方法。

如果不是使用原始glob,而是使用Moose元协议来注入导入,这将起作用,因为Moose会知道你正在尝试显式添加方法。

package anexporter {

    sub import {
        aclass->meta->add_method(finddepth => sub {})
    }

}

然而,这确实意味着需要包装CPAN上的任何内容(如File :: Find的finddepth)。由于通常不希望将出口称为方法,因此无论如何都可能需要进行出口。

答案 1 :(得分:0)

您的角色正在寻找名为finddepth的方法;只是从一些其他包中导入它不是一个方法make。我将它包装在一个方法中,因为你的角色方法无论如何都需要将finddepth称为方法,以使所有内容都能正确解析。

# in package aclass
use File::Find;

sub finddepth { shift; File::Find::finddepth(@_) }

这有几个优点:这并不奇怪,它并不神奇,一切都按预期工作。