Существует небольшая разница между двумя синтаксисами.{ }
имеет более высокий приоритет, чем do ... end
.Таким образом, следующее передаст bar
и блок методу foo
:
foo bar do ... end
, в то время как следующее передаст блок к bar
, а результат этого к foo
:
foo bar { ... }
Так что ваши примеры будут действовать так же.Однако, если вы оставили скобки:
> 3.upto 9 {
puts "Hi"
}
SyntaxError: compile error
(irb):82: syntax error, unexpected '{', expecting $end
3.upto 9 {
^
from (irb):82
from :0
> 3.upto 9 do
puts "Hi"
end
Hi
Hi
Hi
Hi
Hi
Hi
Hi
=> 3
Итак, { }
с большей вероятностью вас настигнет, если вы оставите скобки в Ruby, что довольно часто;по этой причине и поскольку все условные выражения Ruby и другие управляющие конструкции используют end
в качестве разделителя, люди обычно используют do ... end
для многострочных блоков кода, которые идут в конце оператора.
Однако,{ }
часто используется в тех местах, где do ... end
будет громоздким, например, если вы объединяете несколько методов, которые принимают блоки.Это может позволить вам записывать короткие однострочные маленькие блоки, которые можно использовать как часть цепочки методов.
> [1,2,3].sort{|x,y| y<=>x}.map{|x| x+1}
=> [4, 3, 2]
Вот пример, иллюстрирующий эту разницу:
def foo arg
if block_given?
puts "Block given to foo"
yield arg
else
puts "No block given to foo"
arg
end
end
def bar
if block_given?
puts "Block given to bar"
yield "Yielded from bar"
else
puts "No block given to bar"
end
"Returned from bar"
end
irb(main):077:0> foo bar { |arg| puts arg }
Block given to bar
Yielded from bar
No block given to foo
=> "Returned from bar"
irb(main):078:0> foo bar do |arg| puts arg end
No block given to bar
Block given to foo
Returned from bar
=> nil