我想知道以下方法在多个环境中捕获自定义配置参数有多糟糕。这是为了解决可能需要组织多层深度的非常大的配置参数的情况。
需要以下功能: - 设置配置参数需要非常简单,易于复制/粘贴 - 访问配置参数需要简洁 - 应该是灵活的编程,没有yaml(除非确信) - 每个环境的配置不一定是强制性的,应该依赖于一个理智的默认值(在这种情况下,:base config) - 初始化配置对象需要简洁 - 需要隐藏环境细节
此实施的缺点: - eval是邪恶的吗?在这种情况下,eval真的那么糟糕吗?用户不控制值,它们都是源代码中的硬编码。 - 不是最快的,但在我的情况下并不重要 - 初始化哈希是很奇怪的 - “获取”电话也有点奇怪
这是因为我需要一种强大的方法来处理可能包含大量参数的文件。这些参数可以在不同的环境中变化,因此能够轻松覆盖基值(每个环境)是至关重要的。
这些参数也需要与它们被调用的模型紧密耦合,因此初始化器和全局变量不是一种选择。
如果有人有更好的方式以更优雅的方式实现这些目标,我很乐意听到。这段代码不是很好的idomatic设计,所以我希望得到一些其他的想法,比如强有力的oop方法。
class Paramz
def initialize(params)
@env = :development # Rails.env.to_sym
@params = params
end
def get(values)
eval_hash(values.split("."))
end
protected
def eval_hash(values)
new_val = String.new
values.map { |v| new_val = new_val + "[:#{v}]" }
base, env = eval("@params[:base]" + new_val), eval("@params[@env]" + new_val)
return env != {} ? env : base
end
end
p = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }
# file config
p[:base][:file][:path] = "/opt/files"
p[:qa][:file][:path] = "c:\\files\\"
p[:production][:file][:path] = "/opt/projects/final"
params = Paramz.new(p)
# env = :base
puts params.get("file.path")
# >> "/opt/files" # returns :base config
# env = :development
# puts params.get("file.path")
# >> "/opt/files" # no :development config, falls back on :base
# env = :production
# puts params.get("file.path")
# >> "/opt/projects/final" # return :production config