Ruby 使用圆括号的方法调用抛出语法错误
Ruby method call using round brackets throwing syntax error
我无法理解为什么我不能用圆括号调用 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.
有什么想法吗?
圆括号是一种将参数传递给方法的方式,而波浪括号(或 do/end)是一种将块传递给方法的方式。它们不可互换。
波浪括号也可用于在 ruby 中创建哈希,这可能会造成一些混淆。
一些 ruby 方法可以接受参数和一个块,在这种情况下,您可以在波浪形括号之前使用圆括号:E.G.
open("ChangeLog") { |f|
f.slice_before(/\A\S/).each { |e| pp e }
}
你不能通过这样的 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
带或不带括号,Array#select
不接受任何常规参数。然而,它接受块参数,但与方法调用关联的块始终放在括号之后,而不是括号内。
因此,调用:
a.select {|v| v.is_a? Integer }
也可以写成带括号的:
a.select() {|v| v.is_a? Integer }
我无法理解为什么我不能用圆括号调用 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.
有什么想法吗?
圆括号是一种将参数传递给方法的方式,而波浪括号(或 do/end)是一种将块传递给方法的方式。它们不可互换。
波浪括号也可用于在 ruby 中创建哈希,这可能会造成一些混淆。
一些 ruby 方法可以接受参数和一个块,在这种情况下,您可以在波浪形括号之前使用圆括号:E.G.
open("ChangeLog") { |f|
f.slice_before(/\A\S/).each { |e| pp e }
}
你不能通过这样的 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
带或不带括号,Array#select
不接受任何常规参数。然而,它接受块参数,但与方法调用关联的块始终放在括号之后,而不是括号内。
因此,调用:
a.select {|v| v.is_a? Integer }
也可以写成带括号的:
a.select() {|v| v.is_a? Integer }