any?, all?, none? sem bloco
O que o curso de select já cobriu
A aula "Métodos relacionados do Enumerable", do curso do nível intern Enumerable Ruby: select, mostrou any?, all? e none? rodando com bloco: numbers.any? { |n| n > 4 }, numbers.all? { |n| n > 0 }, numbers.none? { |n| n > 10 }. Ela também cobriu count e find. Nada disso se repete aqui. Este curso começa de uma pergunta que aquela aula nunca fez: o que acontece sem bloco nenhum?
Cada elemento julgado pela própria truthiness
[1, 2, 3].all?
# true, todo elemento é truthy
[1, nil, 3].any?
# true, pelo menos um elemento (1) é truthy
[nil, false].any?
# false, nenhum dos dois elementos é truthy
Sem bloco, any?, all? e none? não comparam os elementos com nada. Eles perguntam se cada elemento, do jeito que está, conta como truthy ou falsy no sentido do Ruby. Só nil e false são falsy; todo o resto, inclusive 0 e "", é truthy.
Uma mistura que importa
[1, false, 3].all?
# false, o próprio false quebra "todo elemento é truthy"
[1, 2, 3].any?
# true, óbvio, mas também é [0]:
[0].any?
# true, 0 é truthy no Ruby, diferente de algumas outras linguagens
A última linha merece uma segunda olhada. Quem vem de uma linguagem em que 0 é falsy esperaria [0].any? dar false. No Ruby 4.0.1 desta app dá true. 0 é um objeto Ruby válido que não é nil nem false, e o any? sem bloco só pergunta "isto é nil ou false?"
Quando a forma sem bloco aparece
Código que checa algo específico normalmente usa a forma com bloco, all? { |x| x.valid? }. A forma sem bloco é útil quando a coleção já guarda os booleanos sobre os quais você pergunta:
checks = [user.present?, user.active?, user.email.present?]
checks.all?
# true só se toda checagem individual já veio truthy
Montar primeiro um array de condições e depois perguntar all? (ou any?) sobre o lote inteiro fica limpo, e você não repete as três checagens dentro de um bloco. (present? vem do Active Support do Rails; o padrão funciona com quaisquer booleanos.)
Pontos-chave
- Sem bloco,
any?,all?enone?checam a truthiness de cada elemento, sem comparação nem condição externa. - Só
nilefalsesão falsy em Ruby;0,""e qualquer outro objeto, inclusive arrays e hashes vazios, são truthy. [0].any?étrue, uma pegadinha para quem espera que0seja falsy como em outras linguagens.- A forma sem bloco serve quando a coleção já guarda um lote de booleanos para checar de uma vez.
Continue com a aula 2
A forma de argumento-padrão (Ruby 2.5+)
Desde o Ruby 2.5, esses métodos aceitam um argumento checado com ===, servindo para classes, ranges e regexes.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.