我尝试使用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,在下划线之后总是有垃圾)
你认为这是一只驼鹿虫吗?
答案 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”,所以你确定你在两个盒子上运行相同的代码吗?