nop*_*ole 9 ruby methods syntax function
以下问题与" Ruby Print Inject Do Syntax " 问题有关.我的问题是,我们能坚持使用do
和end
,使其与工作puts
或p
?
这有效:
a = [1,2,3,4]
b = a.inject do |sum, x|
sum + x
end
puts b # prints out 10
Run Code Online (Sandbox Code Playgroud)
所以,它是正确的,inject
是Array对象的实例方法,并且此实例方法接受一段代码,然后返回一个数字.如果是这样,那么它应该与调用函数或方法并获取返回值没有什么不同:
b = foo(3)
puts b
Run Code Online (Sandbox Code Playgroud)
要么
b = circle.getRadius()
puts b
Run Code Online (Sandbox Code Playgroud)
在以上两种情况下,我们可以直接说
puts foo(3)
puts circle.getRadius()
Run Code Online (Sandbox Code Playgroud)
因此,使用以下两种方式无法直接使其工作:
a = [1,2,3,4]
puts a.inject do |sum, x|
sum + x
end
Run Code Online (Sandbox Code Playgroud)
但它给了
ch01q2.rb:7:in `inject': no block given (LocalJumpError)
from ch01q2.rb:4:in `each'
from ch01q2.rb:4:in `inject'
from ch01q2.rb:4
Run Code Online (Sandbox Code Playgroud)
使用方法调用分组( )
也不起作用:
a = [1,2,3,4]
puts (a.inject do |sum, x|
sum + x
end)
Run Code Online (Sandbox Code Playgroud)
这给了:
ch01q3.rb:4: syntax error, unexpected kDO_BLOCK, expecting ')'
puts (a.inject do |sum, x|
^
ch01q3.rb:4: syntax error, unexpected '|', expecting '='
puts (a.inject do |sum, x|
^
ch01q3.rb:6: syntax error, unexpected kEND, expecting $end
end)
^
Run Code Online (Sandbox Code Playgroud)
最后,以下版本有效:
a = [1,2,3,4]
puts a.inject { |sum, x|
sum + x
}
Run Code Online (Sandbox Code Playgroud)
但为什么( )
在前面的例子中没有使用work 的方法调用分组?如果程序员坚持使用do
并且end
可以使其工作,该怎么办?
out*_*tis 15
从(非官方的)ruby语法中,我们看到(...)
in 的内容puts (...)
必须是CALL_ARGS
,而不是直接减少到STMT
.但是,他们可以减少到'(' COMPSTMT ')'
.通过包含一组额外的括号,您可以使用do ... end
.
a = [1,2,3,4]
puts ((a.inject do |sum, x|
sum + x
end))
Run Code Online (Sandbox Code Playgroud)
这里的问题不只是你的括号:这是主要的空间后 puts
前括号.
随着代码
a = [1,2,3,4]
puts (a.inject do |sum, x|
sum + x
end)
Run Code Online (Sandbox Code Playgroud)
我们得到您在问题中列出的语法错误.
如果你放下空间后puts
,
a = [1,2,3,4]
puts(a.inject do |sum, x|
sum + x
end)
Run Code Online (Sandbox Code Playgroud)
10
按预期打印出来.
最后,使用puts ((a.inject...
空格和双括号也打印出来10
,但运行通过ruby -cw XXX.rb
告诉我们:
a.rb:5: warning: (...) interpreted as grouped expression
Syntax OK
ruby -cw
用于ç赫克与全语法W¯¯ arnings开启.当-cw
打开时,您将被警告可疑的括号和分组.我更习惯看到的错误是"不要在参数括号之前放置空格" - 所以不要这样做!
最后,a.inject do
没有括号但失败的原因a.inject {
是,大括号的优先级高于do
/ end
.作为一个非常粗略的准则,你可以说这p a.map { foo }
相当于p(a.map do foo end)
; 并且p a.map do foo end
相当于(p a.map) do foo end
,当然不会采用块参数.
块,闭包和过程
块/瓶盖
- 块必须遵循方法调用:
invocation do ... end
invocation { ... }
- 块记住它们的变量上下文,并且是完全闭包.
- 块通过yield调用,可以传递参数.
- Brace表单具有更高的优先级,并且如果调用没有pare,则将绑定到最后一个参数.
- do/end表单具有较低的优先级,即使没有parens也会绑定到调用.