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)
Если они не эквивалентны?
Ответы
Ответ 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