为什么Ruby代码运行报错undefined method `[]=' for 3:Integer (NoMethodError)
报错原因
Ruby中reduce(也叫inject)方法要求每次迭代的块的返回值,会作为下一次迭代时的第一个聚合参数传入。你当前代码的块内最后一行是result[animal] = animal.length,赋值表达式的返回值是等号右侧的整数(也就是单词长度),第一次迭代结束后,下一次迭代的result就从最初的哈希变成了整数类型,后续尝试调用[]=方法给整数赋值时就触发了报错:
block in find_word_lengths': undefined method `[]=' for 3:Integer (NoMethodError)
修复方案
有两种常用修复方式:
方式1:修改reduce块,手动返回聚合对象
每次迭代结束显式返回哈希对象result,确保下一次迭代拿到的聚合参数还是哈希类型:
animals = ['cat', 'horse', 'rabbit', 'deer'] def find_word_lengths(word_list) word_list.reduce(Hash.new()) do |result, animal| result[animal] = animal.length result # 显式返回哈希作为下一次迭代的聚合参数 end end puts find_word_lengths(animals)
运行输出为:{"cat"=>3, "horse"=>5, "rabbit"=>6, "deer"=>4}
方式2:改用each_with_object方法
each_with_object不需要手动返回聚合对象,会自动把初始对象传入每一次迭代,写法更简洁:
animals = ['cat', 'horse', 'rabbit', 'deer'] def find_word_lengths(word_list) word_list.each_with_object(Hash.new()) do |animal, result| result[animal] = animal.length end end puts find_word_lengths(animals)
运行结果和方式1完全一致。
内容的提问来源于stack exchange,提问作者Mohammed Khiari
相关产品推荐
相关产品推荐

