有没有办法在Perl中使用“常量”作为哈希键?

时间:2008-09-18 20:54:26

标签: perl hash constants

有没有办法将常量用作散列键?

例如:

use constant X => 1;

my %x = (X => 'X');

上面的代码将创建一个散列,其中“X”作为键,而不是1作为键。然而,我想使用常数X的值作为关键。

9 个答案:

答案 0 :(得分:45)

use constant实际上是常量子程序。

要做你想做的事,你需要明确地调用sub:

use constant X => 1;

my %x = ( &X => 'X');

use constant X => 1;

my %x = ( X() => 'X');

答案 1 :(得分:19)

根据Damian Conway的Perl最佳实践中的建议,另一个选择是不使用使用常量编译指示并翻转到Readonly。

我意识到常量散列引用只是对散列的一个常量引用,但我没有做任何关于散列内部数据的事情。

readonly语法创建“正常查看”变量,但实际上会强制执行常量或只读。您可以像使用任何其他变量一样使用它。


use Readonly;

Readonly my $CONSTANT => 'Some value';

$hash{$CONSTANT} = 1;

答案 2 :(得分:14)

你的问题是=>是一个魔术逗号,自动引用它前面的单词。所以你写的相当于('X','X')。

最简单的方法是使用逗号:

my %x = (X, 'X');

或者,您可以添加各种标点符号,以便在=>前面不再有简单的单词:

my %x = ( X() => 'X' );
my %x = ( &X => 'X' );

答案 3 :(得分:9)

使用$hash{CONSTANT()}$hash{+CONSTANT}来防止裸字引用机制被踢入。

来自:http://perldoc.perl.org/constant.html

答案 4 :(得分:6)

其他大多数人都很好地回答了你的问题。总之,这些创建了对问题的完整解释和推荐的解决方法。问题是Perl pragma“use constant”确实在当前包中创建了一个子例程,其子名称是pragma的第一个参数,其值是最后一个。

在Perl中,一旦声明了子例程,就可以在没有parens的情况下调用它。

理解“常量”只是子程序,你可以看到它们没有用字符串插值的原因以及为什么“胖逗号”运算符“=>”引用左手参数认为你已经把它递给了一个字符串(尝试其他内置函数,比如time()和keys(),有时用胖逗号来获得额外的乐趣)。

幸运的是,您可以使用明显的标点符号来表示常量,例如parens或&符号。

但是,我有一个问题:你为什么要使用常量来表示哈希键呢?

我可以想到一些可能引导您朝这个方向发展的方案:

  1. 您希望控制哈希中的哪些键。

  2. 您希望抽象出密钥的名称,以防以后更改

  3. 在数字1的情况下,常量可能不会保存您的哈希值。相反,请考虑创建一个具有公共setter和getter的类,该类填充仅对该对象可见的哈希。这是一个非常不像Perl的解决方案,但很容易做到。

    在2号的情况下,我仍然坚持主张一个班级。如果通过定义良好的接口来调节对散列的访问,则只有该类的实现者负责获取正确的散列键名称。在这种情况下,我不会建议使用常量。

    希望这有助于并感谢您的时间。

答案 5 :(得分:5)

use constant pragma创建一个子例程原型,不带参数。虽然看起来就像一个C风格的常量,但它实际上是一个返回常量值的子程序。

=>(胖逗号)会自动引用左操作数,如果它是一个单词,就像$ hash {key}表示法一样。

如果您对常量名称的使用看起来像一个单词,引用机制将会启动,您将获得其名称作为键而不是其值。要防止这种情况,请更改用法,使其不是一个单词。例如:

use constant X => 1;
%hash = (X() => 1);
%hash = (+X => 1);
$hash{X()} = 1;
$hash{+X} = 1;

在初始值设定项中,您也可以使用普通逗号:

%hash = (X, 1);

答案 6 :(得分:2)

=>运算符将其左侧解释为“字符串”,qw()的方式。

尝试使用

my %x = ( X, 'X');

答案 7 :(得分:2)

一种方法是将X封装为(X):

my %x ( (X) => 1 );

另一种选择是取消'=>'并使用','代替:

my %x ( X, 1 );

答案 8 :(得分:1)

评论@shelfoo(声誉不足以直接在那里添加评论!)

完全同意达米安康威的Perl最佳实践......强烈推荐阅读。

但是,如果您计划将PBP用于内部样式指南,请阅读PBP Module Recommendation Commentary这是一个有用的“勘误表”。