perl-通用运算符重载
我对perl有了一个想法,我正试图找出实现它的最佳方法perl-通用运算符重载,perl,overloading,operator-keyword,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 等等 理想情况下,这应该是
这个想法是每个操作符都有新的版本,它将未定义的值作为该操作的标识。例如:
$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
等等
理想情况下,这应该是一个pragma之类的语言
use operators::awesome;
但是,如果我能自己实现这个特殊逻辑,然后在需要时调用它,我会感到满意:
use My::Operators;
问题是,如果我在My::Operators中说“use重载”,那么只会影响到My::Operators中的对象
所以问题是:有没有一种方法(使用overload或其他方式)来实现“通用操作符重载”——它将被调用用于所有操作,而不仅仅是对标量的操作
如果不是,谁认为这是个好主意!?这将为我节省大量此类代码
if($object && $object{value} && $object{value} == 15)
replace with
if($object{value} == 15) ## the special "is-equal-to" operator
正如暴民所说,你的布拉格语已经存在。拼写为
没有“未初始化”的警告代码>。Perl已经将undef
视为0或空字符串(取决于上下文)。这只会抑制您通常收到的警告(假设您打开了警告,您应该打开)
如果要创建自动执行此操作的包,可以:
package operators::awesome;
use strict;
use warnings;
sub import {
warnings->unimport('uninitialized');
}
现在使用操作符::真棒代码>将关闭有关未初始化值的警告
这里有一个更为奇特的import
版本,它打开了严格和警告,但关闭了有关未初始化值的警告:
sub import {
strict->import;
warnings->import;
warnings->unimport('uninitialized');
}
正如暴民所说,你的布拉格语已经存在。拼写为没有“未初始化”的警告代码>。Perl已经将undef
视为0或空字符串(取决于上下文)。这只会抑制您通常收到的警告(假设您打开了警告,您应该打开)
如果要创建自动执行此操作的包,可以:
package operators::awesome;
use strict;
use warnings;
sub import {
warnings->unimport('uninitialized');
}
现在使用操作符::真棒代码>将关闭有关未初始化值的警告
这里有一个更为奇特的import
版本,它打开了严格和警告,但关闭了有关未初始化值的警告:
sub import {
strict->import;
warnings->import;
warnings->unimport('uninitialized');
}
这是可能的。这将需要大量工作,但您可以编写一个“操作检查器”,用自定义操作替换&&
的操作,这是您对&&
的重新实现
但这将是一个非常糟糕的主意。首先
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) {
...
}
或
或
这是可能的。这将需要大量工作,但您可以编写一个“操作检查器”,用自定义操作替换&&
的操作,这是您对&&
的重新实现
但这将是一个非常糟糕的主意。首先
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) {
...
}
或
或
所有这些操作都已经按照您期望的方式工作:
- 在数字上下文中,
undef
是0
- 在字符串上下文中,
unde
是空字符串'
- 在布尔语言的上下文中,
undef
是0
如果您使用警告,那么perl会让您知道该值未初始化,但仍然可以正常工作。所有这些操作都已经按照您期望的方式工作:
- 在数字上下文中,
undef
是0
- 在字符串上下文中,
unde
是空字符串'
- 在布尔语言的上下文中,
undef
是0
如果使用警告,那么perl会让您知道该值未初始化,但它仍然可以正常工作。此杂注已经存在。它被称为无警告
;我假设你是想说
$object->{value}`而不是$object{value}
。这个杂注已经存在了。它被称为无警告
;我假设你想说
$object->{value}`而不是$object{value}
。这与仅仅使用无警告“未初始化”
有何不同?@TLP,它不是。我刚刚指出,您可以编写一个软件包,为您提供与“未初始化”的无警告类似的功能。它还可以做其他事情,比如打开严格警告和其他警告。如果你愿意,它甚至可以导出函数,尽管那会更复杂。@ikegami,我只是注意到他的描述不一致。他说“undef被视为false,$a=true”,但是false&&true是false,而不是true。这与仅仅使用没有“未初始化”的警告有什么区别?@TLP,它不是。我刚刚指出,您可以编写一个软件包,为您提供与“未初始化”的无警告类似的功能。它还可以做其他事情,比如打开严格警告和其他警告。如果你愿意,它甚至可以导出函数,尽管那会更复杂。@ikegami,我只是注意到他的描述不一致。他说“undef被视为false,$a=true”,但是false&&true是false,而不是true。你是对的,我所说的大多数警告都是“未初始化”的。想不想再详细介绍一下“定制操作检查器”的想法?我不知道perl如何允许您在两个文字数字之间挂接运算符。@Todd Freed,op检查器访问每个op,并可以用其他op替换它们。这就是(模块)的工作方式。自动活体化模块似乎完全用xs实现。所以我想你不能让操作符过载