为什么不“使用过载”?使用“use namespace:autoclean”?

发布于 2024-12-09 12:09:53 字数 1146 浏览 1 评论 0原文

好吧,只是为了健全性检查过载似乎对我不起作用。我不知道是否是我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

儭儭莪哋寶赑 2024-12-16 12:09:53

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 文档中解决此问题的任何内容,因此我猜这是一个意料之外的功能。一些搜索显示已报告错误

我想这取决于 overload 添加到您的包中的特殊符号。重载+会添加符号表条目()(+OVERLOAD。我猜有些或所有这些都由 namespace::autoclean 清理掉,从而消除您的超载,

如果您喜欢冒险,这里有一个 namespace::autoclean 的补丁,可以过滤掉重载符号。

namespace::autoclean is futzing with the magic that overload adds to handle your operator. The following works as you would expect:

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;

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 (), (+, and OVERLOAD. I'm guessing some or all of these are vacuumed up by namespace::autoclean, thus undoing your overloading.

If you're feeling adventurous, here's a patch for namespace::autoclean that filters out overload symbols.

伪装你 2024-12-16 12:09:53

所以弗里多是绝对正确的;问题在于 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.

花辞树 2024-12-16 12:09:53

我遇到了同样的问题(在我的例子中尝试重载 "" ),但还没有让 MooseX::MarkAsMethods 工作。尚未正确研究原因,但确实有效的替代解决方案是使用 MooseX::Role::WithOverloading(因为我已经使用了各种角色,所以很容易适应)。

package MyClass;
use Moose;
use namespace::autoclean;
with 'MyRole';

package MyRole;
use MooseX::Role::WithOverloading;

use overload '""' => sub { ... };

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).

package MyClass;
use Moose;
use namespace::autoclean;
with 'MyRole';

package MyRole;
use MooseX::Role::WithOverloading;

use overload '""' => sub { ... };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文