perl - 通用运算符重载

Tod*_*eed 1 perl overloading operator-keyword

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

等等.

理想情况下,这将是语言作为一个pragma,或其他东西.

use operators::awesome;
Run Code Online (Sandbox Code Playgroud)

但是,如果我能够自己实现这个特殊的逻辑,然后在需要的地方调用它,我会感到满意:

use My::Operators;
Run Code Online (Sandbox Code Playgroud)

问题是,如果我说My :: Operators中的"use overload"只会影响被祝福到My :: Operators中的对象.

所以问题是:是否有一种方法(使用"overoad"或其他方式)来执行"通用运算符重载" - 这将被调用所有操作,而不仅仅是对受祝福标量的操作.

如果不是 - 谁认为这将是个好主意!这将节省我这种代码的TON

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

replace with

if($object{value} == 15)  ## the special "is-equal-to" operator
Run Code Online (Sandbox Code Playgroud)

ike*_*ami 6

这是可能的.这需要花费很多工作,但你可以编写一个"操作检查器",用&&你自己重新实现的自定义操作替换操作&&.

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

if ($a && $b) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

会停止相当于

if ($a) {
   if ($b) {
      ...
   }
}
Run Code Online (Sandbox Code Playgroud)

举个例子,

if ($object && $object{value} && $object{value} == 15) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

根据您要求的型号,必须编写

if ($object{value}) { if ($object{value} == 15) {
   ...
}}
Run Code Online (Sandbox Code Playgroud)

你实际上想要与你要求的完全相反.你真的想要当前的行为.没有你的模块,你可以写:

if ($object{value} && $object{value} == 15) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

要么

no warnings 'uninitialized';
if ($object{value} == 15) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

要么

if (($object{value} // 0) == 15) {
   ...
}
Run Code Online (Sandbox Code Playgroud)


cjm*_*cjm 5

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

如果要创建一个自动执行此操作的程序包,则可以:

package operators::awesome;

use strict;
use warnings;

sub import {
  warnings->unimport('uninitialized');
}
Run Code Online (Sandbox Code Playgroud)

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

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

sub import {
  strict->import;
  warnings->import;
  warnings->unimport('uninitialized');
}
Run Code Online (Sandbox Code Playgroud)