Почему эта подпрограмма принуждения Moose не работает на Perl 5.8.8? - PullRequest
1 голос
/ 05 ноября 2010

Я пытаюсь использовать лося.Здорово, когда это работает.

Однако я обнаружил что-то, похожее на ошибку (но я спрошу здесь, прежде чем это делать).

Когда я запускаю этот код

package Experiment;

use Moose;
use Moose::Util::TypeConstraints;

subtype 'K'
    => as 'Str';

coerce 'K'
    => from 'Str'
    => via {
        s/^([^_]*).*$/$1/;
    };

has 'k' => (
    is => 'ro',
    isa => 'K',
    coerce => 1
);

1;
package main;

my $exp = new Experiment(k=>"abcd_efgh");
print $exp->k."\n";

На одном компьютере с Perl 5.010 он правильно показывает abcd.Когда я запускаю его на другом компьютере с 5.8.8 (где, к сожалению, тоже должен работать скрипт), я вижу неправильный abcd_efgh;и подпрограмма принуждения, кажется, никогда не запускается (например, если я добавлю печать или умру там, на машине 5.8.8 ничего не произойдет).

(Это действительно упрощено, ноэто реальный случай из реальной жизни - мне нужно вывести K из строк, в которых всегда есть мусор после подчеркивания)

Как вы думаете, это ошибка Moose?

1 Ответ

6 голосов
/ 05 ноября 2010

Если вы действительно используете Perl 5.8.0, это не ошибка, потому что Moose требует минимальную версию Perl 5.8.3 .Извините.

Вы действительно уверены, что не можете обновить?5.8.0 действительно очень старый, и переход на 5.8.8 (который сам по себе довольно старый, но все еще работает во многих корпоративных средах) принесет вам множество исправлений ошибок.

Но (спасибо, Дойдля того, чтобы заметить это), ваше принуждение никогда не будет выполнено, потому что существующее ограничение типа 'K' пройдет.Вам нужно добавить предложение where в определение подтипа, чтобы вызвать приведение:

subtype 'K'
    => as 'Str'
    => where { $_ !~ /_/ };

coerce 'K'
    => from 'Str'
    => via {
        m/^([^_]*).*$/; $1;
        # this is an alternate method:
        # (split('_', $_, 2))[0];
    };

(Обратите внимание, что оператор подстановки возвращает количество выполненных подстановок; я предложил два альтернативных перезаписивыше.)

Наконец, код, который вы написали в своем вопросе, печатает «abcd_efgh» в полностью работающей системе, так что вы уверены, что запускаете один и тот же код в обоих полях?

...