Разыменование скалярной ссылки в хеш-адресе - PullRequest
2 голосов
/ 26 января 2011

У меня есть hashref со значениями arrayrefs и scalarrefs. Я могу получить доступ к значениям arrayrefs, но не к скалярным ссылкам.


foreach (keys %$data) {
  if (ref $data->{$_} eq 'ARRAY') { 
    push @values, $data->{$_}[0];
  }
  elsif (ref $data->{$_} eq 'SCALAR') { 
    push @values, $data->???
  }
}

Как мне это сделать?

Ответы [ 2 ]

7 голосов
/ 26 января 2011

Чтобы разыменовать скалярную ссылку, просто предварите значение скалярным символом, $:

if (ref $data->{$_} eq 'SCALAR') { 
    push @values, ${$data->{$_}};
}

Ваш аргумент для arrayref не совсем правильный, так как вы разыменовываете ссылку на первый массив* element , вместо того, чтобы получать все элементы массива.Однако, так как вы храните скаляр, вы не можете сохранить все значения arrayref, если вы не преобразовали их каким-либо образом в скаляр - скажем, получите количество элементов в этом arrayref (то, что вы получите при оценкемассив в скалярном контексте) или путем объединения всех элементов массива в строку.

См. perldoc perlref :

Использование ссылок

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

$bar = $$scalarref;
push(@$arrayref, $filename);
$$arrayref[0] = "January";
$$hashref{"KEY"} = "VALUE";
&$coderef(1,2,3);
print $globref "output\n";

Важно понимать, что мы специально не разыменовываем там $ arrayref [0] или $ hashref {"KEY"}.Разыменование скалярной переменной происходит до того, как она выполняет какие-либо ключевые поиски.Все, что сложнее простой скалярной переменной, должно использовать методы 2 или 3 [ниже].Однако «простой скаляр» включает идентификатор, который сам использует метод 1 рекурсивно.Поэтому на следующий выводится «привет».

$refrefref = \\\"howdy";
print $$$$refrefref;
1 голос
/ 26 января 2011

Если вас интересуют только значения %$data, вы можете зациклить их вместо клавиш:

for my $value (values %$data) {
    if (ref $value eq 'ARRAY') {
        push @values, $value->[0];
    } elsif (ref $value eq 'SCALAR') {
        push @values, $$value;
    }
}

Более кратко и читабельно, ИМХО.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...