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

Kar*_*lek 1 perl 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";
Run Code Online (Sandbox Code Playgroud)

在一台带有perl 5.010的计算机上,它正确显示abcd.当我在5.8.8的另一台计算机上运行它(不幸的是,脚本也必须工作),我看到不正确abcd_efgh; 并且强制子程序似乎从未实际运行(例如,如果我在那里添加打印或模具,5.8.8机器上没有任何反应).

(它真的很简单,但它是一个真实的现实案例 - 我需要从字符串强制K,在下划线之后总是有垃圾)

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

Eth*_*her 6

如果你真的运行perl 5.8.0,那不是bug,因为Moose 需要最低版本的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];
    };
Run Code Online (Sandbox Code Playgroud)

(注意,替换运算符返回所做的替换次数;我在上面提出了两个备用重写.)

最后,您在问题中编写的代码在完全可操作的系统上打印"abcd_efgh",因此您确定在两个盒子上运行相同的代码吗?