如何传递定义为常量的数组的引用?

How can I pass a reference of an array defined as constant?

我定义了哈希和数组常量,将它们传递给函数时,我必须将它们作为引用传递。 但是我想知道正确的语法是什么。

考虑这个例子:

#!/usr/bin/perl
use strict;
use warnings;

use constant AC => qw(a b c);

sub f($)
{
    print "ref=", ref $_[0], "\n";
    print "$_\n" foreach (@{$_[0]});
}

f(\AC);

当我 运行 它时,我得到:

ref=SCALAR
Use of uninitialized value $_ in concatenation (.) or string at /run/media/whatever/constref.pl line 10.

Perl 调试器将 AC 打印为数组:

13: f(\AC);
  DB<1> x AC
0  'a'
1  'b'
2  'c'
  DB<2> c

List Constants section in the constant pragma 文档告诉我们

Constants may be lists of more (or less) than one value.
...
List constants are lists, not arrays.

这意味着,除其他属性外,不能引用该“列表常量”,就好像它是一个单独的实体,一个数组(变量);它表现为一个列表。

为了完成所要求的,我们需要从该列表中构建一个(匿名)数组引用并传递它,f([AC])

use warnings;
use strict;
use feature 'say';

use constant AC => qw(a b c);

sub f {
    my ($r) = @_;
    say "ref=", ref $r;
    say for @$r;
}

f( [ AC ] );

这将“列表常量”作为单个值、数组引用传递,并按预期打印。但是,我不喜欢必须复制值,也不喜欢进一步丢失 constant-ness. 的任何外观。还有其他方法可以做到这一点,但对我来说更不受欢迎。 §

我建议重新考虑在需要适当的 read-only 变量时使用的工具。

还有其他的库,我推荐 Const::Fast, or Readonly

use Const::Fast;    
const my @const_ary => qw(a b c);
f( \@const_ary );                 # same f() from above

use Readonly;
Readonly my @carr => qw(a b c);
f( \@carr );                      # same f() from above

这些是可以像处理任何其他变量一样处理的词法变量。请参阅文档。


尝试正式“引用”列表会导致引用列表

\($v, $t)  -->  $v, $t

虽然 AC 本身是一个常量,但它关联的列表 isn't read-only

use constant AC => qw(a b c);

(AC)[1] = "other";

say for AC;

打印

a
other
c

它们只是不稳定。


§ 我可以看到另外两种方式

  • constant pragma produces (is implemented as) a subroutine。然后 可以 使用它并按原样传递 f(\&AC),然后按原样使用它 say for $r->().

    但是,现在我们必须传递并取消引用该列表符号 (AC) 的子例程,并获得一个列表。这是一个非常糟糕的黑客攻击。

  • 问题中的代码使用了“常量列表”。可以改用引用,并且可以这样传递

    use constant AC => [ qw(a b c) ];
    
    # same sub f { } as above
    
    f( AC );  # prints as expected
    

    但是,除了先将其复制到 arrayref 之外,我不知道如何取消引用 AC 来获取整个列表(@{ AC } 行不通?),例如 f()。但这违背了将其作为 constant 的目的——所有 pretense to constant-ness 都被删除了。