blank? e present?: os dois casos que surpreendem todo mundo
Um padrão de alternativa numa linha
O app/models/identity/user.rb, o model deste app:
name.presence || username
Isso dá o nome de exibição do usuário, se ele definiu um, e o username caso contrário. O presence (não o present?) devolve self quando o receptor conta como presente e nil quando não conta, então se encadeia direto com ||. Não há if/else, nem um booleano lido uma vez e jogado fora. É a extensão do ActiveSupport em Object, e funciona igual em strings, arrays, hashes, nil, booleanos e números, todos checados nesta aula.
A tabela-verdade completa, rodada neste app
nil.blank? # => true
"".blank? # => true
" ".blank? # => true
"x".blank? # => false
0.blank? # => false
1.blank? # => false
false.blank? # => true
true.blank? # => false
[].blank? # => true
[1].blank? # => false
{}.blank? # => true
{a: 1}.blank? # => false
São doze chamadas, rodadas no console deste app. O present? é !blank? para cada uma delas: o código do ActiveSupport o define assim, um método devolvendo a negação do outro.
Os dois casos que pegam as pessoas
0.blank? é false, e isso é uma fonte comum de bugs. Um número zero conta como presente, não como ausente, e o mesmo vale para a string "0" que um formulário envia. Um código que quer dizer "uma quantidade foi informada?" e usa .blank? para pegar um zero deliberado se surpreende assim que um usuário digita 0.
false.blank? é true, na direção oposta. Um campo booleano definido como false de propósito, como active: false ou visible: false, é lido como vazio por esse método, como se nunca tivesse sido definido. O trabalho do blank? é "isso seria inútil para exibir ou processar", não "isso é falso" nem "isso falta no hash de params". O false falha nesse primeiro teste mesmo sendo um valor válido e com significado.
O que este curso cobre
Sete aulas, cada uma checada contra o código deste app ou o código-fonte instalado do Rails. Esta aula trata de blank?, present? e presence, com a tabela-verdade e os dois casos surpreendentes. A aula 2 trata de Time.current contra Time.now, que diferem em horas na máquina que rodou estes exemplos. A aula 3 trata do ActiveSupport::Duration, o objeto por trás de .days, .hours e .ago, que não é um inteiro disfarçado. A aula 4 trata de beginning_of_day, beginning_of_week e beginning_of_month, encadeados em .ago na query de relatório mais rica deste app. A aula 5 trata do to_sentence, que transforma um array de erros em prosa legível com uma regra de pontuação própria. A aula 6 trata do try, e de uma correção sobre qual de except e except! ainda pertence ao ActiveSupport hoje.
Continue com a aula 2
Time.current contra Time.now, diferentes na máquina que os rodou
Por que Time.current e Time.now diferem em horas, e como o Rails define o Time.zone como UTC por padrão.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.