在 Perl 中,哈希键周围的引号是一种好习惯吗?

Posted

技术标签:

【中文标题】在 Perl 中,哈希键周围的引号是一种好习惯吗?【英文标题】:Are quotes around hash keys a good practice in Perl? 【发布时间】:2010-09-28 22:19:03 【问题描述】:

在 Perl 中使用哈希时引用键是个好主意吗?

我正在处理一个非常大的遗留 Perl 代码库,并尝试采用 Damian Conway 在Perl Best Practices 中建议的许多最佳实践。我知道最佳实践总是程序员来说是一个敏感的话题,但希望我能在这个问题上得到一些好的答案,而不会引发一场激烈的战争。我也知道这可能是很多人不会争论的事情,因为它是一个小问题,但我正在努力获得一份可靠的指南列表,以便在我通过这个代码库工作时遵循。

在Perl Best Practices book by Damian Conway 中,有这个例子展示了对齐如何帮助一段代码的易读性,但它没有提到(在书中我能找到的任何地方)关于引用哈希键的任何内容。

$ident name    = standardize_name($name);
$ident age     = time - $birth_date;
$ident status  = 'active';

用引号来强调你没有使用裸词不是更好吗?

$ident 'name'    = standardize_name($name);
$ident 'age'     = time - $birth_date;
$ident 'status'  = 'active';

【问题讨论】:

【参考方案1】:

没有引号更好。它在 中,因此很明显您没有使用裸字,而且它更易于阅读和输入(少两个符号)。但这一切当然取决于程序员。

【讨论】:

不使用引号还有一个额外的好处,那就是在使用双引号和插值字符串时,您永远不会意外地击中自己的脚。 print "Hello $planet"Earth"\n";会导致语法错误,而print "Hello $planetEarth\n"; 不会。【参考方案2】:

在指定常量字符串哈希键时,您应该始终使用(单)引号。例如,$hash'key' 这是最佳选择,因为它无需考虑此问题并导致格式一致。如果您有时省略引号,则必须记住在您的密钥包含内部连字符、空格或其他特殊字符时添加它们。在这些情况下,您必须使用引号,从而导致格式不一致(有时不加引号,有时加引号)。带引号的键也更有可能被您的编辑器突出显示语法。

这是一个使用“有时引用,其他时候不引用”约定可能会给您带来麻烦的示例:

$settingsunlink-devices = 1; # I saved two characters!

use strict 下编译得很好,但在运行时不会完全符合您的预期。哈希键是字符串。字符串应根据其内容适当引用:单引号表示文字字符串,双引号表示允许变量插值。引用您的哈希键。这是最安全的约定,也是最容易理解和遵循的。

【讨论】:

这显然是一个主观问题,所以我选择了一个主观的答案。在阅读了每个人的回答后,我倾向于始终使用引号,而不是仅在需要它们以保持一致性和可能减少错误的情况下使用。 $settingsunlink-devices = 1; 实际上是做什么的? @Despertar 你可以通过运行 `perl -MO=Deparse -e "$settingsunlink-devices=1"` 来查看它,这会产生 $settingsunlink -'devices' = 1;。 unlink 是一个函数。你最终会得到$settings0=1【参考方案3】:

我从不单引号哈希键。我知道 基本上像引号一样工作,除了在特殊情况下(a + 和双引号)。我的编辑也知道这一点,并给了我一些基于颜色的提示,以确保我做到了我的意图。

在我看来,到处使用单引号就像不了解 Perl 的人所犯的“防御性”做法。节省一些键盘磨损并学习 Perl :)

随着咆哮,我发布此评论的真正原因......其他 cmets 似乎错过了+ 将“取消引用”一个裸词的事实。这意味着你可以写:

sub foo 
    $hash+shift = 42;

或:

use constant foo => 'OH HAI';
$hash+foo = 'I AM A LOLCAT';

所以很明显,+shift 表示“调用 shift 函数”,shift 表示“字符串 'shift'”。

我还要指出,cperl-mode 正确地突出了所有不同的情况。如果没有,请在 IRC 上 ping 我,我会修复它:)

(哦,还有一件事。我在 Moose 中引用属性名称,就像在 has 'foo' => ... 中一样。这是我与 stevan 一起工作时养成的习惯,虽然我认为它看起来不错......与我的其余代码有点不一致。也许我很快就会停止这样做。)

【讨论】:

什么是“cperl 模式”? Emacs 中有什么东西?【参考方案4】:

无引号的哈希键得到了 Larry Wall 的语法级别的关注,以确保它们除了最佳实践之外没有其他理由。不要担心引号。

(顺便说一句,数组键上的引号 php 中的最佳实践,如果不使用它们可能会产生严重后果,更不用说大量的E_WARNING。在Perl 中可以!= 在PHP 中可以.)

【讨论】:

在某处有提到拉里沃尔的采访或文章吗?我很想读它。 不知道。当它发生时,我在一些相关的邮件列表中。【参考方案5】:

我认为这方面没有最佳做法。我个人在哈希键中使用它们,如下所示:

$ident'name' = standardize_name($name);

但不要在箭头运算符的左侧使用它们:

$ident = name => standardize_name($name);

别问我为什么,我就是这么干的:)

我认为你能做的最重要的事情就是永远,永远,永远:

use strict;
use warnings; 

这样,编译器会为您捕获任何语义错误,从而减少您输入错误的可能性,无论您决定采用哪种方式。

第二个最重要的事情是保持一致。

【讨论】:

是的,一致性是关键。我试图在整个代码库中获得一致的风格,这是因脚本而异的领域之一。幸运的是,所有脚本都使用严格,但大多数当前不使用警告。我去的时候正在纠正这个问题。 :)【参考方案6】:

我不带引号,只是因为它减少了打字、阅读和担心。我有一个不会被自动引用的密钥的时间很少而且相差很远,因此不值得所有额外的工作和混乱。也许我对哈希键的选择已经改变以适合我的风格,这也是一样的。完全避免边缘情况。

这与我默认使用" 的原因相同。对我来说,在字符串中间插入一个变量比使用一个我不想插值的字符更常见。也就是说,我写'Hello, my name is $name' 的频率比"You owe me $1000" 多。

【讨论】:

【参考方案7】:

至少,在不太完美的编辑器中,引用可以防止语法高亮保留字。签出:

$ikeys = $a;
$ivalues = [1,2];
...

【讨论】:

【参考方案8】:

我更喜欢不带引号,除非我想要一些字符串插值。然后我使用双引号。我把它比作文字数字。 Perl 确实允许您执行以下操作:

$achoo['1']  = 'kleenex';
$achoo['14'] = 'hankies';

但是没有人这样做。而且它对清晰度没有帮助,仅仅是因为我们添加了另外两个字符来输入。就像有时我们特别想要数组中的插槽#3,有时我们想要%ENV 之外的PATH 条目。就我而言,单引号添加 no 清晰度。

Perl 解析代码的方式使得在哈希索引中无法使用其他类型的“裸词”。

试试

$myhashshift

而你只会得到存储在 'shift' 键下的散列中的项目,你必须这样做

$myhashshift()

为了指定您希望第一个参数来索引您的哈希。

此外,我使用jEdit,ONLY 可视化编辑器(我见过——除了 emacs),它允许 完全控制突出显示。所以这对我来说是双重清楚的。任何看起来像前者的东西都会得到 KEYWORD3 ($myhash) + SYMBOL () + LITERAL2 (shift) + SYMBOL () 如果在结束花括号之前有一个括号,它会得到 KEYWORD3 + SYMBOL + KEYWORD1 + SYMBOL (())。另外,我可能也会像这样格式化它:

$myhash shift() 

【讨论】:

像 $myhashshift 这样的东西正是你想要使用引号的原因,恕我直言。当然,知道你在做什么,但是可怜的 shmoe 在你离开后必须维护你的代码呢?他或她会看到并思考:Axeman 真的是指 shift 键或 shift() 吗? 这就是为什么“shift”可能永远不会是一个公开的键,只是偶然的——被称为 $hash$this_should_be_here。【参考方案9】:

引用引号!它们在视觉上分解了语法,更多的编辑器将在语法高亮中支持它们(嘿,甚至 Stack Overflow 也在高亮引用版本)。我还认为,当编辑检查您是否结束了报价时,您会更快地注意到拼写错误。

【讨论】:

所以你建议引用是因为当你忘记结束引用时你的编辑会告诉你? 奇怪的是,我认为这就是他所说的。要么这样,要么他是说因为字符串通常比普通代码更突出显示,所以更容易在哈希键中看到拼写错误? 奥威尔式?真的吗?不要偷懒。如果开发人员不懒惰或“聪明”,大量的 Perl 就很难维护。任何可以帮助他人阅读和维护代码的做法都是朝着正确方向迈出的一步。 或者我们可以省略引号以识别糟糕的语法荧光笔。 :)【参考方案10】:

使用引号更好,因为它允许您使用裸词中不允许的特殊字符。通过使用引号,我可以在哈希键中使用我母语的特殊字符。

【讨论】:

【参考方案11】:

我自己也想过这个问题,尤其是当我发现自己犯了一些错误时:

 use constant CONSTANT => 'something';
 ...
 my %hash = ()
 $hashCONSTANT          = 'whoops!';  # Not what I intended
 $hashword-with-hyphens = 'whoops!';  # wrong again 

如果至少有一个文字键需要引号,我现在倾向于在每个哈希的基础上普遍应用引号;并使用带常量的括号:

 $hashCONSTANT() = 'ugly, but what can you do?';

【讨论】:

【参考方案12】:

您也可以在密钥前面加上“-”(减号),但请注意,这会将“-”附加到密钥的开头。来自我的一些代码:

$args-title ||= "Intrig";

我也使用单引号、双引号和无引号的方式。都在同一个程序中:-)

【讨论】:

你们要杀了我 :-) 为什么叮?这是一个主观问题? 问题是 -title 是 != 到标题。它们是两个不同的键。 投票最多和投票最多的答案是否有徽章?我认为这个是赢家:-)【参考方案13】:

我一直在使用它们时不带引号,但我会重复使用严格和警告,因为它们会找出大多数常见错误。

【讨论】:

除了 strict 对哈希键没有任何作用,并且警告可能会在远离错误的哈希读取的地方触发。这是由内而外的对象和命运多舛的伪哈希(现在是受限哈希)的推动力之一。 它可能会警告使用未定义的值。 是的,当使用散列 value 时,通常远离错误点,因此不是非常有用。这并不是说不要使用严格和警告,只是它们不能解决这个问题。

以上是关于在 Perl 中,哈希键周围的引号是一种好习惯吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 perl 中使用嵌套映射是一种好习惯吗?

在数据仓库(关系)中有外键是一种好习惯吗?

在“for”循环条件中使用“三元运算”是一种好习惯吗?

在连接模型中验证 ID 是一种好习惯吗?

在整个应用程序中使用此 NSManagedObjectContext 是一种好习惯吗

在 Java 中更改参数是一种好习惯吗