В PHP я могу написать:
$vname = 'phone'; $$vname = '555-1234'; print $phone;
… И скрипт выведет «555-1234».
Есть ли эквивалент в Perl?
Есть ли способ ограничить $phone
областью локального блока, как будто я написал my $phone
? Использование my $$vname
дает мне my $$vname
«Невозможно объявить скалярное разыменование в моем при …».
То, что вы пытаетесь сделать, называется «символической ссылкой». Хотя вы можете сделать это в 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++; }