Ruby Data Types (parte 2)

Array, Hash e Boolean, o que faltava para você dominar os Ruby Data Types

Continuando nosso Magic Resource Data Types

Array

Um Array é um tipo de dado no qual podemos representar uma lista de objetos em Ruby. Uma das formas mais simples de criar um Array é colocar colchetes [] em volta de uma lista de objetos separados por vírgula:

2.1.6 :001 > array = [0, 1, 2]
 => [0, 1, 2]

Podemos criar um Array com qualquer tipo de objeto em Ruby, inclusive outro Array:

2.1.6 :001 > array = ['texto', 0, [1, 2], 'outro texto']
 => ["texto", 0, [1, 2], "outro texto"]

Para acessar um item do Array você pode fazer assim:

2.1.6 :001 > array = [0, 1, 2]
 => [0, 1, 2]
2.1.6 :002 > array[0]
 => 0
2.1.6 :003 > array[1]
 => 1

Apesar de não parecer [] é um método e essa forma que o Ruby nos permite acessar os itens de um Array é chamada Syntax Sugar. Veja:

2.1.6 :001 > array = [0, 1, 2]
 => [0, 1, 2]
2.1.6 :002 > array.[](0)
 => 0
2.1.6 :003 > array.[](1)
 => 1
2.1.6 :004 > array.[](3)
 => nil

No exemplo acima, quando tentamos acessar um item que não existe, o método [] nos retorna nil.

Podemos passar dois parâmetros para acessar uma parte de um Array:

2.1.6 :001 > array = [0, 1, 2, 5, 6, 8]
 => [0, 1, 2, 5, 6, 8]
2.1.6 :002 > array[2, 3]
 => [2, 5, 6]

No exemplo acima, com array[2, 3] acessamos, a partir da posição 2 (terceiro elemento), três itens da lista, que nos retornou [2, 5, 6]

Outro método interessante e muito usado em Arrays é o método <<. Ele adiciona um item na lista:

2.1.6 :001 > array = [0, 1, 2, 5, 6, 8]
 => [0, 1, 2, 5, 6, 8]
2.1.6 :002 > array << 10
 => [0, 1, 2, 5, 6, 8, 10]

Hash

Pense no seguinte problema, você tem um Array com os seguintes dados:

2.1.6 :001 > dados = ["José Arnaldo", 29, "Programador", "Casado", "Brasileiro", "São Paulo", "SP", "09995-000", "Rua do Meio, 44"]
 => ["José Arnaldo", 29, "Programador", "Casado", "Brasileiro", "São Paulo", "SP", "09995-000", "Rua do Meio, 44"]

Agora, como acessaria o endereço? Talvez dados[5] dados[6] dados[7] dados[8] ...?

Bem, no Ruby temos o Hash que é um conjunto de pares com chave e valor.

Para determinar um hash no Ruby basta usar chaves {} em volta dos pares separados por => (sintaxe antiga, evite!) ou separado por :, veja:

2.1.6 :001 > dados2 = {:nome=>"Jose Arnaldo", :profissao=>"Programador", :estado_civil=>"casado", :nacionalidade=>"Brasileiro", :cidade=>"São Paulo", :estado=>"SP", :cep=>"09995-000", :logradouro=>"Rua do Meio, 44"}
=> {:nome=>"Jose Arnaldo", :profissao=>"Programador", :estado_civil=>"casado", :nacionalidade=>"Brasileiro", :cidade=>"São Paulo", :estado=>"SP", :cep=>"09995-000", :logradouro=>"Rua do Meio, 44"}
2.1.6 :002 > dados3 = {nome: "Jose Arnaldo", profissao: "Programador", estado_civil: "casado", nacionalidade: "Brasileiro", cidade: "São Paulo", estado: "SP", cep: "09995-000", logradouro: "Rua do Meio, 44"}
=> {:nome=>"Jose Arnaldo", :profissao=>"Programador", :estado_civil=>"casado", :nacionalidade=>"Brasileiro", :cidade=>"São Paulo", :estado=>"SP", :cep=>"09995-000", :logradouro=>"Rua do Meio, 44"}

Em dados2 usamos a sintaxe antiga e em dados3 usamos a sintaxe nova (a partir do Ruby 1.9).

Agora, para acessar os dados de endereço, podemos fazer assim:

2.1.6 :003 > dados2[:cidade]
 => "São Paulo"
2.1.6 :004 > dados2[:estado]
 => "SP"
2.1.6 :005 > dados2[:cep]
 => "09995-000"
2.1.6 :006 > dados2[:logradouro]
 => "Rua do Meio, 44"

Muito mais fácil de ler, não?

Veja que nas chaves do Hash usamos um Symbol. Isso não é obrigatório, mas é muito frequente por ser único e mais fácil de comparar.

Como pode ver também, para acessar um dado de um Hash, basta usar o método [] com a chave correspondente. Caso a chave não exista, será retornado nil.

Mais um observação que pode parecer óbvia: a sintaxe {chave: valor} só pode ser usada se você quiser usar Symbol como chave, ser precisar de outro tipo de objeto você precisará usar a sintaxe mais antiga (mais conhecida por hash rocket) {"chave" => valor}.

Boolean

Boolean são basicamente true ou false, mas por quê? Ruby considera qualquer coisa diferente de nil e false como true. Mas vamos ao básico primeiro:

2.1.6 :001 > 1 < 2
true
2.1.6 :002 > 1 > 2
false
2.1.6 :003 > 1 == 2
false
2.1.6 :004 > 1 != 2
true

Até aqui nada demais, certo? Mostramos os operadores menor que <, maior que >, igual ==, diferente != e a forma óbvia que o Ruby avalia as expressões com esses operadores.

  • Atenção ao igual ==, somente um = é usado para atribuição, como vimos em diversos exemplos até agora.

Outros operadores lógicos são o E && e o OU ||. Com eles você pode combinar múltiplas expressões, veja:

2.1.6 :001 > 1 > 2 || 1 < 2
 => true
2.1.6 :002 > 1 != 2 && 1 == 2
 => false

As expressões acima podem ser lidas da seguinte forma

1 é maior que 2 OU 1 é menor que 2
Verdadeiro - 1 é menor que dois

1 é diferente de 2 E 1 é igual a 2
Falso - 1 não é igual a dois

Os operadores && e || operam em curto circuito. Isso significa que se em uma expressão com && a primeira avaliação (da esquerda) for false a segunda não será avaliada (por que não há necessidade). Já no caso do || , a segunda expressão só será avaliada se a primeira for false. Vamos aos exemplos:

2.1.6 :001 > x = 10
=> 10
2.1.6 :002 > x > 5 && 'x é maior que 5'
 => "x é maior que 5"
2.1.6 :001 > x == 5 || x = x + 1
 => 11

Vamos por parte, primeiro começamos com a expressão: x > 5, neste caso sim. Como estamos usando operador &&, precisamos avaliar a próxima expressão para determinar se é true. A próxima expressão é x é maior que 5.

No segundo exemplo, verificamos se x == 5. Neste caso é false, sendo assim verificamos a segunda expressão do || que é x = x + 1 e resulta em 11.

Em Ruby, um uso muito comum do short circuit é o operador ||=. Esse operador atribui o valor da direita caso a variável tiver valor considerado false (false e nil). Vamos aos exemplos:

2.1.6 :001 > x = nil
 => nil
2.1.6 :002 > x ||= 10
 => 10
2.1.6 :003 > x ||= 20
 => 10

Esse operador ||= também é um syntax sugar. A expressão x ||= 10 poderia ser escrita x = x || 10, no caso seria avaliada em x = nil || 10 e ainda x = 10, na segunda vez em x ||= 20, a variável x já tem valor atribuído diferente de nil, sendo assim seu valor não é alterado.

Por enquanto, é isso! Estes são os três Data Types que faltavam na nossa lista.

Esperamos que tenham gostado. Até mais!

Faça login para comentar.

Entrar

2 Comentários

Dany Silva

Dany Silva há mais de 1 ano

Bom, pra mim não ficou claro o exemplo com os boleanos aqui acima com o uso do ||= , ou seja o uso pela direita.


Ale Galliard

Ale Galliard há mais de 1 ano

Não sei se é o melhor jeito de explicar, mas eu entendi que é quase como se fosse um if ternário implícito (tem algo parecido com isso no javascript).

Testei assim pra entender melhor:

puts 'Quantos ovos quer pôr na cesta?' ovos = gets.strip

if ovos.size < 1 ovos = nil end

puts "#{ovos ||= 'Nenhum'} ovo(s) adicionado(s) à cesta"

que é o mesmo que

puts "#{ovos = ovos || 'Nenhum'} ovo(s) adicionado(s) à cesta"

Assim: eu estou assumindo que se a entrada do gets estiver vazia (dei um enter direto), 'ovos' passa a ser nulo, e aí cai na regra do 'nenhum'. Se vier qualquer valor na entrada, ele vai assumir o valor que passei. Resumindo, se ovos não for nulo, ovos = ovos. Mas se ovos for nulo, ovos = 'Nenhum'.

Acho que é mais ou menos isso. Espero ter ajudado.


Hidemitsu Goncalves Hashimoto

Hidemitsu Goncalves Hashimoto há 10 meses

Pelo que entendi é que o ||= atribui o valor da direita caso a varável ainda não tenha valor atribuído ou se seu valor atual for falso (false).


Gilvan

Gilvan há mais de 3 anos

outra alternativa para acessar o endereço no array dados: 2.1.6 :001 > dados = ["José Arnaldo", 29, "Programador", "Casado", "Brasileiro", "São Paulo", "SP", "09995-000", "Rua do Meio, 44"]

pode ser: irb(main):049:0> dados[5, 4] => ["São Paulo", "SP", "09995-000", "Rua do Meio, 44"]