do_something and do_other_stuff
# abc
do_something && do_other_stuff
# abc
28
Casa do Código
Capítulo 2. Conhecendo Ruby
# No ||, do_other_stuff não é avaliado por ser operador
# de curto circuito!
do_something || do_other_stuff
# 123
# Caso 1: and
if var = do_something and do_other_stuff
puts "var is #{var}"
end
# var is 123
# Caso 2: &&
if var = do_something && do_other_stuff
puts "var is #{var}"
end
# var is abc
Nestes exemplos, é possível ver que há uma confusão. No primeiro caso a asso-
ciação (var =) tem maior precedência e é executado antes do and, ou seja, a execu-
ção é a mesma que (var = do_something) and do_other_stuff. Já no segundo
caso, o && é executado antes, portanto temos o mesmo que var = (do_something
&& do_other_stuff). Fica muito difícil de ler, portanto a recomendação é sempre
usar o operador && e || e parênteses para deixar o código mais claro, ou ainda me-
lhor, fazer a associação fora do if.
elsif
É possível ainda usar o elsif, uma combinação de else com if:
a = 1
# => 1
if a == 0
puts "A é 0"
elsif a == 1
puts "A é 1"
else
puts "A não é nenhum"
end
# A is 1
29
2.4. Fluxos e laços
Casa do Código
unless
Também herdado do Perl é o unless, que basicamente inverte o comportamento
do if, ou seja, o bloco associado é executado se a expressão
associada retorna false:
a = 0
# => 0
# Uso comum, sem else
unless a == 0
puts "A não é zero"
end
# => nil
# Uso com else
unless a == 0
puts "A não é zero"
else
puts "A é zero, na verdade!"
end
# A é zero, na verdade
# => nil
# Uso do unless como posfixo
puts "A é zero" unless a > 0
# A é zero
# => nil
Dica: Cuidados com o uso do unless
O unless pode ser muito confuso para entender caso você tenha múl-
tiplas cláusulas na expressão associada, já que ele inverte a lógica do if
que já é de costume.
Outro problema do unless é com o else, por exatamente o mesmo mo-
tivo. É preferível, neste caso, inverter os blocos e usar if diretamente,
que é muito mais legível e sem pegadinhas.
O operador ternário ? também pode ser usado, conhecido de linguagens como
Java e C:
30
Casa do Código
Capítulo 2. Conhecendo Ruby
a = 0
# => 0
a == 0 ? puts("É zero!") : puts("Não é zero")
# É zero!
# => nil
O operador ternário ? recebe, do seu lado esquerdo a expressão a ser avaliada.
No seu lado direito, a primeira parte é para o caso da expressão ser true e o outro
lado, caso seja false.
Use com cautela, pois, nesse caso por exemplo, é necessário explicitar os parên-
teses devido a confusão com precedência de operadores. O ? deve ser usado com
pequenas linhas de código para não prejudicar a legibilidade.
case
O case é usado quando há muitas condições a serem checadas, evitando muitos
else e elsif:
case
when a > 0
puts "A é maior que 0"
when a < 0
puts "A é menor que 0"
when a == 0
puts "A é 0"
else
puts "Quebramos a matemática!"
end
# A é 0
# => nil
31
2.4. Fluxos e laços
Casa do Código
Cascade em Ruby
Em linguagens como C e JavaScript, uma vez que o interpreta-
dor/compilador encontra um caso verdadeiro, todo o código restante é
executado, independente se os resultados dos outros cases sejam false.
Esse fenômeno é chamado de cascade:
// Cascade em JavaScript:
var a = 1;
switch(a) {
case 0:
console.log("0");
case 1:
console.log("1");
case 2:
console.log("2");
}
// 1
// 2
Para resolver esse problema, é necessário executar um break:
// Cascade em JavaScript:
var a = 1;
switch(a) {
case 0:
console.log("0");
break;
case 1:
console.log("1");
break;
case 2:
console.log("2");
break;
}
// 1
32
Esse fenômeno não acontece com Ruby, portanto não é necessário tem-
perar o case com breaks.
Casa do Código
Capítulo 2. Conhecendo Ruby
O case é especial. Para alguns tipos de objetos, ele pode reagir diferente, veja os
exemplos a seguir:
case number_of_kills
when 0..10
puts ""
when 11..20
puts "Monster kill!"
when 21..40
puts "Rampage!"
when 41..70
puts "DOMINATING!"
else
puts "GODLIKE!"
end
Neste exemplo, verificamos a que intervalo pertence a variável number_of_kills
com o uso de Range (veremos mais detalhes sobre Ranges na seção 2.3). Vejamos
agora um exemplo com strings:
case input_date
when /\d{4}-\d{2}-\d{2}/
puts "O formato é yyyy-mm-dd"
when /\d{2}-\d{2}-\d{4}/
puts "O formato é dd-mm-yyyy"
when /\d{2}-\d{2}-\d{2}/
puts "O formato é dd-mm-yy"
else
puts "Não sei que formato é"
end
Neste caso, o bloco associado ao when irá ser executado quando a string bater
com expressão regular.
Case statement operator
Não é escopo deste livro ensinar internamente como o Ruby verifica isso,
mas se você tiver interesse em saber como isto é feito, busque pelo mé-
todo === ou case statement operator.
33
2.4. Fluxos e laços
Casa do Código
while e until
while e until são conhecidos de qualquer linguagem imperativa. O while exe-
cuta um bloco associado de código enquanto a condição
estiver satisfeita:
a = [1, 2, 3]
while a.length > 0 do
puts "Bye bye, #{a.pop}"