Ответ 1
Это потому, что вторая строка интерпретируется как:
p(a.map) do ... end
вместо:
p(a.map do ... end)
В этом случае грамматика неоднозначна и do
, похоже, не привязана так сильно, как {
.
Почему это выражение карты дает разные результаты в зависимости от того, использую ли я фигурные скобки или do/end?
a = [1,2,3,4,5]
p a.map { |n|
n*2
}
#=> [2,4,6,8,10]
p a.map do |n|
n*2
end
#=> [1,2,3,4,5]
Это потому, что вторая строка интерпретируется как:
p(a.map) do ... end
вместо:
p(a.map do ... end)
В этом случае грамматика неоднозначна и do
, похоже, не привязана так сильно, как {
.
Это связано с различием в ассоциативности символа {
и ключевого слова do
.
В первом случае блок интерпретируется как блок-аргумент функции map
. Результатом функции map является аргумент функции p
.
Во втором случае блок интерпретируется как блок-аргумент функции p
, а a.map
интерпретируется как первый аргумент функции p
. Поскольку a.map
оценивается как a
, это печатает исходный массив. В этом случае блок эффективно игнорируется.
С синтаксисом do/end
вы передаете блок в p
как второй аргумент, а не на карту. Вы получаете тот же результат:
p a.map
Блок игнорируется p
, поскольку он не производит ничего на inspect
.