11

在 PHP 中,我可以写:

$vname = 'phone';
$$vname = '555-1234';
print $phone;

...脚本将输出“555-1234”。

Perl 中是否有任何等价物?

有没有办法限制$phone本地块的范围,就像我写的一样my $phone?使用my $$vname给我“无法在我的 at ... 中声明标量取消引用”错误。

4

5 回答 5

57

您尝试做的事情称为“符号引用”。虽然您可以在 Perl 中执行此操作,但您不应该这样做。符号引用仅适用于全局变量——不适用于词法 ( my) 变量。没有办法限制它们的范围。符号引用是危险的。strict出于这个原因,它们在pragma下不起作用。

通常,每当您认为需要符号引用时,都应该使用散列:

my %hash;
$hash{phone} = '555-1234';
print $hash{phone};

在少数情况下,symrefs 很有用,甚至是必要的。例如,Perl 的导出机制使用它们。这些是高级主题。当你准备好迎接他们时,你不需要问如何。;-)

于 2008-11-12T02:25:22.300 回答
13

阅读 Mark-Jason Dominus 在“为什么将变量用作变量名是愚蠢的”中反对这样做的咆哮。

您可以通过以以下方式开始块来限制对 $phone 的更改范围

local $phone;

甚至

local $$vname;

(尽管对于从您的块中调用的任何 subs 都更改了 $phone ,但它与my()声明的词法范围不同。)

于 2008-11-12T08:08:20.530 回答
8

您可以以非常相似的方式进行操作:

$vname = "phone";
$$vname = "555-1234";
print $phone;

但你可以并不意味着你应该。正如 Michael Carman 所说,最好的管理方法是使用 HASH!

于 2008-11-12T00:56:46.893 回答
6

您不能在启用 strict pragma 的情况下执行此操作,并且通常应该始终启用 strict pragma。不过,您可以在关闭编译指示的情况下执行此操作,请看一下这一行:

perl -le 'my $vname = "phone"; ${ $vname } = "555-1234"; print $phone'

这将起作用,但这不会:

perl -Mstrict -le 'my $vname = "phone"; ${ $vname } = "555-1234"; print $phone'

“-Mstrict”告诉它“使用严格”。

对这样的事情使用散列几乎总是更好,这与 PHP 中的关联数组大致相同。

于 2008-11-12T01:12:19.683 回答
0

您确实意识到 PHP 继承了 Perl 的许多特性,对吧?

Perl 不仅可以做 PHP 可以做的所有符号引用的事情,

use strict;
use warnings;
use 5.010;

our $test=1;

# Access $test through the special hash %::
say ${$::{test}}++;

# This is essentially what the previous line did.
say ${\$test}++

# Same as $test
say ${test}++;

{
  # PHP's simple symbolic ref
  my $ref = "test";
  no strict 'refs';
  say $$ref++;
  say ${"test"}++;
}
{
  package d;
  say ${$main::{test}}++;

  my $ref = $main::{"test"};
  say $$ref++;

  $ref = \$main::test;
  say $$ref++;
}
于 2009-07-21T01:24:30.113 回答