Как я разыменовываю хеш, это было возвращено из метода класса?

У меня есть класс с методом, который возвращает хеш. Обычно, я получил бы результат как так:

%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-последовательность разыменования должна сделать это?

7
задан brian d foy 13 February 2010 в 19:48
поделиться

5 ответов

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

{ $myclass->sub($foo) }->{key}{subkey}

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

Правка: Преимущество возврата хэш-ссылки из вашей подпрограммы, а не хеша (в виде списка) в значительной степени зависит от производительности. В случае hashref хэш создается один раз, а затем к нему осуществляется доступ. В случае со списком хэш создается, затем преобразуется в список, затем создается снова, а затем разыменовывается. Для маленьких хешей это не займет много времени, но для больших это просто ненужная работа во время выполнения. В принципе, если вы планируете использовать данные в виде списка в одних местах и ​​в качестве хеша в других, возвращение хеша в виде списка вполне нормально. Но если вы всегда планируете использовать его как хэш, возврат ссылки будет более четким и быстрым.

6
ответ дан 6 December 2019 в 10:49
поделиться

Вместо этого я бы вернул ссылку на HASH из подпрограммы. В противном случае (возможно) ваш хэш без причины превращается в СПИСОК, а затем снова в ХЭШ:

sub mysub() {
  ...
  return \%myhash;
}

При возврате ссылки требуется меньше копирования, следовательно, он более эффективен.

2
ответ дан 6 December 2019 в 10:49
поделиться

Просто верните хэш-ссылку вместо хеша:

$ myclass-> sub ($ foo) -> {key} -> {subkey}

1
ответ дан 6 December 2019 в 10:49
поделиться

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

 sub get_subkey {
      my( $class, $arg, $key, $subkey ) = @_;

      my $hashref = $class->method( $arg );
      return unless ref $hashref;

      return $hashref->{$key}{$subkey};
      }
0
ответ дан 6 December 2019 в 10:49
поделиться

То, что вы пытаетесь сделать, не является ни элегантным, ни целесообразным. Вам каким-то образом удалось вызвать процедуру в скалярном контексте (именно этому соответствует "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.

Короче говоря, возвращаем ссылку на хэш.

Обратите внимание, что свежий анонимный хэш, который вы создаете, не является бесплатным. Также не бесплатна стоимость возврата хэша в виде плоского списка из подпрограммы.

9
ответ дан 6 December 2019 в 10:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: