Ruby中传递参数与传递块的区别及两段代码是否等效的疑问
Ruby中参数传递与块传递的区别及代码分析
核心区别
- 参数传递:直接把数组、哈希这类对象作为实参传给方法,方法通过形参接收。调用时参数用括号包裹(Ruby中括号可省略,但逻辑上属于参数传递)。
- 块传递:传递的是一段可执行的代码片段(用
do...end或{}包裹),方法需要通过yield、block.call或block_given?等方式主动执行这段代码才能拿到结果。块本身不是普通对象,除非用&转换为Proc。
你的两段代码分析
先看第一段代码:
some_method do [val1, val2, val3] end
这里是给some_method传了一个块,块内部的逻辑是返回包含val1、val2、val3的数组。some_method必须主动执行这个块(比如yield),才能拿到数组,再用其中元素创建哈希。
第二段代码:
some_method([val1, val2, val3])
这是直接把数组[val1, val2, val3]作为参数传给方法,方法通过形参就能直接拿到这个数组。
二者是否等价?
答案是不一定,完全取决于some_method的内部实现:
- 如果
some_method同时支持参数和块,比如内部逻辑是“有参数就用参数,没参数就执行块拿结果”,那两段代码运行效果可能一致。比如这个实现:
def some_method(arr = nil) # 优先用参数,没有参数就执行块 arr ||= yield # 用数组元素作为键创建哈希 arr.each_with_object({}) { |key, hash| hash[key] = nil } end
这种情况下,两段代码调用后得到的哈希是一样的,但语法本质完全不同。
- 如果
some_method只处理块(比如必须通过yield获取值),那第二段代码会报错,因为方法没定义接收参数的形参;反过来,如果方法只处理参数,第一段代码的块会被直接忽略(除非方法里特意检查了block_given?)。
内容的提问来源于stack exchange,提问作者Colin Wu
相关产品推荐
相关产品推荐

