为什么不“使用过载”?使用“use namespace:autoclean”?
好吧,只是为了健全性检查过载似乎对我不起作用。我不知道是否是我的 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);
}
main
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;
prints
$VAR1 = 12900840;
最糟糕的是我在日志中没有收到任何类型的警告或错误。
更新
感谢 Freido 发现问题。我已经更新了这个问题,以防其他人偶然发现这个问题。
Perl/Moose 社区一般不使用重载吗?
Ok just to sanity check overload doesnt seem to be working for me. I don't know if it's the version of perl I have, or the version of overload.pm, or something wrong with how I've implemented it, but this code doesnt work for me.
perl version
This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi
overload version
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);
}
main
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;
prints
$VAR1 = 12900840;
The worst part is that I'm not getting any kind of warning or errors in the log.
UPDATE
Thanks to Freido for finding the problem. I've updated the question just in case anyone else stumbles on this.
Does the Perl/Moose community generally not use overload?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
namespace::autoclean
正在使用overload
添加来处理操作符的魔力。以下内容如您所期望的那样工作:粗略地看一眼,并不会发现
namespace::autoclean
文档中解决此问题的任何内容,因此我猜这是一个意料之外的功能。一些搜索显示已报告错误。我想这取决于
overload
添加到您的包中的特殊符号。重载+
会添加符号表条目()
、(+
和OVERLOAD
。我猜有些或所有这些都由namespace::autoclean
清理掉,从而消除您的超载,如果您喜欢冒险,这里有一个
namespace::autoclean
的补丁,可以过滤掉重载符号。namespace::autoclean
is futzing with the magic thatoverload
adds to handle your operator. The following works as you would expect:A casual glance does not reveal anything in the
namespace::autoclean
docs that addresses this, so I guess it's an unanticipated feature. Some searching reveals that a bug has been reported.I guess it comes down the special symbols that
overload
adds to your package. Overloading+
adds the symbol table entries()
,(+
, andOVERLOAD
. I'm guessing some or all of these are vacuumed up bynamespace::autoclean
, thus undoing your overloading.If you're feeling adventurous, here's a patch for
namespace::autoclean
that filters out overload symbols.所以弗里多是绝对正确的;问题在于 Class::MOP 用来确定什么是“方法”、什么不是“方法”的启发式方法。一般来说,从另一个包导入的任何东西都不是方法,并且重载在技术上也符合方法。由于 namespace::autoclean 询问 Class::MOP 包存在哪些方法并删除其余方法,因此 autoclean 会盲目地清除重载以及其他所有内容。
我认为这非常令人惊讶。
MooseX::MarkAsMethods 将为 Moose 类提供帮助;它在 autoclean 之前运行,并告诉 Moose 将该包的任何重载代码符号识别为方法。这使它们免遭自动清理的困扰,并且还有一个额外的优点,即现在您可以在角色中使用重载,消耗它们,并让它们“正常工作”。 (全面披露:两年前我的 autoclean 修复被拒绝后,我编写了 MX::MarkAsMethods。)
但是,这对您可能想要使用 autoclean 的非 Moose 类没有帮助...通过 autoclean 删除重载是,充其量是自动清洁的一个缺陷。
So friedo is absolutely correct; the problem lies in the heuristic Class::MOP uses to determine what is and what isn't a "method". Generally, anything imported from another package is not a method, and overloads technically qualify as that. Since namespace::autoclean asks Class::MOP what methods exist for the package and removes the rest, autoclean blindly purges overloads along with everything else.
Which is pretty surprising, I think.
MooseX::MarkAsMethods will help with this for Moose classes; it runs before autoclean does and tells Moose to recognize any overload code symbols for that package as methods. This spares them autoclean's axe, and has the added advantage that now you can use overloads in roles, consume them, and have them "just work". (Full disclosure: I wrote MX::MarkAsMethods after my autoclean fix was rejected 2 years ago.)
However, this does not help with non-Moose classes you may want to use autoclean with... The removal of overloads by autoclean is, at best, a flaw in autoclean.
我遇到了同样的问题(在我的例子中尝试重载
""
),但还没有让 MooseX::MarkAsMethods 工作。尚未正确研究原因,但确实有效的替代解决方案是使用 MooseX::Role::WithOverloading(因为我已经使用了各种角色,所以很容易适应)。I've had the same problem (trying to overload
""
in my case), but haven't got MooseX::MarkAsMethods to work yet. Not looked into why properly yet, but an alternative fix that did work was to use MooseX::Role::WithOverloading (and since I already was using various roles it fitted easily).