Я скопировать соответствующую часть моего ответа от the other question здесь.
Особое внимание уделяется интерфейсу. Как будет использоваться возвращаемый массив? Это важно, потому что разыменование целых массивов в Perl выглядит ужасно. Например:
for my $info (@{ getInfo($some, $args) }) {
...
}
Это уродливое. Это намного лучше.
for my $info (getInfo($some, $args)) {
...
}
Он также поддается картированию и grepping.
my @info = grep { ... } getInfo($some, $args);
Но возвращающий реф массив может быть удобно, если вы собираетесь выбрать отдельные элементы:
my $address = getInfo($some, $args)->[2];
Это проще, чем:
my $address = (getInfo($some, $args))[2];
Или:
my @info = getInfo($some, $args);
my $address = $info[2];
Но в этот момент вы шо uld вопрос, является ли @info действительно списком или хешем.
my $address = getInfo($some, $args)->{address};
В отличие от массивов против рефов массива, нет особых причин, чтобы выбрать, чтобы вернуть хэш по хэш-реф. Хэш-ссылки позволяют использовать короткие руки, например, код выше. И напротив массивов vs refs, он делает итератор более простым или, по крайней мере, избегает переменной среднего человека.
for my $key (keys %{some_func_that_returns_a_hash_ref}) {
...
}
То, что вы не должны сделать, это getInfo()
возвращают реф массив в скалярном контексте и массив в контексте списка. Это мешает традиционному использованию скалярного контекста как длины массива, что удивит пользователя.
Я хотел бы добавить, что, делая все последовательно, X - хорошее эмпирическое правило, это не имеет первостепенного значения при разработке хорошего интерфейса. Пойдите слишком далеко с этим, и вы можете легко справиться с другими более важными проблемами.
Наконец, я подключу свой собственный модуль, Method::Signatures, потому что он предлагает компромисс для передачи ссылок на массивы без использования синтаксиса ref ref.
use Method::Signatures;
method foo(\@args) {
print "@args"; # @args is not a copy
push @args, 42; # this alters the caller array
}
my @nums = (1,2,3);
Class->foo(\@nums); # prints 1 2 3
print "@nums"; # prints 1 2 3 42
Это делается с помощью магии Data::Alias.
В "my ($ result) = [];", почему parens? – ysth
Опять же, для последовательности, я всегда делаю my ($ foo); my ($ bar, $ baz); Я никогда не делаю «мой $ foo», потому что некоторые из моих «моих» находятся в скалярном контексте, а некоторые из них находятся в контексте списка. Следовательно, я иногда делаю my ($ cnt) = scalar (@array); , который, я уверен, привел бы людей в бешенство .... –