Неведомый Array#find

November 20, 2014

Полагаясь на интуицию, как делаю в 90% случаев, программируя на Руби, я написал проверку наличия элемента в массиве array.find(4) ? 'success' : 'fail' и с удивлением узнал, что это не работает.

Документация нам подсказывает , что find вернет Enumerator если блок не задан.

[1, 2, 3].find(4)  # =>  #<Enumerator: [1, 2, 3]:find(4)>

Любой объект в руби - это true, поэтому конструкция из вступления будет всегда возвращать success. Есть несколько способов исправить ситуацию.

Использовать блочную версию find (не очень изящно, но работает):

[1, 2, 3].find { |x| x == 4 }  # =>  nil

Использовать метод index или include? (я так делаю, когда пишу на чистом руби):

[1, 2, 3].index(4)     # =>  nil
[1, 2, 3].include?(4)  # =>  false

В Рейлс (или когда просто подключен ActiveSupport) еще есть метод #in? , позволяющий иногда сделать код более читаемым:

array = [1, 2, 3]
4.in?(array)       # =>  false

На один неправильный вариант использования find, есть много правильных.

comments powered by Disqus