perl - 通用运算符重载

发布于 2024-12-16 16:45:24 字数 823 浏览 0 评论 0原文

我对 perl 有一个想法,并且正在尝试找出实现它的最佳方法。

这个想法是为每个运算符提供新版本,将未定义的值视为该操作的标识。例如:

$a = undef + 5;     # undef treated as 0, so $a = 5
$a = undef . "foo"; # undef treated as '', so $a = foo
$a = undef && 1;    # undef treated as false, $a = true

等等。

理想情况下,这将在语言中作为编译指示或其他东西。

use operators::awesome;

然而,如果我可以自己实现这个特殊的逻辑,然后在需要的地方调用它,我会很满意:

use My::Operators;

问题是,如果我在 My::Operators 中说“使用重载”,只会影响祝福到 My::Operators 中的对象。

所以问题是:有没有一种方法(使用“使用过载”或其他方式)来执行“通用运算符重载”——所有操作都会调用它,而不仅仅是对祝福标量的操作。

如果不是——谁会认为这是个好主意!?它会为我节省大量此类代码

if($object && $object{value} && $object{value} == 15)

replace with

if($object{value} == 15)  ## the special "is-equal-to" operator

I have an idea for perl, and I'm trying to figure out the best way to implement it.

The idea is to have new versions of every operator which consider the undefined value as the identity of that operation. For example:

$a = undef + 5;     # undef treated as 0, so $a = 5
$a = undef . "foo"; # undef treated as '', so $a = foo
$a = undef && 1;    # undef treated as false, $a = true

and so forth.

ideally, this would be in the language as a pragma, or something.

use operators::awesome;

However, I would be satisfied if I could implement this special logic myself, and then invoke it where needed:

use My::Operators;

The problem is that if I say "use overload" inside My::Operators only affects objects blessed into My::Operators.

So the question is: is there a way (with "use overoad" or otherwise) to do a "universal operator overload" - which would be called for all operations, not just operations on blessed scalars.

If not - who thinks this would be a great idea !? It would save me a TON of this kind of code

if($object && $object{value} && $object{value} == 15)

replace with

if($object{value} == 15)  ## the special "is-equal-to" operator

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

小清晰的声音 2024-12-23 16:45:24

这是可能。这需要做很多工作,但您可以编写一个“操作检查器”,用自定义操作替换 && 的操作,这是您对 && 的重新实现>。

但这将是一个非常糟糕的主意。对于初学者来说,

if ($a && $b) {
   ...
}

将不再等同于

if ($a) {
   if ($b) {
      ...
   }
}

以您自己的示例为例,

if ($object && $object{value} && $object{value} == 15) {
   ...
}

对于您所请求的模型,必须将其写为

if ($object{value}) { if ($object{value} == 15) {
   ...
}}

您实际上想要与您所要求的完全相反的内容。您实际上想要当前的行为。没有你的模块,你可以写:

if ($object{value} && $object{value} == 15) {
   ...
}

no warnings 'uninitialized';
if ($object{value} == 15) {
   ...
}

if (($object{value} // 0) == 15) {
   ...
}

It is possible. It would take a lot of work, but you could write an "op checker" that replaces the ops for && with custom op that's your reimplementation of &&.

But it would be a very bad idea. For starters,

if ($a && $b) {
   ...
}

would stop being equivalent to

if ($a) {
   if ($b) {
      ...
   }
}

To take your own example,

if ($object && $object{value} && $object{value} == 15) {
   ...
}

With your requested model, it would have to be written

if ($object{value}) { if ($object{value} == 15) {
   ...
}}

You actually want the exact opposite of what you asked for. You actually want the current behaviour. Without your module, you can write:

if ($object{value} && $object{value} == 15) {
   ...
}

or

no warnings 'uninitialized';
if ($object{value} == 15) {
   ...
}

or

if (($object{value} // 0) == 15) {
   ...
}
凤舞天涯 2024-12-23 16:45:24

正如暴民所说,你的编译指示已经存在。它的拼写是no warnings 'uninitialized';。 Perl 已经将 undef 视为 0 或空字符串(取决于上下文)。这只会抑制您通常收到的警告(假设您打开了警告,这是您应该打开的)。

如果您想创建一个自动执行此操作的包,您可以:

package operators::awesome;

use strict;
use warnings;

sub import {
  warnings->unimport('uninitialized');
}

现在 use Operator::awesome; 将关闭有关未初始化值的警告。

这是 import 的一个更高级的版本,它打开严格和警告,但关闭有关未初始化值的警告:

sub import {
  strict->import;
  warnings->import;
  warnings->unimport('uninitialized');
}

As mob said, your pragma already exists. It's spelled no warnings 'uninitialized';. Perl already treats undef as either 0 or the empty string (depending on context). This just suppresses the warning you usually get (assuming you have warnings turned on, which you should).

If you want to create a package that does this automatically, you can:

package operators::awesome;

use strict;
use warnings;

sub import {
  warnings->unimport('uninitialized');
}

Now use operators::awesome; will turn off warnings about uninitialized values.

Here's a fancier version of import that turns on strict and warnings, but turns off warnings about uninitialized values:

sub import {
  strict->import;
  warnings->import;
  warnings->unimport('uninitialized');
}
烟花易冷人易散 2024-12-23 16:45:24

所有这些操作都已按照您期望的方式工作:

  • 在数字上下文中,undef0
  • 在字符串上下文中,undef 是空字符串 ''
  • 在布尔值上下文中,undef0

如果您使用警告,那么 Perl 会让您知道该值尚未初始化,但它仍然可以正常工作。

All of those operations already work the way you expect them to:

  • In the context of numbers, undef is 0.
  • In the context of strings, undef is the empty string ''.
  • In the context of booleans, undef is 0.

If you use warnings, then perl will let you know that the value is uninitialized, but it will still work just fine.

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