在Ruby中使用圆括号和块时会感到困惑

时间:2012-03-16 10:20:36

标签: ruby

在Surface, Ruby似乎与Java,Php,C等其他对象语言非常相似。

但是,当我们开始遇到障碍时,事情变得有点奇怪。

例如,这可行

(0...8).max()
 => 7 

但这不是

(0...8).map(puts "hello world")
hello world
ArgumentError: wrong number of arguments(1 for 0)

显然,map方法不接受参数但接受块,因此将()替换为{}会修复错误。

(0...8).map{puts "hello world"}
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
 => [nil, nil, nil, nil, nil, nil, nil, nil] 

然后,有一些方法应该采取 - 块和&参数

8.downto(1){puts "hello world"}
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
 => 8 

我遇到的问题是,如果我在给定方法上使用(){}或两者,我会感到困惑。在什么基础上决定?

  • 是否按每种方法固定?我只记得方法采用的方法(块或参数)?
  • 或者,如果方法采用块{}或参数(),是否有任何其他逻辑推理依据它来决定?

请帮助我理解

3 个答案:

答案 0 :(得分:6)

方法调用后的括号实际上是可选的。

(0...8).map{puts "hello world"}相当于(0...8).map() {puts "hello world"}

所以你并没有真正取代它们。

块的接受完全取决于方法,它们可以在方法声明中指定:

def method(param, &block)
  block.call
end

允许在方法中将块作为变量进行访问,例如通过block.call调用。

通过使用yield关键字

,也可以隐含使用它们
def method(param)
  yield
end

因此,您必须参考API文档以确定接受的内容。

答案 1 :(得分:2)

应该在方法的API中记录。

如果存在接受参数的方法,则该块通常是可选的 - 在这种情况下,它用于“细化”方法的工作方式 - 例如Hash.new,可以接受一个参数(默认哈希值)和一个块,用于在键值初始化期间执行智能操作。但是大多数需要阻塞的方法都不接受参数,例如: Array#selectArray#map

答案 2 :(得分:2)

使用括号将参数传递给函数。这始终是以逗号分隔的对象列表。它们可能是函数的结果,但不是必须的。它们所产生的功能将始终只被调用一次。

示例:

x = Array.new
=> []
x.push(2)
=> [2]
x.push(7.modulo(4))
=> [2,3]

使用块将功能行为传递给方法。这些函数通常用于调用许多不同的参数或一定次数。 puts "hello world"是一个打印内容的函数,但只返回nil。因此,您几乎不会尝试将其用作函数的参数(因为您将nil传递给该函数),但通常将其作为块传递给函数,以便可以多次调用它。

大多数情况下,你想要传递一个块,你传递给一个函数,使用参数,这样它实际上每次调用都会有不同的东西。

示例:

(0..8).each{ |number| 
  if number.odd?
    puts "#{number} is odd"
  end
}
=> 1 is odd
=> 3 is odd
=> 5 is odd
=> 7 is odd
=> => 0..8