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

Ruby Print Inject Do Syntax

Почему этот код работает нормально

p (1..1000).inject(0) { |sum, i|
    sum + i
}

Но, следующий код дает ошибку

p (1..1000).inject(0) do |sum, i|
    sum + i
end

warning: do not use Fixnums as Symbols
in `inject': 0 is not a symbol (ArgumentError)

Если они не эквивалентны?

4b9b3361

Ответ 1

Блок, написанный с использованием фигурных скобок, привязывается к методу инъекции, что и является вашим намерением, и оно будет работать нормально.

Однако блок, который заключен в блок do/end, будет привязан к p-методу. Из-за этого вызов инъекции не имеет связанного блока. В этом случае инъекция будет интерпретировать аргумент, в данном случае 0, как имя метода для вызова каждого объекта. Bacuase 0 не является символом, который может быть преобразован в вызов метода, это даст предупреждение.

Ответ 2

Это выглядит как эффект разницы в привязке между do/end и brackets:

Скобки

используемые по мере того, как вы находитесь выше, свяжутся с последней функциональной цепочкой, а end/end будет привязываться к первой.

Я думаю, что это какой-то странный способ сказать это, но в основном первый экземпляр передает блок функции "впрыскивать", а второй на самом деле пытается передать блок первому методу "p".

Ответ 3

Проблема с p в начале. Если вы опустите их, вы увидите, что оба работают нормально:

# Works!
[5, 6, 7].inject(0) do |sum, i| # Correctly binds to `inject`.
  sum + i
end

# Works too!
[5, 6, 7].inject(0) { |sum, i|  # Correctly binds to `inject`.
  sum + i
}

Но это не сработает:

# Kablammo! "p" came first, so it gets first dibs on your do..end block.
# Now inject has no block to bind to!
p [5, 6, 7].inject(0) do |sum, i|   # Binds to `p` -- not what you wanted.
  sum + i
end