为什么不“使用重载”与“使用命名空间:autoclean”一起工作?

时间:2011-10-12 03:18:53

标签: perl namespaces overloading moose

好的只是为了理智检查超载似乎并不适合我。我不知道它是我的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社区一般不会使用过载吗?

3 个答案:

答案 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 { ... };