如何整理在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
,它将象征所有键而不仅仅是顶层?
答案 0 :(得分: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]
我认为这种安排对于同行和用户来说更容易理解。
答案 1 :(得分:0)
在博客的帮助下: - Ruby Nested Hash - Deep Fetch - Returning a (Default) Value for a Key That Does Not Exist in a Nested Hash:
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