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

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

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

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

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

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

Я поместил это в ответ CMS, потому что я не видел этого редактирования, но оно должно быть «$$ vname = '555-1234'», удалите «my».

gpojd 12.11.2008 04:15

Это устаревший код даже в PHP. Как уже писали другие, используйте хеш.

staticsan 12.11.2008 06:05

Эта функция была скопирована с Perl, когда PHP был написан на Perl.

Brad Gilbert 13.11.2008 03:35

PHP никогда не был написан на Perl twitter.com/rasmus/status/226405807305138176

Kevin Schroeder 21.07.2012 00:01

Обратите внимание, четыре года спустя мне очень стыдно, что я когда-либо задал этот вопрос. :)

Rob Howard 14.08.2012 08:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
11
5
11 924
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

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

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

Почему я никогда не знал, что вы можете сделать это на Perl?

Greg Hewgill 12.11.2008 04:01

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

Rob Howard 12.11.2008 04:07

Это дает мне следующую ошибку: «Глобальный символ« $ phone »требует явного имени пакета в строке 6 temp.pl».

Svante 12.11.2008 04:11

Роб Ховард - не используйте "my" для $$ vname Harleqin - отключите директиву strict, она не будет работать, если она включена

gpojd 12.11.2008 04:14

Если мне нужно выключить "строгий", конструкция сломается.

Svante 12.11.2008 04:58

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

brian d foy 12.11.2008 05:43

Для людей, проголосовавших против: он ответил на вопрос.

NotMe 13.11.2008 05:15

Арлекин: не уверен, что ты имеешь в виду; запрашиваемая функция существует в Perl, но считается достаточно опасной, чтобы заслужить строгий режим, специально запрещающий ее. Это не значит, что он сломан, просто опасно.

ysth 13.11.2008 09:24

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

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

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

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

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

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

Ответ принят как подходящий

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

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

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

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

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

Вы бы ограничили объем своих изменений $ phone, начав блок с

local $phone;

или даже

local $$vname;

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

Я никогда не думал об использовании C <local> для ограничения объема symref. Это и интересно, и извращенно. Это все равно, что сказать, что вы готовы выстрелить себе в ногу, но только из пневматического пистолета.

Michael Carman 12.11.2008 17:14

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

Другие вопросы по теме