Ruby Print Inject Do Syntax

随声附和 提交于 2019-11-27 12:47:31

问题


Why is it that the following code runs fine

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

But, the following code gives an error

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)

Should they not be equivalent?


回答1:


The block written using the curly braces binds to the inject method, which is what your intention is, and it will work fine.

However, the block that is encapsulated in the do/end block, will bind to the p-method. Because of this, the inject call does not have an associated block. In this case, inject will interpret the argument, in this case 0, as a method name to call on every object. Bacuase 0 is not a symbol that can be converted into a method call, this will yield a warning.




回答2:


The problem is with the p at the beginning. If you omit these you'll see that both work fine:

# 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
}

But this won't work:

# 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



回答3:


This looks like a effect of the difference in binding between do/end and brackets:

brackets, used as you are above, will bind to the last function chained while do/end will bind to the first.

I think thats sort of a odd way to say it, but basically the first instance is passing the block to the function 'inject', while the second is actually trying to pass the block to the first method 'p'.



来源:https://stackoverflow.com/questions/2127836/ruby-print-inject-do-syntax

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!