Что означает $# массив в Perl?

Я просматриваю следующий фрагмент кода:

my @ret = <someMethod>
return (undef) if( $DB_ERROR );
return (undef) unless ($#ret >= 0);

Может ли $# дать вам количество элементов в массиве?

Ответы

Ответ 1

$#arrayname дает вам индекс последнего элемента, поэтому, если массив @ret имеет 2 элемента, то $#ret равен 1.

И, как заметил Барри Браун, пустой массив дает -1.

Чтобы получить длину, вы можете использовать массив в скалярном контексте:

print scalar @ret;

Ответ 2

edg правильный, но исходный код излишне тупой. В большинстве случаев $#foo является красным флагом, что код можно было бы написать проще, используя scalar @foo.

return (undef) unless ($#ret >= 0);

unless foo >= bar трудно разобраться. Во-первых, превратите его в положительное утверждение.

return (undef) if ($#ret < 0);

Когда $# ret < 0? Когда он -1. A $# ret of -1 - это массив длины 0. Таким образом, вышесказанное может быть написано гораздо проще, поскольку...

return (undef) if scalar @ret <= 0;

Но вы не можете иметь массив отрицательной длины, поэтому...

return (undef) if scalar @ret == 0;

И == находится в скалярном контексте, так что "скаляр" является избыточным...

return (undef) if @ret == 0;

Но это просто словесный способ сказать "if @ret false".

return (undef) if [email protected];

Я думаю, что для простых модификаторов операторов лучше выражать, если только.

return (undef) unless @ret;

Не так ли проще?

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

return unless @ret;

Ответ 3

Имейте в виду, что выражение $# array вернет -1, когда массив имеет нулевые элементы.

Ответ 4

Чтобы подвести итог всем остальным, этот код гораздо читабельнее, если он написан следующим образом:

my @ret = someMethod();
return if $DB_ERROR;
return unless @ret;