在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
我遇到的问题是,如果我在给定方法上使用()
,{}
或两者,我会感到困惑。在什么基础上决定?
{}
或参数()
,是否有任何其他逻辑推理依据它来决定? 请帮助我理解
答案 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#select
或Array#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