2017-04-24 8 views
1

私のアプリは、鍵が異なっていても空である場合があるjson_elementの異なるメソッドに渡します。ruby​​を使ってDRYの方法でハッシュ値を抽出する

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を使用しています。

私はメソッドに変わってから、このハードコードされたコードをすべて置き換えようとしていました。

しかし、これが良いパスであるかどうかは完全にはわかりませんでした。

答えて

3

ほとんどの場合、任意のインスタンス変数を設定するのではなく、{ 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ファイルにそれを定義することを使用します目的。これは実際にどのくらいの頻度で変化するか、また入力の不規則性についてどのような期待を持っているかによって大きく異なります。

+0

おかげで...私は、キーを抜くと確認するために....「$」は、実際にCobravsMongoose gem.BUTを使用してのartfactであることに気づいた...本当の問題は、あなたが議論されているものですエラーが発生していないかどうかを判断します。 キーの1つに値がありません - それは空です。だから、私は 'nil?'チェックを持っているのです。 – Angela

+0

空と 'nil? 'は2つの異なるものです。ちょっと心に留めておいてください。あなたがナビゲートできるものを探しているだけの場合は、テスト対「v」で十分です。最小限のコードは通常、デバッグが容易です。これらのケースでは – tadman

0

これは、元のコードの機能をやや簡潔にする方法です。

code, predicate, replace, hash = json_element.values_at *%w{ 
    CODE PREDICATE REPLACE-KEY HASH 
}.map { |x| x.fetch("$", nil) if x } 
+0

が、私はキーが 'code、predicate、replace ... etc 'であることを知る必要があるでしょうか?それらは毎回変わっていきます。 .... – Angela

+0

これを解析するにはどうすればいいですか? '$'アーティファクトなしでこれを作成できるかもしれません。 – Angela

+0

これは、メタプログラミングを使用せずに、4つの特定のキーをトップレベル変数に抽出する方法です。多くの場合、ルビーでは同じことをする多くの方法があります –

関連する問題