我的应用向不同的方法传递一个json_element
,其中的键是不同的,有时是空的。
为了处理它,我一直在使用以下示例代码对提取进行硬编码:
def act_on_ruby_tag(json_element)
begin
# logger.progname = __method__
logger.debug json_element
code = json_element['CODE']['$'] unless json_element['CODE'].nil?
predicate = json_element['PREDICATE']['$'] unless json_element['PREDICATE'].nil?
replace = json_element['REPLACE-KEY']['$'] unless json_element['REPLACE-KEY'].nil?
hash = json_element['HASH']['$'] unless json_element['HASH'].nil?
我想消除对值的硬编码,但不太确定如何。
我开始思考如下:
keys = json_element.keys
keys.each do |k|
set_key = k.downcase
instance_variable_set("@" + set_key, json_element[k]['$']) unless json_element[k].nil?
end
然后在方法的其余部分使用 @code
作为示例。
我打算尝试变成一种方法,然后替换所有这些硬编码代码。
但我不确定这是否是一条好路。
从具有{ code: ... }
之类的方法返回散列结构几乎总是比设置任意实例变量更好。如果您将它们返回到一致的容器中,调用者就可以更轻松地将其交付到正确的位置、存储它以备后用,或者挑选出他们想要的并丢弃其余的。
尝试将一个大而笨重的步骤分解为一系列更小、更轻的操作也是一个好主意。这使得代码更容易理解:
def extract(json)
json.reject do |k, v|
v.nil?
end.map do |k, v|
[ k.downcase, v['$'] ]
end.to_h
end
然后你得到这个:
extract(
'TEST' => { '$' => 'value' },
'CODE' => { '$' => 'code' },
'NULL' => nil
)
# => {"test"=>"value", "code"=>"code"}
如果您想将整个事物作为实例变量持久化,这是一个相当典型的模式,但它将有一个可预测的名称,不受您正在使用的任意 JSON 文档的支配。
另一种方法是将键硬编码为常量,例如:
KEYS = %w[ CODE PREDICATE ... ]
然后改用它,或者更进一步,在 YAML 或 JSON 文件中定义您可以读入以进行配置的文件。这实际上取决于这些更改的频率,以及您对输入的不规则性有什么样的期望。
我是一名优秀的程序员,十分优秀!