terça-feira, 3 de dezembro de 2013

Ruby 3

Blocos e iteradores em Ruby


As duas sintaxes para criar um bloco de código:
{ puts "Alô, Mundo!" } # note as chaves
# ou:
do
  puts "Alô, Mundo!"
end
Um bloco de código pode ser passado a um método com um argumento opcional do bloco. Várias métodos internos possuem tais argumentos:
File.open('file.txt', 'w') do |file|       # 'w' denota "modo de escrita"
  file.puts 'Wrote some text.'
end                                  # o arquivo é automaticamente fechado aqui
 
File.readlines('file.txt').each do |line|
  puts line
end
# => Escreveu algum texto.
Passagem de um parâmetro de um bloco com fechamento:
(também fechamento lexical ou fechamento de função) é uma função ou referência a uma função, juntamente com um ambiente de referência. Um fechamento, ao contrário de uma função simples ponteiro permite que uma função possa acessar essas variáveis ​​não-locais, mesmo quando chamado fora de seu escopo lexical imediato.
# In an object instance variable (denoted with '@'), remember a block.
def remember(&a_block)
  @block = a_block
end
 
# Invoke the preceding method, giving it a block which takes a name.
remember {|name| puts "Hello, #{name}!"}
 
# Call the closure:
@block.call("Jon")   # => "Hello, Jon!"
Criado uma função anônima:
proc {|arg| puts arg}
Proc.new {|arg| puts arg}
lambda {|arg| puts arg}
->(arg) {puts arg}         # introduced in Ruby 1.9
Retornando o fechamento de um método:
def create_set_and_get(initial_value=0) # note the default value of 0
  closure_value = initial_value
  return Proc.new {|x| closure_value = x}, Proc.new { closure_value }
end
 
setter, getter = create_set_and_get  # returns two values
setter.call(21)
getter.call      # => 21
 
# Parameter variables can also be used as a binding for the closure,
# so the preceding can be rewritten as:
 
def create_set_and_get(closure_value=0)
  return proc {|x| closure_value = x } , proc { closure_value }
end
Cedendo o fluxo de controle do programa para um bloco que foi fornecido no momento da chamada:
def use_hello
  yield "hello"
end
 
# Invoke the preceding method, passing it a block.
use_hello {|string| puts string}  # => 'hello'
Iterações sobre enumerações e arrays utilizando blocos:
array = [1, 'hi', 3.14]
array.each {|item| puts item }
# prints:
# 1
# 'hi'
# 3.14
 
array.each_index {|index| puts "#{index}: #{array[index]}" }
# prints:
# 0: 1
# 1: 'hi'
# 2: 3.14
 
# The following uses a Range
(3..6).each {|num| puts num }
# prints:
# 3
# 4
# 5
# 6
Um método como inject pode aceitar ambos, um parâmetro e um bloco. Ele faz iteração sobre cada membro da list, executa algumas funções nele enquanto mantem um agregado.
[1,3,5].inject(10) {|sum, element| sum + element}   # => 19
Na primeira passagem, o bloco recebe 10 (o argumento para inject) como soma, e um (o primeiro elemento da array) como element. Isso retorna 11, que torna-se então soma na próxima passagem. Ele é adicionado a 3 para obter 14, que é então adicionada a 5 no terceiro passo, para finalmente voltar 19.
Usando uma enumeração e um bloco ao quadrado os números de 1 a 10 (com um intervalo):
(1..10).collect {|x| x*x}  # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Ou invoca um método a cada item (map é um sinônimo para collect):

(1..5).map(&:to_f)  # => [1.0, 2.0, 3.0, 4.0, 5.0]





Função anônima (também função constante, função literal ou função lambda) é uma função (ou uma sub-rotina) definida, e possivelmente chamada, sem estar vinculado a um identificador. 

Funções anônimas são convenientes para passar como um argumento para uma função de ordem superior e são onipresentes em línguas com funções de primeira classe. 
É uma forma de função aninhada, na medida em que permitem o acesso a variáveis ​​no escopo da função que contém (variáveis ​​não- locais). Ao contrário das funções aninhadas nomeadas, elas não podem ser recursiva sem a assistência de um operador fixpoint ( também conhecido como um fixpoint anônimo ou recursão anônimo) .

Nenhum comentário:

Postar um comentário