Fuentes Vinícius Baggio - Ruby on Rails: coloque sua aplicação web nos trilhos стр 10.

Шрифт
Фон

end

# Bye bye, 3

# Bye bye, 2

# Bye bye, 1

# => nil

O until (até que em inglês) faz justamente o contrário. Ele executa um bloco

associado de código até que a situação se faça verdadeira:

a = [1, 2, 3]

until a.empty? do

puts "Bye bye, #{a.pop}"

end

# Bye bye, 3

# Bye bye, 2

# Bye bye, 1

# => nil

Cuidados com until

O until possui o mesmo problema semântico do unless (seção 2.4),

ou seja, podemos ter problemas ao pensar em dupla negativa. Dessa

forma, recomenda-se usar apenas while, negando a expressão quando

pertinente.

for ... in

O for ...

in é uma maneira de iterar elementos de uma coleção, ou um objeto

iterável, ou seja, um objeto que seja um Enumerator. A estrutura do for é simples:

34

Casa do Código

Capítulo 2. Conhecendo Ruby

for variável in coleção

Vejamos um exemplo com Arrays, que são iteráveis":

fruits = %w{pera uva maçã}

for fruit in fruits

puts "Gosto de " + fruit

end

# Gosto de pera

# Gosto de uva

# Gosto de maçã

# => ["pera", "uva", "maçã"]

Hashes também são iteráveis, com uma pequena diferença:

frequencies = {'hello' => 10, 'world' => 20}

for word, frequency in frequencies

puts "A frequência da palavra '#{word}' é #{frequency}"

end

# A frequência da palavra 'hello' é 10

# A frequência da palavra 'world' é 20

# => {"hello"=>10, "world"=>20}

Blocos

Blocos são estruturas singulares a Ruby, e são extremamente importantes, tanto é

que merecem atenção especial. Blocos são trechos de código associados a um método

que podem ser executados a qualquer momento por este método.

Este conceito é um pouco estranho para quem vem de linguagens como Java

(apesar de que Java possui uma forma de se fazer blocos, com classes anônimas) e C,

mas se você já ouviu falar de lambdas, está familiarizado com o conceito.

O exemplo mais clássico de blocos é o uso de iteradores:

fruits = %w{pera uva maçã}

fruits.each do |fruit|

puts "Gosto de " + fruit

end

# Gosto de pera

# Gosto de uva

35

2.4. Fluxos e laços

Casa do Código

# Gosto de maçã

# => ["pera", "uva", "maçã"]

Explicando o exemplo anterior, o método #each pega cada valor dentro de sua

coleção e repassa para o bloco associado, através da variável fruit.

Outro método que usa bloco bastante útil é o #map, de Hashes e Arrays, que

retorna um novo Array contendo como elementos o resultado devolvido a cada ite-

ração:

numbers = [1, 2, 3, 4]

squared_numbers = numbers.map { |number| number * number }

squared_numbers # [1, 4, 9, 16]

Notação para blocos

Como você pôde perceber, foram usadas duas notações distintas nos

exemplos anteriores, a notação com do ...

end e a notação com cha-

ves. Ambas funcionam da mesma maneira. Porém, a comunidade Ruby

adotou a seguinte regra:

Para blocos curtos, de apenas uma linha, adota-se as chaves;

Para blocos longos, de duas ou mais linhas, adota-se o do ...

end.

A grande utilidade de blocos é que existem inúmeras APIs que exigem operações

antes e depois de serem utilizadas. Com o uso de blocos, este procedimento fica

transparente, como é possível observar no próximo exemplo:

# Exemplo tradicional

file = File.new('file.txt', 'w')

file.puts "Escrevendo no arquivo"

file.close

# Ao invés de termos que nos preocupar com a abertura e o fechamento do

# arquivo, a própria API faz isso antes e depois do bloco.

36

Casa do Código

Capítulo 2. Conhecendo Ruby

File.open('another_file.txt', 'w') do |file|

file.puts "Escrevendo no arquivo com blocos!"

end

É possível também passar e receber mais de um argumento para blocos. O fun-

cionamento é bem o mesmo de argumentos para funções, vejamos o exemplo abaixo

com Hashes:

a = {:a => 1, :b => 2, :c => 3}

a.each do |key, value|

puts "A chave #{key} possui valor #{value}"

end

# A chave a possui valor 1

# A chave b possui valor 2

# A chave

c possui valor 3

Escopo de variáveis

Variáveis declaradas no mesmo escopo em que o bloco se encontra são acessíveis

de dentro deste bloco.

a = %w{a b c d e}

counter = 0

a.each { |val| counter += 1 }

puts "O valor do contador é: #{counter}" # O valor do contador é: 5

Se usarmos um nome de variável para o parâmetro de bloco que é o mesmo que

uma variável externa ao bloco, a variável externa deixará de ser acessível dentro do

bloco, mas terá seu valor mantido:

a = %w{a b c}

i = 5

a.each do |i|

puts i

end # a; b; c

puts i # 5

37

2.4. Fluxos e laços

Casa do Código

Atenção ao escopo!

O comportamento do exemplo anterior é restrito à variáveis em parâ-

metros. Isso significa que variáveis externas ao bloco são modificáveis

dentro deste mesmo bloco, conforme o primeiro exemplo. O resultado

disso pode ser inesperado, já que o bloco pode estar alterando valores de

outras variáveis.

As variáveis declaradas dentro do bloco são criadas a cada vez que o bloco é

chamado, ou seja, essas variáveis não existirão caso o bloco seja chamado novamente

e serão criadas novamente:

a = %w{w o r d}

a.each do |letter|

word ||= ""

word << letter

puts word

end

# w

# o

# r

# d

Existem situações em que nós não ligamos para um dos valores passados para

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке