Подтвердить что ты не робот

Есть ли в Perl динамические переменные типа PHP?

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

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

... И script выведет "555-1234".

Существует ли какой-либо эквивалент в Perl?

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

4b9b3361

Ответ 1

То, что вы пытаетесь сделать, называется "символической ссылкой". Хотя вы можете сделать это в Perl вам не следует. Символьные ссылки работают только с глобальными переменными - не лексическими (my). Невозможно ограничить их сферу охвата. Символьные ссылки опасны. По этой причине они не работают под strict прагмой.

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

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

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

Ответ 2

Прочитайте Mark-Jason Dominus, чтобы не делать этого в Почему это глупо "использовать переменную как имя переменной" .

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

local $phone;

или даже

local $$vname;

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

Ответ 3

Вы можете сделать это очень похоже:

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

Но вы можете это не значит, что вам нужно. Лучший способ справиться с этим - как говорит Майкл Карман, ИСПОЛЬЗОВАТЬ HASH!

Ответ 4

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

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

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

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

"- Mstrict" говорит "использовать строгий".

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

Ответ 5

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