Как я могу использовать переменную как имя переменной в Perl?

Мне нужно сделать следующее в perl

printmsg(@val1, $msg1) if @val1;
printmsg(@val2, $msg2) if @val2;
printmsg(@val3, $msg3) if @val3;
printmsg(@val4, $msg4) if @val4;
printmsg(@val5, $msg5) if @val5;
printmsg(@val6, $msg6) if @val6;

Итак, я написал следующий фрагмент

for(my $i=1; $i < 6; $i++ ) {
    printmsg(@val$i, $msg$i) if @val$i;
}

Он не работает и выходит из строя с ошибками.

Ответ 1

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

my @msgs = ('msg1', 'msg2', ..., 'msg6');
my @vals = ( [ @val1 ], [ @val2 ], ..., [ @val6 ] );

См. также FAQ Как использовать переменную в качестве имени переменной?

В качестве ответа на часто задаваемые вопросы, если переменные не индексируются целым числом, вы можете использовать хеш-таблицу:

Используя символические ссылки, вы просто используете хэш-таблицу таблицы символов пакета (например, %main::) вместо пользовательского хэша. Решение состоит в том, чтобы вместо этого использовать собственный хэш или реальную ссылку.

$USER_VARS{"fred"} = 23;
my $varname = "fred";
$USER_VARS{$varname}++;  # not $$varname++

Вы должны прочитать весь список часто задаваемых вопросов не реже одного раза в год.

Обновление: Я целенаправленно оставил символические ссылки из моего ответа, потому что они не нужны и, вероятно, очень вредны в контексте вашего вопроса. Для получения дополнительной информации см. Почему это глупо для использования переменной как имени переменной?, часть 2 и часть 3 MJD.

Ответ 2

Вы не можете просто сгруппировать переменные вместе и получить результирующую переменную. Вы МОЖЕТЕ оценить выражение $msg + i, но, вероятно, лучше, если вы создадите msg массив и просто индексируете: $msg[$i].