Определение блока - разница между фигурными скобками и do-end? - PullRequest
9 голосов
/ 30 мая 2011

Кто-нибудь может объяснить, почему следующий код прерывается с ошибкой

irb(main):186:0> print ((1..10).collect do |x| x**2 end)
SyntaxError: (irb):186: syntax error, unexpected keyword_do_block,
expecting ')'
print ((1..10).collect do |x| x**2 end)
                         ^
(irb):186: syntax error, unexpected keyword_end, expecting $end
print ((1..10).collect do |x| x**2 end)
                                      ^
        from /usr/bin/irb:12:in `<main>'

тогда как следующий код с той же функциональностью работает как ожидалось?

irb(main):187:0> print ((1..10).collect { |x| x**2 })
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]=> nil

Я верил, что фигурные скобки "{}" могут произвольно заменить "конец" в блоке определение.

Я знаю, что могу "исправить" первый вызов, пропустив пробел между печатью. метод и первая скобка, но я заинтересован в объяснении почему ведет себя иначе.

Ответы [ 2 ]

13 голосов
/ 30 мая 2011

Разница в приоритете:

# Equivalent to puts( (1..10).map { |i| i*2 } )
> puts (1..10).map { |i| i*2 }
2
4
6
8
10
12
14
16
18
20
 => nil 

# Equivalent to puts( (1..10).map ) { |i| i*2 }
> puts (1..10).map do |i| i*2 end
#<Enumerator:0x928f24>
 => nil 

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

Что касается синтаксической ошибки, если убрать пробел между print и (, все работает;)

Разница заключается в том, обрабатывает ли ruby ​​ваши круглые скобки как разделители аргументов метода, или это общая группировка операторов.Я не уверен в точной разнице, но она тонкая и раздражающая

0 голосов
/ 10 июня 2011

На SO уже есть окончательный ответ .

К сожалению, это определенно не хорошая демонстрация философии наименее удивительного в Ruby.

...