我很难理解为什么我不能用圆括号调用select。
a = [1,2,3]
a.select {|v| v.is_a?(Integer)} # works
a.select({|v| v.is_a?(Integer)}) # syntax error, unexpected '|', expecting '}
据我所知,select是一种常规方法。
Array.method_defined? :select # true
Array.method_defined? :is_a? # true
我认为圆形括号对于ruby中的方法是可选的 在下面的情况下,圆括号没有区别。
a.reverse() == a.reverse #true
我使用ruby 2.2.1。
有什么想法吗?
答案 0 :(得分:4)
你不能通过这样的synatx传递一个块,你必须做这样的事情:
a.select(&lambda { |v| v.is_a?(Integer) })
但通常你会这样做
a.select { |v| v.is_a?(Integer) }
与
相同a.select() { |v| v.is_a?(Integer) }
,即该块在方法参数之外。
你也可以使用'stabby'lambda语法:
is_a_integer = ->(v) { v.is_a?(Integer) }
a.select(&is_a_integer)
因此,如果您想要将块作为参数传递,则需要使用&
作为前缀,但由于无神论的原因,通常您会在参数之外使用该块。
还要注意这些与方法签名之间的区别以及它们的调用方式:
def call(&block)
yield
end
call { 1 } # => 1
call(lambda { 1 }) # => ArgumentError
call(&lambda { 1 }) # => 1
和
def call(block)
block.call
end
call { 1 } # => ArgumentError
call(lambda { 1 }) # => 1
call(&lambda { 1 }) # => ArgumentError
这是因为lambda(和Procs)是对象,因此我们可以#call
来评估它们,但是块不是并且可以使用yield
关键字来评估。 this blog post中有更多信息。
lambda { 1 }.class # => Proc
答案 1 :(得分:2)
圆括号是一种将参数传递给方法的方法,而波浪形括号(或do / end)是将块传递给方法的一种方法。它们不可互换。
Squiggly括号也可用于在ruby中创建哈希,这可能会引起一些混淆。
一些ruby方法可以使用参数和块,在这种情况下,您可以在波浪形括号之前使用圆括号:E.G。
open("ChangeLog") { |f|
f.slice_before(/\A\S/).each { |e| pp e }
}
答案 2 :(得分:1)
有或没有括号,Array#select
不接受任何常规参数。然而,它接受一个块参数,但是与方法调用相关联的块总是放在括号之后,而不是在它们内部。
因此,电话:
a.select {|v| v.is_a? Integer }
也可以用括号写成:
a.select() {|v| v.is_a? Integer }