2017-12-01 3 views
0

私は料理の本からコミュニティconsulの料理本に依存しています。
私はconsulをサーバモードとクライアントモードに持っているので、名前空間を分けたいと思います。この場合
、私は私のレシピでは以下の構成を使用することができます。これは同じになぜ起こるかシェフがレシピ内の別の名前空間から属性を再割り当てすると、4レベルの配列で未定義のメソッドエラーが発生する

================================================================================ 
    Recipe Compile Error in /tmp/kitchen/cache/cookbooks/eax-consul-cluster/recipes/default.rb 
    ================================================================================ 

    NoMethodError 
    ------------- 
    undefined method `[]' for nil:NilClass 

:予想通り

node.default['consul']['config']['server'] = node['consul-server']['config']['server'] if node['consul-server']['config']['server'] 
node.default['consul']['config']['ui'] = node['consul-server']['config']['ui'] if node['consul-server']['config']['ui'] 
node.default['consul']['config']['ports']['http'] = node['consul-server']['config']['ports']['http'] if node['consul-server']['config']['ports']['http'] 
node.default['consul']['config']['ports']['https'] = node['consul-server']['config']['ports']['https'] if node['consul-server']['config']['ports']['https'] 

最初の二行のフォークが、次のエラーを生成する2つの最後の行をそれらの間の唯一の違いは、配列が1レベル深いことですか?

答えて

0

あるレベルでは、[]メソッドがnilを返すためです。たとえば、node.default['consul']nilを返し、次にnode.default['consul']['config']がエラーを発生させるとします。

node.defaultは...のハッシュのハッシュのハッシュである場合には、読み取り値のために、あなたは例えば、Hash#digを試すことができます。

h = {'a' => {'b' => 'c'} } 
h.dig('a', 'b') #=> c 
h.dig('x', 'y') #=> nil 

値を設定するためには、必ず親レベルを確認する必要がありますすでに設定されています。

+0

だから私はそれが 'if'セクションで起こると信じていますが、' if'はnilの場合は 'else'に移動しないでください。 – vvchik

+0

もしconditionの値が 'nil'ならば' then'セクションの変数にこの値を代入する必要はありません – vvchik

+0

'node ['consul-server'] ['config'] ['ports']' 'nil'ですが、どうなりますか? 'node ['consul-server'] ['config'] ['ports'] ['http']'は 'nil ['http']'であり、間違いなく間違いが発生します。 – Aetherus

0

if if node.read('consul-server', 'config', 'ports', 'http')に切り替えます。これにより、Hash#digと同様に、介入するキーでnilが自動的にチェックされます。例の場合などサイドノートで

+0

「シェフ」があなたの専門と思われるので、あなたは「私たち」と以下に述べましたが、私はあなたが開発と何か関係があると思います。なぜこのタイプのものに 'deep_merge'を提供しないのか説明してください(私はmixinとして提供されているのを見ましたが、なぜそれが' Mash'に混ざらないのですか)?また、私が持っているものを実装することに異議はありますか?私はシェフを使用していませんが、ルビーはルビーであり、投稿されたオリジナルのコードは、私の意見ではその多くの条件を必要としません – engineersmnky

0

あなたの命名規則は、それらをマージし、正確に最初のレベルより下に並んでいるので、より適切と思われると、すべての条件文、深さのチェックを回避し、

# Essentially a railsesque #deep_merge! 
merge_proc = Proc.new do |_k,old,new| 
    if old.is_a?(Hash) && new.is_a?(Hash) 
    old.merge(new,&merge_proc) 
    else 
    new 
    end 
end 

node.default['consul'].merge!(node['consul-server'], &merge_proc) 

Hash#merge!Mash(シェフのHashのサブクラス)は依然としてa Hash

関連する問題