检查Perl数据引用类型

时间:2015-01-25 14:59:20

标签: perl reference

在Perl中检查引用类型时,为什么使用constant pragma更好:

use constant HASH => ref {};

die "I expect a hashref" unless $ref_type eq HASH;

比硬编码字符串:

die "I expect a hashref" unless $ref_type eq 'HASH';

有哪些优点和缺点(如果有的话)?

2 个答案:

答案 0 :(得分:5)

我可以看到的主要优点是,在strict 'subs'生效的情况下,如果标识符拼写错误,则会引发错误,而拼错字符串将被忽视。

例如,如果我写

use strict;
use warnings;

my $data = {};

die "I expect a hashref" unless ref $data eq 'HSH';

然后我的代码编译没有问题,但无法正常运行。但如果我有了

use strict;
use warnings;

use constant HASH => ref {};

my $data = {};

die "I expect a hashref" unless ref $data eq HSH;

然后我被告知

Bareword "HSH" not allowed while "strict subs" in use
在程序开始运行之前


这是提及Scalar::Util提供的reftype功能的合适位置。

ref运算符如果应用于简单哈希引用,则会返回HASH。但是,如果该引用已被祝福以将其转换为Perl对象,ref将返回引用已被祝福的类的名称。

对象通常是受祝福的哈希引用,但它可以通过对任何类型数据的引用形成 - 包括子例程和typeglobs。显然,一个简单的ref将无法帮助我们发现用于创建对象的基础Perl数据类型,因此编写了reftype来填补这一空白。

考虑一下这个Perl程序

use strict;
use warnings;

use Scalar::Util 'reftype';

my $data = { };

print "Plain hash reference\n";
printf "  ref     => %s\n", ref $data;
printf "  reftype => %s\n", reftype $data;

bless $data, 'Class';

print "\nBlessed hash reference\n";
printf "  ref     => %s\n", ref $data;
printf "  reftype => %s\n", reftype $data;

<强>输出

Plain hash reference
  ref     => HASH
  reftype => HASH

Blessed hash reference
  ref     => Class
  reftype => HASH

正如您所看到的,refreftype为简单的哈希引用返回相同的结果,而只有reftype可以在祝福引用的类后面看到它的基础数据类型不变。

答案 1 :(得分:1)

@Borodin在这种情况下有正确的答案,错字保护。值得一提的是,这种技术还可以保护您免受无证假设的影响。如果未记录ref {}的行为,则代码将在以后更改时继续工作。 (我想不出一个好的例子,它现在才有用)。

然而,记录ref变化行为的几率是不太可能的,你应该采取保险措施防止被撞上流星的恐龙击中。


您还询问了缺点。创建常量的性能非常小,但这只是在启动时。我们正在谈论毫秒。一旦创建,它们不会因使用而受到惩罚。