Если бы Вы ловите свои исключения для дружественных пользовательских сообщений или регистрируетесь, Вы, вероятно, хотели бы, чтобы отладчик остановился при исключении при отладке. Перейдите к Отладке/Исключениям и проверьте типы исключительной ситуации, которые Вы хотите, чтобы отладчик прекратил выполнять в, Система. NullReferenceException в Вашем случае.
Просто верните ссылку. Нет необходимости разыменовывать все хеш, как в ваших примерах:
my $result = some_function_that_returns_a_hashref;
say "Foo is ", $result->{foo};
say $_, " => ", $result->{$_} for keys %$result;
и т. д.
Я никогда не видел, чтобы кто-нибудь передавал пустые ссылки для хранения результата. Это Perl, а не C.
Попытка создать копии, говоря
my %hash = %{$ref_hash};
, даже более опасна, чем использование hashref. Это потому, что он создает только неглубокую копию. Это приведет вас к мысли, что изменять хеш - это нормально, но если он содержит ссылки, они изменят исходную структуру данных. Я считаю, что лучше просто передавать ссылки и быть осторожными, но если вы действительно хотите убедиться, что у вас есть копия переданной ссылки, вы можете сказать:
use Storable qw/dclone/;
my %hash = %{dclone $ref_hash};
Э ... «передача хэшей может быть выполнена только по ссылке»?
sub foo(%) {
my %hash = @_;
do_stuff_with(%hash);
}
my %hash = (a => 1, b => 2);
foo(%hash);
Что мне не хватает?
Я бы сказал, что если проблема в том, что вам нужно иметь несколько выводов из функции, лучше в качестве общей практики выводить структуру данных, возможно, хэш, которая содержит все, что вам нужно отправить, а не принимать изменяемые ссылки в качестве аргументов.
Первый вариант лучше:
my ($ref_array,$ref_hash) = $this->getData('input');
Причины:
Примечание: строки
@array = @{$ref_array};
%hash = %{$ref_hash};
сомнительны, поскольку вы неглубоко копируете здесь целые структуры данных . Вы можете использовать ссылки везде, где вам нужен массив / хэш, используя для удобства оператор ->.
Мои личные предпочтения для субинтерфейсов:
foo ('a', 12, [1 , 2,3]);
foo (one => 'a', two => 12, three => [1,2,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;
}
]Я первоначально поместил это на другой вопрос, а затем кто-то указал на это как на "сообщение о связи", так что я поместил это здесь, чтобы высказать свое мнение по этому вопросу, предполагая, что люди столкнутся с этим в будущем.[
] []Я собираюсь противоречить Принятому Ответу и сказать, что я предпочитаю, чтобы мои данные возвращались в виде обычного гашиша (ну, в виде четного списка, который, вероятно, будет интерпретирован как гашиш). Я работаю в среде, где мы обычно делаем такие вещи, как следующий фрагмент кода, и гораздо проще комбинировать и сортировать, а также нарезать кубики и кубики, когда не нужно разыменовывать каждую другую строку. (Также приятно знать, что кто-то не может повредить ваш хэш-файл, потому что вы передали его целиком по значению - хотя кто-то заметил, что если ваш хэш содержит больше, чем простые скаляры, это не так просто. )[
] [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 устанавливаются на ключ и значение каждого элемента списка соответственно). [](Да, у нас есть люди, которые могут программировать на этом уровне. Найм - это неприятно, но у нас есть качественный продукт.)[][
]Если вы не собираетесь делать ничего похожего на функциональное программирование вроде этого, или если вам нужно больше производительности (вы профилировали?), то конечно, используйте хэшрифы.[
].