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

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

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

… И скрипт выведет «555-1234».

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

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

Solutions Collecting From Web of "Есть ли в Perl динамические переменные типа PHP?"

То, что вы пытаетесь сделать, называется «символической ссылкой». Хотя вы можете сделать это в Perl, вы не должны . Символьные ссылки работают только с глобальными переменными – не лексическими ( 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; 

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

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

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

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

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

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

Почти всегда лучше использовать хэш для чего-то подобного, что примерно так же, как ассоциативный массив в 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++; }