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

Ruby do/end vs braces

Почему это выражение карты дает разные результаты в зависимости от того, использую ли я фигурные скобки или 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]
4b9b3361

Ответ 1

Это потому, что вторая строка интерпретируется как:

p(a.map) do ... end

вместо:

p(a.map do ... end)

В этом случае грамматика неоднозначна и do, похоже, не привязана так сильно, как {.

Ответ 2

Это связано с различием в ассоциативности символа { и ключевого слова do.

В первом случае блок интерпретируется как блок-аргумент функции map. Результатом функции map является аргумент функции p.

Во втором случае блок интерпретируется как блок-аргумент функции p, а a.map интерпретируется как первый аргумент функции p. Поскольку a.map оценивается как a, это печатает исходный массив. В этом случае блок эффективно игнорируется.

Ответ 3

С синтаксисом do/end вы передаете блок в p как второй аргумент, а не на карту. Вы получаете тот же результат:

p a.map

Блок игнорируется p, поскольку он не производит ничего на inspect.