在 Perl 中使用裸词有哪些陷阱?
What are the pitfalls in using bare words in Perl?
我知道裸词可以用作引号运算符(q//、qq//)、哈希键等中的字符串。我个人对此并不太兴奋,因为我无法克服应该引用文字字符串的心理期望,如在 C、C++ 中一样。但是,如果我要混合使用引号字符串和裸词,我想确保我不会不小心搬起石头砸自己的脚,因为裸词在运行时不会正确运行。
请排除 'use strict' 会在编译时将其捕获为错误的用例。我总是启用 'strict' 模式,所以我不关心这些情况。
下面是基于所提供的答案和评论的代码说明:
#!/usr/bin/perl
use strict;
use constant SIZE => "const_size";
sub size {
return "getsize";
}
my $href = {
size => 1,
getsize => 2,
const_size => "CONST_SIZE",
SIZE => "LARGE",
};
print "constant SIZE:", SIZE, "\n";
print "1. $href->{size}:", $href->{size}, "\n";
print "1a. $href->{size()}:", $href->{size()}, "\n";
print "2. $href->{getsize}:", $href->{getsize}, "\n";
print "3. $href->{SIZE}:", $href->{SIZE}, "\n";
print "3a. $href->{(SIZE)}:", $href->{(SIZE)}, "\n";
输出:
$ ./bare_word.pl
constant SIZE:const_size
1. $href->{size}:1
1a. $href->{size()}:2
2. $href->{getsize}:2
3. $href->{SIZE}:LARGE
3a. $href->{(SIZE)}:CONST_SIZE
关于 哈希键 ,裸词似乎在所有情况下都按预期运行。要覆盖该行为,我们需要明确消除歧义。
是的,如果引用不当,你可能搬起石头砸自己的脚:
$ perl -MData::Dumper -e'
my %h;
$h{"foo-bar"} = 1;
print Dumper \%h
'
$VAR1 = {
'foo-bar' => 1
};
$ perl -MData::Dumper -e'
my %h;
$h{foo-bar} = 1;
print Dumper \%h
'
$VAR1 = {
'0' => 1 # oops!
};
然而,严格模式将其从未捕获的逻辑错误转变为语法错误:
$ perl -Mstrict -MData::Dumper -e'
my %h;
$h{foo-bar} = 1;
print Dumper \%h
'
Bareword "foo" not allowed while "strict subs" in use at -e line 1.
Bareword "bar" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.
...除非:
$ perl -Mstrict -MData::Dumper -e'
sub foo { 1 }
sub bar { 1 }
my %h;
$h{foo-bar} = 1;
print Dumper \%h
'
Ambiguous use of -bar resolved as -&bar() at -e line 1.
$VAR1 = {
'1' => 1 # oops!
};
故事的寓意?始终 use strict;
,并始终引用不是 identifiers 的哈希键(标识符仅包含字母、数字和下划线,首字符不能是数字)。
Please exclude use cases where 'use strict' would catch them as errors at compile time.
use strict;
完全阻止了 barewords 的使用。允许裸词允许拼写错误非常安静地失败 and/or。
文档声称小写裸词在未来的 Perl 版本中可能会被误解为函数调用,但事实并非如此。需要启用新功能,例如 say
.
也就是说,我认为您实际上是想谈论自动引用的哈希键。可能会造成混淆,因为有人可能会写 $hash{foo}
并期望它等同于 $hash{foo()}
。但不仅 foo
(与 foo()
相对)首先是一种奇怪的调用 sub 的方式,而且没有人愿意首先编写 $hash{foo()}
。 (肯定需要争论。)
唯一防止代码被误解的可能性无限小的是常量被用作散列键的可能性。 $hash{CONSTANT}
会失败。需要使用 $hash{(CONSTANT)}
、$hash{+CONSTANT}
或其他形式的消歧。
我知道裸词可以用作引号运算符(q//、qq//)、哈希键等中的字符串。我个人对此并不太兴奋,因为我无法克服应该引用文字字符串的心理期望,如在 C、C++ 中一样。但是,如果我要混合使用引号字符串和裸词,我想确保我不会不小心搬起石头砸自己的脚,因为裸词在运行时不会正确运行。
请排除 'use strict' 会在编译时将其捕获为错误的用例。我总是启用 'strict' 模式,所以我不关心这些情况。
下面是基于所提供的答案和评论的代码说明:
#!/usr/bin/perl
use strict;
use constant SIZE => "const_size";
sub size {
return "getsize";
}
my $href = {
size => 1,
getsize => 2,
const_size => "CONST_SIZE",
SIZE => "LARGE",
};
print "constant SIZE:", SIZE, "\n";
print "1. $href->{size}:", $href->{size}, "\n";
print "1a. $href->{size()}:", $href->{size()}, "\n";
print "2. $href->{getsize}:", $href->{getsize}, "\n";
print "3. $href->{SIZE}:", $href->{SIZE}, "\n";
print "3a. $href->{(SIZE)}:", $href->{(SIZE)}, "\n";
输出:
$ ./bare_word.pl
constant SIZE:const_size
1. $href->{size}:1
1a. $href->{size()}:2
2. $href->{getsize}:2
3. $href->{SIZE}:LARGE
3a. $href->{(SIZE)}:CONST_SIZE
关于 哈希键 ,裸词似乎在所有情况下都按预期运行。要覆盖该行为,我们需要明确消除歧义。
是的,如果引用不当,你可能搬起石头砸自己的脚:
$ perl -MData::Dumper -e'
my %h;
$h{"foo-bar"} = 1;
print Dumper \%h
'
$VAR1 = {
'foo-bar' => 1
};
$ perl -MData::Dumper -e'
my %h;
$h{foo-bar} = 1;
print Dumper \%h
'
$VAR1 = {
'0' => 1 # oops!
};
然而,严格模式将其从未捕获的逻辑错误转变为语法错误:
$ perl -Mstrict -MData::Dumper -e'
my %h;
$h{foo-bar} = 1;
print Dumper \%h
'
Bareword "foo" not allowed while "strict subs" in use at -e line 1.
Bareword "bar" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.
...除非:
$ perl -Mstrict -MData::Dumper -e'
sub foo { 1 }
sub bar { 1 }
my %h;
$h{foo-bar} = 1;
print Dumper \%h
'
Ambiguous use of -bar resolved as -&bar() at -e line 1.
$VAR1 = {
'1' => 1 # oops!
};
故事的寓意?始终 use strict;
,并始终引用不是 identifiers 的哈希键(标识符仅包含字母、数字和下划线,首字符不能是数字)。
Please exclude use cases where 'use strict' would catch them as errors at compile time.
use strict;
完全阻止了 barewords 的使用。允许裸词允许拼写错误非常安静地失败 and/or。
文档声称小写裸词在未来的 Perl 版本中可能会被误解为函数调用,但事实并非如此。需要启用新功能,例如 say
.
也就是说,我认为您实际上是想谈论自动引用的哈希键。可能会造成混淆,因为有人可能会写 $hash{foo}
并期望它等同于 $hash{foo()}
。但不仅 foo
(与 foo()
相对)首先是一种奇怪的调用 sub 的方式,而且没有人愿意首先编写 $hash{foo()}
。 (肯定需要争论。)
唯一防止代码被误解的可能性无限小的是常量被用作散列键的可能性。 $hash{CONSTANT}
会失败。需要使用 $hash{(CONSTANT)}
、$hash{+CONSTANT}
或其他形式的消歧。