自定义Ruby inject方法传参时self为何变为空数组?
问题原因及修复方案
问题根源
你遇到的问题核心在于直接修改了原数组对象:
- Ruby的数组是可变对象,
shift方法会直接从原数组中移除并返回第一个元素,而非操作副本。 - 第一次调用
my_inject(不传参数)时,self.shift()取出了原数组的第一个元素,后续循环里的self.shift持续移除元素,调用结束后原数组my_array已经变成空数组。 - 第二次调用
my_inject(100)时,self指向的就是这个已经被掏空的空数组,所以until self.empty?的条件一开始就满足,循环从未执行,直接返回传入的初始值100。
修复方案
不要直接操作原数组,先复制一份数组副本进行操作,避免修改原对象。修改后的代码如下:
def my_inject(arg=nil, &block) puts self arr = self.dup # 创建原数组的副本,后续操作副本而非原数组 arg.nil? ? memo = arr.shift() : memo = arg until arr.empty? memo = block.call(memo, arr.shift) end memo end
测试验证:
my_array = [3, 5, 8, 9] # 不传参数时返回25,原数组保持不变 p my_array.my_inject { |m, v| m + v} # 传参数时返回125,原数组仍为[3,5,8,9] p my_array.my_inject(100) { |m, v| m + v }
内容的提问来源于stack exchange,提问作者Kasper
相关产品推荐
相关产品推荐

