Moose - импортированные функции не считаются ролевыми методами? - PullRequest
3 голосов
/ 09 сентября 2011

У меня есть роль, которая заявляет, что для этого требуется метод (с 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 ]

3 голосов
/ 09 сентября 2011

Проблема в том, что Moose очень старается отследить, откуда берутся методы, чтобы все, что не определено в локальном пакете, не было случайно обработано как метод.

Если вместо использования необработанного глобуса вы должны использовать метапротокол Moose для внедрения импорта, это сработает, потому что Moose будет знать, что вы пытаетесь явно добавить метод.

package anexporter {

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

}

Однако это означает, что что-нибудь в CPAN (например, File :: Find's finddepth) должно быть упаковано. Который, поскольку обычно экспорт не ожидает вызова в качестве методов, вероятно, в любом случае это должно произойти.

0 голосов
/ 05 октября 2011

Ваша роль ищет метод с именем finddepth; просто импортировать его из другого пакета не метод make. Я бы обернул его в метод, так как ваши методы ролей в любом случае должны будут вызывать finddepth как метод, чтобы все разрешалось правильно.

# in package aclass
use File::Find;

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

У этого есть пара преимуществ: это не удивительно, это не волшебно, и все работает как ожидалось.

...