Подтвердить что ты не робот

Разница между блоком и блоком в Ruby

Почему иногда я должен использовать блок и другое время и блок внутри функций, которые принимают блоки?

4b9b3361

Ответ 1

block является только локальной переменной, &block является ссылкой на блок, переданный методу.

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:[email protected]:20>

Вы также можете использовать &block при вызове методов для передачи proc как блока метода, чтобы вы могли использовать procs так же, как вы используете блоки.

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)

Имя переменной block не означает ничего особенного. Вы можете использовать &strawberries, если хотите, амперсанд - это ключ.

Вы можете найти эту статью.

Ответ 2

В списке аргументов &whatever принимает блок, который был передан методу, и завершает его в объекте Proc. Proc хранится в переменной с именем whatever (где это может быть любое имя, которое вы вводили после амперсанда, конечно - обычно это "блок" ). После вызова метода синтаксис &whatever превращает Proc в блок. Поэтому, если вы определите такой метод:

def thing(&block)
  thing2 &block
end

Вы определяете метод, который принимает блок, а затем вызывает другой метод с этим блоком.

Ответ 3

Если вы не установите блок before и раньше, Ruby не узнает его отношение к "блоку", который вы передаете функции. Вот несколько примеров.

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

Для последующего использования в функции:

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

Итак, если вы вызываете z(&block) его (почти!!) так же, как и вызов z { yield }: вы просто передаете блок следующей функции.