Ruby 中的代码块有两种形式
{}
or
do
...
end
我相信你也相信他们可以随意使用,对么? 我一直都是这么认为的,直到有一天我写了如下的代码:
clear_cache users.each_with_object([]) do |user, array|
disassociate_user user.id
array << user.cache_key
end
def clear_cache
Array(cache_keys).each { |key| Rails.cache.delete key }
end
这段代码始终和我的预期有很大的差距,我期望的是
users.each_with_object([]) do |user, array|
disassociate_user user.id
array << user.cache_key
end
这段代码能返回一个数组作为clear_cache
的参数,但结果并不是这样。为什么呢?
这就涉及到了 Ruby 中代码块的优先级了,如果上面的代码我换个写法
clear_cache users.each_with_object([]) { |user, array|
disassociate_user user.id
array << user.cache_key }
你猜如何,这就是我要的结果。这说明了{}
这个形式的代码块有更高的优先级,它和调用的方法会被优先执行。
下面再给出一些借来的例子:
1.upto 3 do |x|
puts x
end
1.upto 3 { |x| puts x }
# SyntaxError: compile error
对于上例的第二种情况,因为 block 会被优先处理,那么这个例子就类似于method x y
这样的方法调用,这必然是没有被 Ruby 允许的。
method1 method2 do
puts "hi"
end
method1 method2 {
puts "hi"
}
对于这个例子,第一种情况的执行逻辑是method1
接受一个叫做method2
的参数,且调用一个 block;第二种情况就是method1
接受method2
调用 block 返回的结果作为参数。