Ruby中如何收集hash的KeyError到数组,一次性返回所有缺失字段
问题原因
你当前的代码只能收集到第一个缺失键,是因为KeyError的捕获逻辑写在call方法外层,extract_values内第一个fetch触发异常后,就会直接终止整个方法执行,跳转到外层的rescue分支返回,不会执行后续的fetch操作。
修复后实现
我们可以把异常捕获逻辑下沉到单个键的读取流程中,逐个处理每个必填键的读取和异常记录,避免单键缺失终止整个校验流程:
class Extractor # 单独维护必填字段配置,后续增删字段只需要修改此处 REQUIRED_KEYS = [:required_field_1, :required_field_2, :required_field_3] def initialize(hash) @hash = hash @missed_keys = [] end def call extracted = extract_values return "Missed keys: #{@missed_keys.join(', ')}" if @missed_keys.any? # 无缺失字段时返回提取后的结果,可按需调整返回逻辑 extracted end private def extract_values REQUIRED_KEYS.each_with_object({}) do |key, result| result[key] = @hash.fetch(key) rescue KeyError @missed_keys << key end end end
如果需要保留原代码中value_1、value_2这类自定义别名的映射,可以调整配置结构:
class Extractor # 别名 => 原始hash键的映射配置 REQUIRED_MAPPING = { value_1: :required_field_1, value_2: :required_field_2, value_3: :required_field_3 } def initialize(hash) @hash = hash @missed_keys = [] end def call extracted = extract_values return "Missed keys: #{@missed_keys.join(', ')}" if @missed_keys.any? extracted end private def extract_values REQUIRED_MAPPING.each_with_object({}) do |(alias_key, origin_key), result| result[alias_key] = @hash.fetch(origin_key) rescue KeyError @missed_keys << origin_key end end end
运行效果
传入空hash测试:
pry(main)> Extractor.new({}).call => "Missed keys: required_field_1, required_field_2, required_field_3"
注意事项
原代码中使用的present?是Ruby on Rails框架专属方法,如果你在纯Ruby环境运行,替换为通用的any?即可。
内容的提问来源于stack exchange,提问作者mzsrn
相关产品推荐
相关产品推荐

