为什么这个Moose强制子程序不能用于Perl 5.8.8?

时间:2010-11-04 23:30:07

标签: perl moose

我尝试使用Moose。这很好,当它工作。

但是,我发现了一些看起来像虫子的东西(但我会在提交之前询问)。

当我运行此代码时

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,在下划线之后总是有垃圾)

你认为这是一只驼鹿虫吗?

1 个答案:

答案 0 :(得分:6)

如果你真的在运行perl 5.8.0,那不是bug,因为Moose requires a minimum version of perl 5.8.3。遗憾。

你真的确定无法升级吗? 5.8.0真的很老了,转到5.8.8(它本身已经很老了,但仍然在许多企业环境中运行)会给你带来很多bug修复。

但是(感谢doy注意到这一点),你的强制将永远不会运行,因为现有的类型约束'K'将通过。您需要在子类型定义中添加where子句,以触发强制:

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

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

(请注意,替换运算符返回所做的替换次数;我之前提出了两次替换重写。)

最后,你在问题中写的代码在一个完全可操作的系统上打印“abcd_efgh”,所以你确定你在两个盒子上运行相同的代码吗?