2008-10-27 2 views
13

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

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

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

+1

Я изменил $ # $ # на массив в названии. Вы должны понимать, что $ # сам по себе является магической переменной (хотя я думаю, что он удалился в Perl 5.10) – 2008-10-27 21:19:07

+6

Кроме того, я хотел бы указать, что у вас есть потенциальная ошибка в вашем скрипте. Вы не должны возвращать (undef), а просто говорите о возврате.В контексте списка ваша функция будет оцениваться как истина! – 2008-10-27 21:23:20

ответ

34

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

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

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

print scalar @ret; 
+0

Кроме того, если @ret не имеет в нем ничего, $ # ret вернет -1. – 2008-10-27 21:22:55

5

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

23

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

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

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

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

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

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

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

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

А == в скалярном контексте, так что «скаляр» является излишним ...

return (undef) if @ret == 0; 

Но это просто многословный способ сказать «если @ret ложно».

return (undef) if [email protected]; 

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

return (undef) unless @ret; 

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

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

return unless @ret; 
2

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

my @ret = someMethod(); 
return if $DB_ERROR; 
return unless @ret; 
Смежные вопросы