LoginSignup
1
1

More than 5 years have passed since last update.

Chefのattributeで値を設定する際、その値に属性を追加する可能性があるならば、その値は予めキーとして設定しておく

Posted at

問題

attributes/default.rb

default['foo']['bar']['file'] = '/tmp/test.txt'

などと最終的な値をdefault[]に代入すると、後からその属性情報を以下の様な感じで追加できない。

attributes/default.rb

default['foo']['bar']['file']['/tmp/test.txt']['owner'] = 'usr1'

対応

この様な拡張が後からできる様にするには、最初から以下の様にkeyにしておけば良い。

attributes/default.rb
default['foo']['bar']['file']['/tmp/test.txt'] = nil

# あるいは、通常は省略しているactionなどをあえて書いておく。
default['foo']['bar']['file']['/tmp/test.txt']['action'] = :create

これなら、

attributes/default.rb

default['foo']['bar']['file']['/tmp/test.txt'] = nil

# 追加で属性を拡張
default['foo']['bar']['file']['/tmp/test.txt']['owner'] = 'usr1'

などとできる。
この例の場合、もし行の順序が逆となると属性が消されてしまうので注意。それを考慮するとactionなど追加キー込みで設定した方がやや安全

蛇足 : 片方向連結リスト構造の様に、すべてのattributeの最後をnilで終わらせてみる

attributes/default.rb

default['foo']['bar']['file']['/tmp/test.txt'] = nil
default['foo']['bar']['file']['/tmp/test.txt']['owner']['usr1'] = nil

ユーザーデータが途中のキーだったり最後の値だったりという状況から、途中のキーに統一されて分かりやすくはなった

取り出す際のレシピへの影響はどうだろう。

attributes/default.rb

# 最後の値のみ.keys.firstをつける
node['foo']['bar']['file'].each do |f_name, f_attr|
  file f_name do
    owner f_attr['owner'].keys.first
  end
end

# もしくは
# すべての値はhashに対する.eachでキーを取り出す
node['foo']['bar']['file'].each do |f_name, f_attr|
  file f_name do
    f_attr['owner'].each do |o_name, _o_attr|
      owner o_name
    end
  end
end

最後の値だけ.keys.firstが必要という綺麗な実装では無い。
もしくは、ユーザーデータの扱いをhashに対する.eachに統一できるという点では整合性はとれているが、不必要に長い感触。

総合するとあまりメリットを感じなかった。

参考

[]= (Hash) Rubyリファレンス

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1