У меня есть класс с методом, который возвращает хеш. Обычно, я получил бы результат как так:
%resp = $myclass->sub($foo);
И затем члены доступа возвращенного хеша как это:
$resp{key}{subkey};
в случае 2-го хеша.
Я полагаю, что должен быть способ объединить это в единственную, изящную строку, что-то вроде этого:
$myclass->sub($foo)->{key}{subkey}
Это, очевидно, не разыменовывается правильно, поскольку Perl возвращает это при попытке выполнить код:
Can't use string ("1/8") as a HASH ref
В попытке случайных последовательностей разыменования, из смотрящего "Ссылочного справочника" на Perlmonks, я придумал следующее, какой Perl не жалуется на, но также и не возвращает то, что я ищу:
$%{$myclass->sub($foo)}->{key}{subkey}
Кто-то может сказать мне, что волшебная escape-последовательность разыменования должна сделать это?
Лучше всего было бы изменить подпрограмму для возврата ссылки на хэш, но для получения требуемой функциональности:
{ $myclass->sub($foo) }->{key}{subkey}
, которая создаст ссылку на хэш из список, возвращаемый подпрограммой
, а затем немедленно разыменовать ее
Правка: Преимущество возврата хэш-ссылки из вашей подпрограммы, а не хеша (в виде списка) в значительной степени зависит от производительности. В случае hashref хэш создается один раз, а затем к нему осуществляется доступ. В случае со списком хэш создается, затем преобразуется в список, затем создается снова, а затем разыменовывается. Для маленьких хешей это не займет много времени, но для больших это просто ненужная работа во время выполнения. В принципе, если вы планируете использовать данные в виде списка в одних местах и в качестве хеша в других, возвращение хеша в виде списка вполне нормально. Но если вы всегда планируете использовать его как хэш, возврат ссылки будет более четким и быстрым.
Вместо этого я бы вернул ссылку на HASH из подпрограммы. В противном случае (возможно) ваш хэш без причины превращается в СПИСОК, а затем снова в ХЭШ:
sub mysub() {
...
return \%myhash;
}
При возврате ссылки требуется меньше копирования, следовательно, он более эффективен.
Просто верните хэш-ссылку вместо хеша:
$ myclass-> sub ($ foo) -> {key} -> {subkey}
Если вы всегда хотите получить только один подключ, напишите короткую подпрограмму, которая сделает это за вас, и забудьте о игре в гольф на своей линии. Одним из преимуществ является то, что вы можете легко добавить некоторую проверку работоспособности:
sub get_subkey {
my( $class, $arg, $key, $subkey ) = @_;
my $hashref = $class->method( $arg );
return unless ref $hashref;
return $hashref->{$key}{$subkey};
}
То, что вы пытаетесь сделать, не является ни элегантным, ни целесообразным. Вам каким-то образом удалось вызвать процедуру в скалярном контексте (именно этому соответствует "1/8"
).
Возвращаем хэш-ссылку.
Теперь посмотрите:
#!/usr/bin/perl
package My::Mine;
use strict; use warnings;
sub test {
my %h = (
a => { z => 1},
b => { y => 2},
);
return %h;
}
package main;
use strict; use warnings;
my $class = 'My::Mine';
print { $class->test }->{a}{z}, "\n";
Это не сработает. Вместо этого вам придется сделать:
print +{ $class->test }->{a}{z}, "\n";
Вот это элегантно (Нет!) Смотрите perldoc -f print.
Короче говоря, возвращаем ссылку на хэш.
Обратите внимание, что свежий анонимный хэш, который вы создаете, не является бесплатным. Также не бесплатна стоимость возврата хэша в виде плоского списка из подпрограммы.