MooseX :: Проблема объявления типов, жесткий тестовый пример :) - PullRequest
3 голосов
/ 11 января 2011

Итак, после изнурительного количества времени отладки, я наконец разобрал эту проблему до простого тестового примера. Я смиренно попросил бы некоторую помощь, понимающую, почему это терпит неудачу. :) Вот сообщение об ошибке, которое я получаю:

plxc16479> $h2/tmp/tmp18.pl
This method [new] requires a single argument. at /nfs/pdx/disks/nehalem.pde.077/perl/5.12.2/lib64/site_perl/MooseX/Types/TypeDecorator.pm line 91

MooseX::Types::TypeDecorator::new('MooseX::Types::TypeDecorator=HASH(0x655b90)') called at /nfs/pdx/disks/nehalem.pde.077/projects/lib/Program-Plist-Pl/lib/Program/Plist/Pl.pm line 10

Program::Plist::Pl::BUILD('Program::Plist::Pl=HASH(0x63d478)', 'HASH(0x63d220)') called at generated method (unknown origin) line 29

Program::Plist::Pl::new('Program::Plist::Pl') called at /nfs/pdx/disks/nehalem.pde.077/tmp/tmp18.pl line 10

Тестовый скрипт Wrapper:

use strict;
use warnings;

BEGIN {push(@INC, split(':', $ENV{PERL_TEST_LIBS}))};

use Program::Plist::Pl;

my $obj = Program::Plist::Pl->new();

Программа :: Plist :: Pl файл:

package Program::Plist::Pl;

use Moose;
use namespace::autoclean;

use Program::Types qw(Pattern); # <-- Removing this fixes error
use Program::Plist::Pl::Pattern;

sub BUILD {
  my $pattern_obj = Program::Plist::Pl::Pattern->new();
}

__PACKAGE__->meta->make_immutable;

1;

Программа :: Файл типов:

package Program::Types;

use MooseX::Types -declare => [qw(Pattern)];

class_type Pattern, {class => 'Program::Plist::Pl::Pattern'};

1;

И Программа :: Plist :: Pl :: Шаблон файла:

package Program::Plist::Pl::Pattern;

use Moose;
use namespace::autoclean;

__PACKAGE__->meta->make_immutable;

1;

Примечания: Хотя мне не нужен тип Pattern из Program::Types в приведенном выше коде, я делаю в другом коде, который удален. Переменная PERL_TEST_LIBS env, из которой я извлекаю пути INC, содержит только пути к модулям проекта. Из этих путей не загружаются другие модули.

Похоже, определение MooseX :: Types для Pattern вызывает проблемы, но я не уверен, почему. Документация показывает синтаксис, который я использую, но возможно я неправильно использую class_type, так как об этом мало что сказано. Намерение - использовать Pattern для проверки типов через MooseX :: Params :: Validate , чтобы проверить, является ли аргумент объектом Program::Plist::Pl::Program.

Я обнаружил, что удаление промежуточного класса Program::Plist::Pl из уравнения путем прямого вызова Pattern->new из оболочки tmp18.pl не приводит к ошибке, даже если импортируется тип Program::Types Pattern.

1 Ответ

5 голосов
/ 11 января 2011

Когда вы говорите

package Program::Plist::Pl;
...
use Program::Types qw(Pattern);

вы импортируете подпрограмму с именем Pattern в пакет Program::Plist::Pl. Его полное название - Program::Plist::Pl::Pattern. Таким образом,

Program::Plist::Pl::Pattern->new();

разбирается как

Program::Plist::Pl::Pattern()->new();

вместо

'Program::Plist::Pl::Pattern'->new();

это то, что вы имели в виду. Вы можете написать это с явными кавычками, если хотите (и это будет работать), но это раздражающий особый случай. Другое решение - переименовать тип во что-то, что не будет конфликтовать с именем пакета (скажем, PatternObj).

namespace :: autoclean не помогает с этим. Это препятствует тому, чтобы люди назвали импортированные подпрограммы как методы. Но вы вызываете Program::Plist::Pl::Pattern() напрямую, а затем вызываете метод для его возвращаемого значения.

...