2015-11-05 54 views
0

下面的代码按预期方式工作,并产生下列:厨师/红宝石:参考定义在哈希

==> default: foo_definition: a 
==> default: foo_definition: foo 
==> default: foo_definition: fiz 
==> default: bar_definition: b 
==> default: bar_definition: bar 
==> default: bar_definition: biz 

食谱/ foobar的/食谱/ default.rb:

node.default[:configs][:a][:def_name] = 'foo_name' 
node.default[:configs][:a][:message] = 'fiz' 
node.default[:configs][:b][:def_name] = 'bar_name' 
node.default[:configs][:b][:message] = 'biz' 

#def_map = { 
#  'foo_name' => foo_definition, 
#  'bar_name' => bar_definition 
#} 

for config_name in node[:configs].keys do 
     def_name = node[:configs][config_name][:def_name] 

     if def_name == 'foo_name' 
       foo_definition config_name do 
         config_name config_name 
       end 
     elsif def_name == 'bar_name' 
       bar_definition config_name do 
         config_name config_name 
       end 
     else 
       raise Exception('Unknown def #{def_name}') 
     end 
end 

食谱/ foobar的/definitions/default.rb:

define :foo_definition, :config_name => nil do 
     config_name = params[:config_name] 
     print("foo_definition: #{config_name}") 
     print("foo_definition: #{node[:configs][config_name][:def_name]}") 
     print("foo_definition: #{node[:configs][config_name][:message]}") 
end 

define :bar_definition, :config_name => nil do 
     config_name = params[:config_name] 
     print("bar_definition: #{config_name}") 
     print("bar_definition: #{node[:configs][config_name][:def_name]}") 
     print("bar_definition: #{node[:configs][config_name][:message]}") 
end 

我想使用散列来查找在config中指定的特定定义。但是,如果我取消def_map的注释,厨师会抱怨:

==> default: NoMethodError 
==> default: ------------- 
==> default: undefined method `[]' for nil:NilClass 
==> default: 
==> default: 
==> default: Cookbook Trace: 
==> default: --------------- 
==> default: /tmp/vagrant-chef/2e4e554824398d9416eee0b4bd47e8b9/cookbooks/foobar/definitions/default.rb:4:in 'block in from_file' 

任何人都能解释为什么?

最后,我希望能够做这样的事在配方:

node.default[:configs][:a][:def_name] = 'foo_name' 
node.default[:configs][:a][:message] = 'fiz' 
node.default[:configs][:b][:def_name] = 'bar_name' 
node.default[:configs][:b][:message] = 'biz' 

def_map = { 
     'foo_name' => foo_definition, 
     'bar_name' => bar_definition 
} 

for config_name in node[:configs].keys do 
     def_name = node[:configs][config_name][:def_name] 
     if def_map.key?(def_name) 
       named_def = def_map[def_name] 
       named_def config_name do 
         config_name config_name 
       end 
     else 
       raise Exception('Unknown def #{def_name}') 
     end 
end 

回答

1

你定义有一个名为参数:CONFIG_NAME

define :foo_definition, :config_name => nil do 

而且你怎么称呼它不带任何参数在def_map

'foo_name' => foo_definition, 

所以当定义呼叫编有(以你映射),CONFIG_NAME是零,而这条线

print("foo_definition: #{node[:configs][config_name][:def_name]}") 

被称为:

print("foo_definition: #{node[:configs][nil][:def_name]}") 

一种解决方法可以是使用这种代码(未经测试):

for config_name in node[:configs].keys do 
     def_name = node[:configs][config_name][:def_name] 
     send(def_name) config_name do 
         config_name config_name 
     end 
end 

如果定义未在配方方面知道,这应该抛出一个异常,你可以将它包装在一个try/catch块,如果你はnt不会中止运行并仅记录它。

+0

啊。没有意识到我在调用定义而不是简单地给它们分配一个指针。 –