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

qod*_*nja 12 perl overloading namespaces moose

好的只是为了理智检查超载似乎并没有为我工作.我不知道它是我的perl版本,还是overload.pm的版本,或者我实现它的方式有问题,但这段代码对我不起作用.

perl版本

This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi
Run Code Online (Sandbox Code Playgroud)

过载版本

perl -Moverload -e 'print "$overload::VERSION\n";'
1.07
Run Code Online (Sandbox Code Playgroud)

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);
  }
Run Code Online (Sandbox Code Playgroud)

主要

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;
Run Code Online (Sandbox Code Playgroud)

版画

 $VAR1 = 12900840;
Run Code Online (Sandbox Code Playgroud)

最糟糕的是我在日志中没有收到任何警告或错误.

UPDATE

感谢Freido找到问题所在.我已经更新了这个问题,万一其他人偶然发现了这个问题.

Perl/Moose社区一般不会使用过载吗?

fri*_*edo 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;
Run Code Online (Sandbox Code Playgroud)

随意一瞥没有透露namespace::autoclean解决这个问题的文档中的任何内容,所以我猜这是一个意想不到的功能.一些搜索显示已报告错误.

我想它会降低overload你的包装中添加的特殊符号.重载+增加了符号表(),(+OVERLOAD.我猜测其中的一些或全部被吸尘namespace::autoclean,从而消除了你的超载.

如果你喜欢冒险的感觉,这里有一个补丁用于namespace::autoclean过滤掉过载符号.

  • @nodebunny,为什么在你自己编写时会抱怨其他人的代码?:)这个问题激发了我写[namespace :: sweep](http://search.cpan.org/~friedo/namespace-sweep/lib/namespace/sweep.pm),它不会践踏你的重载.更多信息[这里](http://blogs.perl.org/users/mike_friedman/2011/10/announcing-namespacesweep.html). (3认同)

小智 10

所以friedo绝对正确; 问题在于启发式Class :: MOP用于确定什么是什么,什么不是"方法".通常,从另一个包导入的任何东西都不是一种方法,并且技术上的重载符合这一要求.由于namespace :: autoclean要求Class :: MOP包存在哪些方法并删除其余方法,因此autoclean会盲目地清除重载以及其他所有内容.

我认为这是非常令人惊讶的.

MooseX :: MarkAsMethods将为Moose课程提供帮助; 它在autoclean之前运行,并告诉Moose将该包的任何重载代码符号识别为方法.这使他们成为autoclean的斧头,并且具有额外的优势,现在你可以在角色中使用重载,消耗它们,让它们"正常工作".(完全披露:2年前我的autoclean修复被拒绝后,我写了MX :: MarkAsMethods.)

但是,这对于你可能想要使用autoclean的非Moose类没有帮助... autoclean的重载删除充其量只是autoclean中的一个缺陷.

  • `flaw`太善良了,`namespace :: autoclean`因为这个而被打破了.你的修复是完美的BTW,维护者对此很顽固是一种耻辱. (5认同)