'a'..'e'
# Letras entre 'a' e 'e'
'a'...'e' # Letras entre 'a' e 'd', o 'e' fica de fora
A maior utilidade de Ranges é testar se um valor está em um intervalo:
valid_years = 1920..2010
valid_years.include? 1998 # true
valid_years.include? 1889 # false
Há um detalhe importante sobre Ranges. Eles podem ser discretos ou contínuos.
Por exemplo, ranges com floats são contínuos, ou seja, não existe um número finito
24
Casa do Código
Capítulo 2. Conhecendo Ruby
de valores inclusos dentro deste Range. Já um range discreto, existe um número
finito e enumerável de elementos.
Isso se reflete em alguns métodos, inclusive o bastante útil #to_a:
years = 2000..2012
years.to_a
# [2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
#
2010, 2011, 2012]
length = 1.0..5.0
length.to_a
# TypeError: can't iterate from Float
true, false e nil
Diferente de outras linguagens, Ruby não possui um tipo booleano. Tudo em
Ruby é um objeto, e true, false e nil não fogem desta regra. Portanto, true é uma
instância singleton (ou seja, apenas uma única instância dessa classe irá existir em
todo o ciclo de vida de uma aplicação) da classe TrueClass, false, da FalseClass
e nil da NilClass. Dessa forma, estes valores não são comparáveis com 0 e 1, como
é comum em outras linguagens.
1 == 1
# true
1 > 1
# false
if "object"
puts "Objetos em geral resultam em 'true'"
end
# Objetos em geral resultam em 'true'
if 0
puts "0 é um objeto, portanto, true!"
end
# 0 é um objeto, portanto, true!
puts "nil é false em if" if nil
puts "falso é... falso." if false
25
2.4. Fluxos e laços
Casa do Código
Para verificar se um objeto é nil, é possível testar usando o método #nil?, im-
plementado em todos os objetos:
a = nil
a.nil? # true
b = 1
b.nil? # false
2.4
Fluxos e laços
if
Como toda linguagem de programação imperativa, temos controles de fluxos ine-
rente na sintaxe.
a = "0"
if a == "0"
puts "É true!"
else
puts "É falso :("
end
# É true!
# => nil
Uma coisa interessante que aconteceu no exemplo de código acima é que o IRB
nos exibiu não uma, mas duas saídas. A primeira é a impressão do texto na tela,
papel da função puts. Porém, como no primeiro trecho, temos o resultado com o
símbolo =>, denotando o que o bloco de código em si retornou. Isso dá-se ao fato de
que todo bloco de código Ruby retorna alguma coisa:
a = "0"
b = if a == "0"
1
else
2
end
# => 1
26
Casa do Código
Capítulo 2. Conhecendo Ruby
puts b # 1
puts a # "0"
Outro exemplo:
a = 0
if a == 0
10
else
20
end * 100
# => 1000
Note que, em Ruby, blocos de if terminam sempre com o end, com o else sendo
opcional. Existe outra maneira de se fazer if no Ruby que é muito útil: o if como
modificador, herança da linguagem Perl:
puts message if message # Imprime message se ela estiver definida
O if como modificador é muito conveniente e, dependendo de como for usado,
torna o código bastante legível. Portanto é encorajado para se fazer trechos curtos
(ou seja, uma linha) de código.
Para compor cláusulas em um if, podemos usar os operadores booleanos:
and - Clássico e, ou seja, sempre vai avaliar as duas expressões na direita e na
esquerda e verificar se ambas as expressões são verdadeiras;
or - Clássico ou, ou seja, sempre vai avaliar as duas expressões na direita e
na esquerda e verificar se pelo menos uma delas é verdadeira;
&& - E lógico, é parecido com o and, porém possui a característica de curto-
circuito, ou seja, se a expressão da esquerda for falsa, a expressão da direita
não vai ser avaliada;
|| - Ou lógico, parecido com o or, porém possui característica de curto-
circuito, ou seja, se a expressão da esquerda for verdadeira, a expressão da
direita não é executada;
! - O not, ou seja, inverte true em false e vice-versa.
Exemplos:
27
2.4. Fluxos e laços
Casa do Código
age = 10
parents_are_together = true
puts "Não pode beber" if age < 18
puts "Pode votar, mas não beber" if age < 18 and age >= 16
puts "Pode votar, mas não beber" if age < 18 && age >= 16
puts "Pode ver o show" if age > 18 or parents_are_together
puts "Pode ver o show" if age > 18 || parents_are_together
puts "Pode ir pra balada" if !parents_are_together
Booleanos e valores truthy e falsy
Truthy e falsy são maneiras de explicar o comportamento de tipos
(inteiro, string, etc.) em lógica de controle, tal como o if. Ou seja, se um
valor é truthy, o if é executado e, se falsy, não.
No Ruby, apenas false e nil são falsy, todos os outros tipos são
truthy, mesmo que o inteiro seja 0 (zero) ou se a string for (vazia).
Tome bastante cuidado!
Atenção com precedência de operadores booleanos!
Os operadores booleanos são utilizados não somente para a composição de if, e
portanto os operadores or e || possuem precedência diferentes (e o mesmo acontece
para o e), tendo or e and menor precedência. Veja os exemplos abaixo:
do_something = "123"
do_other_stuff = "abc"
# Observemos que and e && retornam o valor da última sentença
# avaliada