好的只是为了理智检查超载似乎并不适合我。我不知道它是我的perl版本,还是overload.pm的版本,或者我实现它的方式有问题,但是这段代码对我不起作用。
perl版
This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi
重载版本
perl -Moverload -e 'print "$overload::VERSION\n";'
1.07
Token.pm
package Token;
use namespace::autoclean;
use Data::Dumper;
use Moose;
use Moose::Util::TypeConstraints;
use overload '+' => \&_overload_add, fallback => 1;
has 'secretvalue' => ( is => 'rw', isa => 'Int');
sub _overload_add{
my ( $one, $two ) = @_;
my $value = $one->secretvalue() + $two->secretvalue();
return ($value);
}
主
use strict;
use warnings;
use Token;
my $t = Token->new( secretvalue => 17, key => 'x' );
my $t2 = Token->new( secretvalue => 12, key => 'y' );
my $x = $t + $t2;
print $x;
打印
$VAR1 = 12900840;
最糟糕的是,我在日志中没有收到任何警告或错误。
更新
感谢Freido找到问题所在。我已经更新了这个问题,万一其他人偶然发现了这个问题。
Perl / Moose社区一般不会使用过载吗?
答案 0 :(得分:16)
namespace::autoclean
充满了overload
为处理您的运营商所添加的魔力。以下工作正如您所期望的那样:
package Token;
use Moose;
use Moose::Util::TypeConstraints;
use overload '+' => '_overload_add';
has 'secretvalue' => ( is => 'rw', isa => 'Int');
sub _overload_add{
my ( $one, $two ) = @_;
my $value = $one->secretvalue() + $two->secretvalue();
return ($value);
}
1;
随意一瞥并未在namespace::autoclean
文档中发现任何解决此问题的内容,因此我猜这是一个意想不到的功能。一些搜索显示已报告bug。
我想它会归结为overload
添加到您的包中的特殊符号。重载+
会添加符号表条目()
,(+
和OVERLOAD
。我猜测部分或全部被namespace::autoclean
吸尘,从而解除了你的重载。
如果您有冒险精神,namespace::autoclean
{{1}}会过滤掉过载符号。
答案 1 :(得分:10)
所以弗鲁多绝对正确;问题在于启发式Class :: MOP用于确定什么是什么,什么不是“方法”。通常,从另一个包导入的任何东西都不是方法,并且技术上的重载符合该方法。由于namespace :: autoclean询问Class :: MOP该包存在哪些方法并删除其余方法,因此autoclean会盲目地清除重载以及其他所有内容。
我认为这是非常令人惊讶的。
MooseX::MarkAsMethods将为Moose课程提供帮助;它在autoclean之前运行,并告诉Moose将该包的任何重载代码符号识别为方法。这使他们成为autoclean的斧头,并且具有额外的优势,现在你可以在角色中使用重载,消耗它们,让它们“正常工作”。 (完全披露:2年前我的autoclean修复被拒绝后,我写了MX :: MarkAsMethods。)
然而,这对于你可能想要使用autoclean的非Moose类没有帮助... autoclean的重载删除充其量只是autoclean中的一个缺陷。
答案 2 :(得分:0)
我遇到了同样的问题(尝试在我的情况下重载""
),但还没有让MooseX :: MarkAsMethods工作。尚未查看原因,但做工作的另一种解决方法是使用MooseX::Role::WithOverloading(因为我已经使用了很多适合的角色)。
package MyClass;
use Moose;
use namespace::autoclean;
with 'MyRole';
package MyRole;
use MooseX::Role::WithOverloading;
use overload '""' => sub { ... };