Погружаясь глубже, я думаю, вы бы выиграли от более глубокого понимания "блоков" в Ruby (которые отличаются от общих терминов программирования "блок кода" или "блок кода").
Притворятьсяна мгновение, когда на самом деле работал следующий (недопустимый) код Ruby:
def add10( n )
puts "#{n} + 10 = #{n+10}"
end
def do_something_with_digits( method )
1.upto(9) do |i|
method(i)
end
end
do_something_with_digits( add10 )
#=> "1 + 10 = 11"
#=> "2 + 10 = 12"
...
#=> "9 + 10 = 19"
Хотя этот код недопустим, его намерение - передать некоторый код методу и запустить этот метод - в Ruby возможноразными способами.Один из таких способов - «Блоки».
Блок в Ruby очень и очень похож на метод: он может принимать некоторые аргументы и запускать код для них.Всякий раз, когда вы видите foo{ |x,y,z| ... }
или foo do |x,y,z| ... end
, это блоки, которые принимают три параметра и запускают на них ...
. (Вы можете даже увидеть, что вышеприведенному методу upto
передается блок.)
Поскольку блоки являются особой частью синтаксиса Ruby, каждому методу разрешено передаватьблок.Независимо от того, использует ли метод , блок зависит от метода.Например:
def say_hi( name )
puts "Hi, #{name}!"
end
say_hi("Mom") do
puts "YOU SUCK!"
end
#=> Hi, Mom!
Приведенному выше методу передается блок, который готов выдать оскорбление, но, поскольку метод никогда не вызывает блок, печатается только симпатичное сообщение.Вот как мы вызываем блок из метода:
def say_hi( name )
puts "Hi, #{name}!"
if block_given?
yield( name )
end
end
say_hi("Mridang") do |str|
puts "Your name has #{str.length} letters."
end
#=> Hi, Mridang!
#=> Your name has 7 letters.
Мы используем block_given?
, чтобы увидеть, был ли передан блок или нет.В этом случае мы передали аргумент обратно в блок;Ваш метод решает, что передать блоку.Например:
def say_hi( name )
puts "Hi, #{name}!"
yield( name, name.reverse ) if block_given?
end
say_hi("Mridang"){ |str1, str2| puts "Is your name #{str1} or #{str2}?" }
#=> Hi, Mridang!
#=> Is your name Mridang or gnadirM?
Это просто соглашение (и хорошее, и то, которое вы хотите поддерживать) для некоторых классов для передачи только что созданного экземпляра в блок.
Надеюсь, этопоможет вам лучше понять ответ @ SimoneCarletti и поможет вам использовать блоки в будущем программировании.