如何在散列中指定参数
How to specify params in a hash
我有一本用于安装 JRuby 的 Community Chef 食谱。我在指定要安装的 Gem 版本时遇到问题。我已经尝试了所有我能想到的散列、键、字符串等的组合。
以下是代码的相关部分:
default[:jruby][:gems] = ["some-gem", "another-one"]
是的,这是一个字符串数组,但散列数组应该是可能的。
这是由以下片段读取的:
node[:jruby][:gems].each do |gem|
Chef::Log.info "Installing Jruby Gem #{gem}"
if gem.is_a? Hash
name = gem.delete(:name)
else
name = gem
gem = nil
end
jruby_gem name, gem || {}
end
并最终落入此定义之手:
define :jruby_gem, :source => nil, :version => nil do
gem_package params[:name] do
gem_binary "#{node[:jruby][:install_path]}/bin/gem"
source params[:source] if params[:source]
version params[:version] if params[:version]
end
end
给定该代码,什么样的哈希将填充生成的定义中的 :name
和 :version
值?
我尝试过的东西在以下领域...
[
{:name => "some-gem", :version => "0.1.2"},
{:name => "another-one"} # I don't need to constrain every Gem to a version
]
编辑:
所以感谢完全正确的 Ruby-esque 响应,但实际上我在转向 SO 之前确实尝试了一些变体的哈希数组方法。疲劳使我打错了最初出现在我问题中的结构。
我看到的问题似乎与 Chef 和您在上面看到的定义有关。我得到的错误如下...
Node attributes are read-only when you do not specify which precedence level to set. To set an attribute use code like `node.default["key"] = "value"'
Cookbook Trace:
---------------
/var/chef/cache/cookbooks/jruby/recipes/default.rb:48:in `block in from_file'
/var/chef/cache/cookbooks/jruby/recipes/default.rb:45:in `each'
/var/chef/cache/cookbooks/jruby/recipes/default.rb:45:in `from_file'
Relevant File Content:
----------------------
/var/chef/cache/cookbooks/jruby/recipes/default.rb:
41: notifies :create_if_missing, "file[/etc/profile.d/jruby.sh]"
42: end
43:
44: # install all gems defined in the module
45: node[:jruby][:gems].each do |gem|
46: Chef::Log.info "Installing Jruby Gem #{gem}"
47: if gem.is_a? Hash
48>> name = gem.delete(:name)
49: else
50: name = gem
51: gem = nil
52: end
53: jruby_gem name, gem || {}
54: end
55:
尝试:
[
{:name => "some-gem", :version => "0.1.2"},
{:name => "another-one"} # I don't need to constrain every Gem to a version
]
注意内部数据结构是用花括号定义的,而不是方括号。
[]
组成一个数组
{}
的哈希
您正在创建一个数组的数组,但您真正想要的是一个哈希数组。
编辑
文档似乎表明您可以按照以下方式尝试:
default[:jruby].set[:gems] = ["some-gem", "another-one"]
这是我从以下内容的简短浏览中得到的:
https://www.chef.io/blog/2013/02/05/chef-11-in-depth-attributes-changes/
不幸的是,这里的问题不是你的属性而是你的实际食谱。
您(和我,今天!)正在使用的 jruby cookbook 的实现与 Chef 11+ 不兼容。看到这个 link:
https://www.chef.io/blog/2013/02/05/chef-11-in-depth-attributes-changes/
Now you must specify which precedence level you want to write to when setting attributes; accessing attributes on the node directly is only for reading.
此处出错的行正是这样做的:
if gem.is_a? Hash
name = gem.delete(:name) <- This is modifying node.jruby.gems.some_gem!
因此,如果你想使用它,你必须采取以下几种方法之一:
- fork jruby cookbook 并修复它。它非常古老,none 现有的直接分支支持 Chef 11,所以如果你想接管它,你可以变得像一个小神。
- 完全使用单独的说明书进行 gem 安装(这是我们到目前为止一直在做的事情)。
- 创建一个包含 jruby cookbook without setting jruby.gems 的 wrapper cookbook,并添加一个属性和你自己的 Ruby 块来设置'right' 方式。
一个例子是:
my_gems = node['jruby']['my_gems'].dup
my_gems.each do |gem|
if gem.is_a? Hash
name = gem.delete('name')
else
name = gem
gem = nil
end
jruby_gem name, gem || {}
end
如果进行适当的调整,这实际上会起作用。使用这个确切块的示例厨师客户端输出将是:
> Recipe: mycompany-jruby::default
> * gem_package[some-package] action install
> - install version #.#.# of package some-package
我有一本用于安装 JRuby 的 Community Chef 食谱。我在指定要安装的 Gem 版本时遇到问题。我已经尝试了所有我能想到的散列、键、字符串等的组合。
以下是代码的相关部分:
default[:jruby][:gems] = ["some-gem", "another-one"]
是的,这是一个字符串数组,但散列数组应该是可能的。
这是由以下片段读取的:
node[:jruby][:gems].each do |gem|
Chef::Log.info "Installing Jruby Gem #{gem}"
if gem.is_a? Hash
name = gem.delete(:name)
else
name = gem
gem = nil
end
jruby_gem name, gem || {}
end
并最终落入此定义之手:
define :jruby_gem, :source => nil, :version => nil do
gem_package params[:name] do
gem_binary "#{node[:jruby][:install_path]}/bin/gem"
source params[:source] if params[:source]
version params[:version] if params[:version]
end
end
给定该代码,什么样的哈希将填充生成的定义中的 :name
和 :version
值?
我尝试过的东西在以下领域...
[
{:name => "some-gem", :version => "0.1.2"},
{:name => "another-one"} # I don't need to constrain every Gem to a version
]
编辑:
所以感谢完全正确的 Ruby-esque 响应,但实际上我在转向 SO 之前确实尝试了一些变体的哈希数组方法。疲劳使我打错了最初出现在我问题中的结构。
我看到的问题似乎与 Chef 和您在上面看到的定义有关。我得到的错误如下...
Node attributes are read-only when you do not specify which precedence level to set. To set an attribute use code like `node.default["key"] = "value"'
Cookbook Trace:
---------------
/var/chef/cache/cookbooks/jruby/recipes/default.rb:48:in `block in from_file'
/var/chef/cache/cookbooks/jruby/recipes/default.rb:45:in `each'
/var/chef/cache/cookbooks/jruby/recipes/default.rb:45:in `from_file'
Relevant File Content:
----------------------
/var/chef/cache/cookbooks/jruby/recipes/default.rb:
41: notifies :create_if_missing, "file[/etc/profile.d/jruby.sh]"
42: end
43:
44: # install all gems defined in the module
45: node[:jruby][:gems].each do |gem|
46: Chef::Log.info "Installing Jruby Gem #{gem}"
47: if gem.is_a? Hash
48>> name = gem.delete(:name)
49: else
50: name = gem
51: gem = nil
52: end
53: jruby_gem name, gem || {}
54: end
55:
尝试:
[
{:name => "some-gem", :version => "0.1.2"},
{:name => "another-one"} # I don't need to constrain every Gem to a version
]
注意内部数据结构是用花括号定义的,而不是方括号。
[]
组成一个数组{}
的哈希
您正在创建一个数组的数组,但您真正想要的是一个哈希数组。
编辑
文档似乎表明您可以按照以下方式尝试:
default[:jruby].set[:gems] = ["some-gem", "another-one"]
这是我从以下内容的简短浏览中得到的: https://www.chef.io/blog/2013/02/05/chef-11-in-depth-attributes-changes/
不幸的是,这里的问题不是你的属性而是你的实际食谱。
您(和我,今天!)正在使用的 jruby cookbook 的实现与 Chef 11+ 不兼容。看到这个 link:
https://www.chef.io/blog/2013/02/05/chef-11-in-depth-attributes-changes/
Now you must specify which precedence level you want to write to when setting attributes; accessing attributes on the node directly is only for reading.
此处出错的行正是这样做的:
if gem.is_a? Hash
name = gem.delete(:name) <- This is modifying node.jruby.gems.some_gem!
因此,如果你想使用它,你必须采取以下几种方法之一:
- fork jruby cookbook 并修复它。它非常古老,none 现有的直接分支支持 Chef 11,所以如果你想接管它,你可以变得像一个小神。
- 完全使用单独的说明书进行 gem 安装(这是我们到目前为止一直在做的事情)。
- 创建一个包含 jruby cookbook without setting jruby.gems 的 wrapper cookbook,并添加一个属性和你自己的 Ruby 块来设置'right' 方式。
一个例子是:
my_gems = node['jruby']['my_gems'].dup
my_gems.each do |gem|
if gem.is_a? Hash
name = gem.delete('name')
else
name = gem
gem = nil
end
jruby_gem name, gem || {}
end
如果进行适当的调整,这实际上会起作用。使用这个确切块的示例厨师客户端输出将是:
> Recipe: mycompany-jruby::default
> * gem_package[some-package] action install
> - install version #.#.# of package some-package