Que signifient-ils? Pourquoi, parfois, je dois utiliser le bloc et en d'autres temps et bloquer à l'intérieur des fonctions qui acceptent les blocs?
Réponses
Trop de publicités?block
est juste une variable locale, &block
est une référence pour le bloc transmis à la méthode.
def foo(block = nil)
p block
end
foo # => nil
foo("test") # => test
foo { puts "this block will not be called" } # => nil
def foo(&block)
p block
end
foo # => nil
foo("test") # => ArgumentError: wrong number of arguments (1 for 0)
foo { puts "This block won't get called, but you'll se it referenced as a proc." }
# => #<Proc:0x0000000100124ea8@untitled:20>
Vous pouvez également utiliser &block
lors de l'appel de méthodes pour passer un proc comme un bloc, d'une méthode, de sorte que vous pouvez utiliser procs, tout comme vous utilisez des blocs.
my_proc = proc {|i| i.upcase }
p ["foo", "bar", "baz"].map(&my_proc)
# => ["FOO", "BAR", "BAZ"]
p ["foo", "bar", "baz"].map(my_proc)
# => ArgumentError: wrong number of arguments (1 for 0)
Le nom de la variable block
ne veut rien dire de spécial. Vous pouvez utiliser &strawberries
si vous le souhaitez, l'esperluette est la clé ici.
Vous pouvez trouver cet article utile.
Dans une liste d'arguments, &whatever
prend le bloc qui a été transmis à la méthode et l'enveloppe dans un Proc objet. Le Proc est stocké dans une variable nommée whatever
(où qui peut être quel que soit le nom que vous avez tapé après l'esperluette, bien sûr - en général c'est "bloc"). Après un appel de méthode, &whatever
de la syntaxe tourne un Proc dans un bloc. Donc, si vous définissez une méthode comme suit:
def thing(&block)
thing2 &block
end
Vous êtes à la définition d'une méthode qui prend un bloc, puis appelle une autre méthode avec ce bloc.
Si vous ne définissez pas l' & avant le bloc, Ruby ne reconnaît pas, c'est la relation avec le "bloc", vous passer à la fonction. Ici quelques exemples.
def f(x, block); end
f(3) { 2+2 } # gives an error, because "block" is a
# regular second argument (which is missing)
def g(x, &block); end
g(3) { 2+2 } # legal
def h(x); end
h(3) { 2+2 } # legal
Pour les utiliser plus tard dans une fonction:
def x(&block) # x is a 0 param function
y(block) # y is a 1 param function (taking one "Proc")
z(&block) # z is a 0 param function (like x) with the block x received
end
Donc, si vous vous appelez z(&block)
il est (presque!!) de même que l'appel à la z { yield }
: Vous venez de passer le bloc à la fonction suivante.