Какова лучшая практика Perl для возврата хешей от функций?

Если бы Вы ловите свои исключения для дружественных пользовательских сообщений или регистрируетесь, Вы, вероятно, хотели бы, чтобы отладчик остановился при исключении при отладке. Перейдите к Отладке/Исключениям и проверьте типы исключительной ситуации, которые Вы хотите, чтобы отладчик прекратил выполнять в, Система. NullReferenceException в Вашем случае.

14
задан Peter Mortensen 8 January 2014 в 13:14
поделиться

7 ответов

Просто верните ссылку. Нет необходимости разыменовывать все хеш, как в ваших примерах:

my $result = some_function_that_returns_a_hashref;
say "Foo is ", $result->{foo};
say $_, " => ", $result->{$_} for keys %$result;

и т. д.

Я никогда не видел, чтобы кто-нибудь передавал пустые ссылки для хранения результата. Это Perl, а не C.

18
ответ дан 1 December 2019 в 07:06
поделиться

Попытка создать копии, говоря

my %hash = %{$ref_hash};

, даже более опасна, чем использование hashref. Это потому, что он создает только неглубокую копию. Это приведет вас к мысли, что изменять хеш - это нормально, но если он содержит ссылки, они изменят исходную структуру данных. Я считаю, что лучше просто передавать ссылки и быть осторожными, но если вы действительно хотите убедиться, что у вас есть копия переданной ссылки, вы можете сказать:

use Storable qw/dclone/;

my %hash = %{dclone $ref_hash};
10
ответ дан 1 December 2019 в 07:06
поделиться

Если это'

4
ответ дан 1 December 2019 в 07:06
поделиться

Э ... «передача хэшей может быть выполнена только по ссылке»?

sub foo(%) {
    my %hash = @_;
    do_stuff_with(%hash);
}

my %hash = (a => 1, b => 2);
foo(%hash);

Что мне не хватает?

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

0
ответ дан 1 December 2019 в 07:06
поделиться

Первый вариант лучше:

my ($ref_array,$ref_hash) = $this->getData('input');

Причины:

  • во втором случае getData () необходимо проверьте структуры данных, чтобы сделать убедитесь, что они пусты
  • , вы можете вернуть undef в качестве специального значения
  • , это выглядит более Perl-идиоматическим.

Примечание: строки

@array = @{$ref_array};
%hash = %{$ref_hash};

сомнительны, поскольку вы неглубоко копируете здесь целые структуры данных . Вы можете использовать ссылки везде, где вам нужен массив / хэш, используя для удобства оператор ->.

5
ответ дан 1 December 2019 в 07:06
поделиться

Мои личные предпочтения для субинтерфейсов:

  1. Если процедура имеет 0–3 аргумента, они могут быть переданы в виде списка: foo ('a', 12, [1 , 2,3]);
  2. В противном случае передать список пар имя-значение. foo (one => 'a', two => 12, three => [1,2,3]);
  3. Если процедура имеет или может иметь более одного аргумента, серьезно подумайте об использовании пар имя / значение .

Передача ссылок увеличивает риск непреднамеренного изменения данных.

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

Я возвращаю хэш или ссылки на массив, когда это приведет к заметному увеличению скорости или потребления памяти (например, БОЛЬШИЕ структуры) или когда задействована сложная структура данных.

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

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

В случае передачи двух хешей я бы сделайте что-нибудь вроде:

my $foo = foo( hash1 => \%hash1, hash2 => \%hash2 ); # gets number of items returned
my @foo = foo( hash1 => \%hash1, hash2 => \%hash2 ); # gets items returned

sub foo {
   my %arg = @_;

   # do stuff

   return @results;
}
1
ответ дан 1 December 2019 в 07:06
поделиться
[

]Я первоначально поместил это на другой вопрос, а затем кто-то указал на это как на "сообщение о связи", так что я поместил это здесь, чтобы высказать свое мнение по этому вопросу, предполагая, что люди столкнутся с этим в будущем.[

] [

]Я собираюсь противоречить Принятому Ответу и сказать, что я предпочитаю, чтобы мои данные возвращались в виде обычного гашиша (ну, в виде четного списка, который, вероятно, будет интерпретирован как гашиш). Я работаю в среде, где мы обычно делаем такие вещи, как следующий фрагмент кода, и гораздо проще комбинировать и сортировать, а также нарезать кубики и кубики, когда не нужно разыменовывать каждую другую строку. (Также приятно знать, что кто-то не может повредить ваш хэш-файл, потому что вы передали его целиком по значению - хотя кто-то заметил, что если ваш хэш содержит больше, чем простые скаляры, это не так просто. )[

] [
my %filtered_config_slice = 
   hashgrep { $a !~ /^apparent_/ && defined $b } (
   map { $_->build_config_slice(%some_params, some_other => 'param') } 
   ($self->partial_config_strategies, $other_config_strategy)
);
] [

]Это приближает что-то, что мой код может сделать: построить конфигурацию для объекта, основанную на различных объектах стратегии конфигурации (некоторые из которых объект знает по сути, плюс какой-то лишний парень), а затем отфильтровать некоторые из них как не относящиеся к делу.[

] [

](Да, у нас есть хорошие инструменты вроде []hashgrep[] и []hashmap[] и []lkeys[], которые делают полезные вещи с хэшами. $a и $b устанавливаются на ключ и значение каждого элемента списка соответственно). [](Да, у нас есть люди, которые могут программировать на этом уровне. Найм - это неприятно, но у нас есть качественный продукт.)[][

] [

]Если вы не собираетесь делать ничего похожего на функциональное программирование вроде этого, или если вам нужно больше производительности (вы профилировали?), то конечно, используйте хэшрифы.[

].
1
ответ дан 1 December 2019 в 07:06
поделиться
Другие вопросы по тегам:

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