Имеет ли Perl динамические переменные, подобные PHP?

в PHP, я могу написать:

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

... А скрипт выведет "555-1234".

есть ли эквивалент в Perl?

есть ли способ ограничить $phone в рамках локального блока, как если бы я написал my $phone? Используя my $$vname дает мне " не может объявить скалярное разыменование в моем at ..." ошибки.

5 ответов


что вы пытаетесь сделать, называется "символическая ссылка.- Пока ты можешь делать это в Перле!--4-->не стоит. Символьные ссылки работают только с глобальными переменными - не лексическими (my) из них. Невозможно ограничить их масштабы. символические ссылки опасны. по этой причине они не работают под strict ПРАГМА.

В общем, всякий раз, когда вы думаете, что вам нужны символические ссылки, вы должны использовать хэш вместо этого:

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

есть несколько случаев, когда symrefs полезны и даже необходимы. Например, механизм экспорта Perl использует их. Это продвинутые темы. К тому времени, когда вы будете готовы к ним, вам не нужно будет спрашивать, как. ;-)


прочитайте разглагольствования Марка-Джейсона Доминуса против этого в почему глупо "использовать переменную в качестве имени переменной".

вы ограничите область ваших изменений до $phone, запустив блок с

local $phone;

или даже

local $$vname;

(хотя либо изменяет $phone для любых подлодок, вызванных из вашего блока, так что это не то же самое, что лексическая область my() декларации.)


вы можете сделать это очень похожим образом:

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

но что вы можете не означает, что вы должны. Лучший способ справиться с этим, как говорит Майкл Кармен, ИСПОЛЬЗУЙТЕ ХЭШ!


вы не можете сделать это с включенной строгой прагмой, и строгая ПРАГМА обычно всегда должна быть включена. Вы можете сделать это с помощью pragma off, взгляните на этот лайнер:

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

он будет работать, но это не так:

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

"- Mstrict "говорит ему " использовать strict".

почти всегда лучше использовать хэш для чего-то подобного, что примерно совпадает с ассоциативным массивом в PHP.


вы понимаете, что 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++;
}