2

如何整理在 ruby​​ 中设置和请求深度哈希值的代码?

例如,假设我有一个这样的哈希:

  hash = {
    user_settings: {
      notifications: {
        overdue_tasks: { enabled: true, duration: 30 },
        created_overdue_tasks: { enabled: true, duration: 30 } 
      }
    }
  }

如何避免编写这样的脆弱访问代码:

  hash[:user_settings][:notifications][:overdue_tasks][:duration] = 5

此外,是否有一个递归symbolize_keys可以象征所有的键,而不仅仅是顶层?

4

2 回答 2

1

我不知道以这种方式简化代码以获取所需的键/值,但我建议通过命名使您的哈希变得简单。

怎么样

hash = {
  user_settings: {
    overdue_task_notification_enabled:  true,
    overdue_task_notification_duration: 30,
    created_overdue_tasks_enabled:      true,
    created_overdue_tasks_duration:     30 
  } 
}

然后像

hash[:user_settings][:created_overdue_tasks_duration]

我认为这种安排对于同行和用户来说看起来更容易理解。

于 2013-08-12T09:44:04.857 回答
0

从博客中获得帮助:- Ruby Nested Hash - Deep Fetch - 返回嵌套哈希中不存在的键的(默认)值

class Hash
 def deep_fetch(key, default = nil)
   default = yield if block_given?
   (deep_find(key) or default) or raise KeyError.new("key not found: #{key}")
 end

 def deep_find(key)
    key?(key) ? self[key] : self.values.inject(nil) {|memo, v| memo ||= v.deep_find(key) if v.respond_to?(:deep_find) }
  end
end


hash = {
    user_settings: {
      notifications: {
        overdue_tasks: { enabled: true, duration: 30 },
        created_overdue_tasks: { enabled: true, duration: 30 } 
      }
    }
  }

p hash.deep_fetch(:duration)
# >> 30
于 2013-08-12T09:44:49.343 回答