Ruby Language Céder aux blocs


Exemple

Vous pouvez envoyer un bloc à votre méthode et il peut appeler ce bloc plusieurs fois. Cela peut être fait en envoyant un proc / lambda ou autre, mais c'est plus facile et plus rapide avec le yield :

def simple(arg1,arg2)
  puts "First we are here:  #{arg1}"
  yield
  puts "Finally we are here:  #{arg2}"
  yield
end
simple('start','end') { puts "Now we are inside the yield" }

#> First we are here:  start
#> Now we are inside the yield
#> Finally we are here:  end
#> Now we are inside the yield

Notez que le { puts ... } n'est pas entre parenthèses, il vient implicitement après. Cela signifie également que nous ne pouvons avoir qu'un seul bloc de yield . Nous pouvons transmettre des arguments au yield :

def simple(arg)
  puts "Before yield"
  yield(arg)
  puts "After yield"
end
simple('Dave') { |name| puts "My name is #{name}" }

#> Before yield
#> My name is Dave
#> After yield

Avec le rendement, nous pouvons facilement créer des itérateurs ou des fonctions fonctionnant sur d'autres codes:

def countdown(num)
  num.times do |i|
    yield(num-i)
  end
end

countdown(5) { |i| puts "Call number #{i}" }

#> Call number 5
#> Call number 4
#> Call number 3
#> Call number 2
#> Call number 1

En fait, c'est avec le yield que des choses comme foreach , each et les times sont généralement implémentées dans les classes.

Si vous voulez savoir si un bloc vous a été donné ou non, utilisez block_given? :

class Employees
  def names
    ret = []
    @employees.each do |emp|
      if block_given?
        yield(emp.name)
      else
        ret.push(emp.name) 
      end
    end

    ret
  end
end

Cet exemple suppose que la classe Employees possède une liste @employees pouvant être itérée avec each pour obtenir des objets ayant des noms d'employés à l'aide de la méthode name . Si on nous donne un bloc, alors nous yield le nom au bloc, sinon nous le pousserons simplement dans un tableau que nous renverrons.