Ruby按条件为哈希数组新增键值对出现NoMethodError如何解决
错误原因
- Ruby 中赋值表达式的返回值为等号右侧的值,你定义的
record_additional_info方法最后一行是materials[:city] = 'Kansas City',因此该方法的返回值是字符串"Kansas City",而非修改后的哈希对象。 - 你使用
map!遍历数组时,块内仅在条件成立时调用上述方法,此时map!会将数组的每个元素替换为方法返回的字符串;如果条件不成立,块返回nil,数组元素会被替换为nil。后续代码尝试遍历数组元素调用each方法时,就会对字符串或nil调用不存在的each方法,触发你遇到的报错。
修复方案
因为你只需要修改数组中已有的哈希对象的属性(哈希是可变对象),不需要替换数组本身的元素,推荐直接用each遍历修改即可,逻辑更简洁也不会出现类型错误:
def location_records(options) materials = [ { name: 'object1', area: 'USA' }, { name: 'object2', area: 'USA' } ] # 仅在条件满足时遍历修改哈希属性 if %w[USA].include?(options.extra_fields_required) materials.each{ |material| record_additional_info(material, options) } end materials end def record_additional_info(material, options) material[:zip] = 63123 material[:state] = 'Missouri' material[:city] = 'Kansas City' end
如果要保留原有的map!写法,需要调整两处逻辑:一是在record_additional_info最后明确返回修改后的哈希,二是在map!的块内始终返回哈希对象,避免数组元素被替换为其他类型:
def location_records(options) materials = [ { name: 'object1', area: 'USA' }, { name: 'object2', area: 'USA' } ] materials.map! do |material| if %w[USA].include?(options.extra_fields_required) record_additional_info(material, options) end material # 始终返回哈希本身 end end def record_additional_info(material, options) material[:zip] = 63123 material[:state] = 'Missouri' material[:city] = 'Kansas City' material # 明确返回修改后的哈希 end
内容的提问来源于stack exchange,提问作者Bao Thai
相关产品推荐
相关产品推荐

