Perl 为什么Scalar::Util::reftype返回'undef',而不是空字符串?

Perl 为什么Scalar::Util::reftype返回'undef',而不是空字符串?,perl,Perl,ref返回标量值的空字符串 为什么Scalar::Util::reftype返回undef而不是像ref那样的空字符串? undef有什么好处?相比之下,空字符串的好处是在执行以下操作时编码更少: reftype $data eq 'HASH' 当返回undef时,我们将使用未初始化值,而eq在…时,我们应该执行以下操作: (reftype($data) //'') eq 'HASH' 一般来说,输入错误会导致undef(如果不是异常的话),这(最终)会导致一个警告,以便可以找到错误 最有争

ref
返回标量值的空字符串

为什么
Scalar::Util::reftype
返回
undef
而不是像
ref
那样的空字符串?

undef
有什么好处?相比之下,空字符串的好处是在执行以下操作时编码更少:

reftype $data eq 'HASH'
当返回
undef
时,我们将使用
未初始化值,而eq在…
时,我们应该执行以下操作:

(reftype($data) //'') eq 'HASH'

一般来说,输入错误会导致
undef
(如果不是异常的话),这(最终)会导致一个警告,以便可以找到错误

最有争议的警告是未初始化的警告,因为没有立即的好处。但是当我们把它看作更大的错误框架的一部分时,就会意识到它是Perl错误检测和调试系统的关键组件。让函数在输入错误时返回undef是该系统的另一个组成部分

我不同意你的说法,它使代码更小。首先,千万不要使用
reftype
,因为它破坏了Perl的数据模型。(这就是为什么
keys$ref
始终是个坏主意,而且从未经过实验阶段。)这意味着所讨论的代码量非常小

尽管如此,只要保证一定的限制,生成需要使用的数据是有意义的。(例如,
decode_json
的输出需要使用它,并且可以安全使用,因为
decode_json
永远不会产生对象或神奇变量。)当需要时,通常会执行大量检查,因此返回空字符串并没有真正的帮助

my $type = reftype($val);
if (!defined($type)) { ... }
elsif ($type eq 'HASH') { ... }
elsif ($type eq 'ARRAY') { ... }
...

请注意,更改
reftype
会破坏此代码,因此更改
reftype
不是一个选项。我想说的是,你可以要求作者提供一种表现出你想要的方式的替代潜艇,但你也可以自己轻松地制作这种潜艇。

这似乎不是一个合适的要求。无论如何,它不太可能改变,因为现在它将是一个没有实际好处的backcompat破坏。为什么在输入不是引用时它应该返回reftype?对我来说似乎是荒谬的,使用unde表示没有值似乎很好。可以说,问题不在于reftype(),而在于Perl的比较运算符如何处理undef。显然,这是无法改变的,不。我自己也想问这个问题(但在这里已经找到了这个问题)…我希望有一些好的理由可以让我学习,这样我就不会太烦恼了。现在,如果对某个应该是数组引用的对象进行输入验证,我必须记住,如果传入的对象根本不是引用,那么比较将失败,并分两步而不是一步进行检查。我关心的是“hash ref”与“everything”,因为第二种情况是carp()。它应该返回一个易于检查的值,而不是一个难以检查的值,以表明它不是引用。必须分两个阶段进行检查很烦人,而且很容易被忘记,许多人甚至多年来都没有意识到他们需要这样做。在我看来,这个论点不适用于我最经常使用reftype的地方——也就是在我验证输入时。我希望得到一个hash ref,如果我得到其他任何东西,我会发出carp()或croak()之类的命令。相反,如果代码在undef警告中失败,那么我的错误报告就不那么好了,我必须记住在每种情况下都添加额外的代码。好吧,或者干脆关掉undef警告;这可能是更好的解决方案。@dd-b你错了。理由是它只在有缺陷的代码中发出警告,而您的代码是有缺陷的。在您描述的情况下使用
reftype
是错误的,因为它有时会给出错误的答案。