我想创建一个Chef库:
该库旨在与外部系统连接并从那里检索一些输入。我需要访问节点属性以允许用户覆盖从外部系统接收的输入:
inputs = MyLib.get_inputs
这受those docs启发。
class Chef::Recipe::MyLib
def self.get_inputs
override_inputs = node.fetch(:mylib, Hash.new).fetch(:override_inputs, nil)
unless override_inputs.nil?
return override_inputs
end
# Do stuff and return inputs (no problem here)
# ...
end
end
现在我得到了:
undefined local variable or method `node' for Chef::Recipe::Scalr:Class
答案 0 :(得分:17)
除非将其传递给初始化程序,否则您无权访问库中的节点对象:
class MyHelper
def self.get_inputs_for(node)
# Your code will work fine
end
end
然后你用:
来称呼它inputs = MyHelper.get_inputs_for(node)
或者,您可以创建一个模块并将其混合到Chef Recipe DSL中:
module MyHelper
def get_inputs
# Same code, but you'll get "node" since this is a mixin
end
end
Chef::Recipe.send(:include, MyHelper)
然后您可以在食谱中访问get_inputs
方法:
inputs = get_inputs
请注意,这是一个实例方法与类方法。
简而言之,除非作为参数提供,否则库无法访问node
对象。如果它们混合到Recipe DSL中,模块将会。此外,node
对象实际上是实例变量,因此在类级别(即self.
)不可用。
答案 1 :(得分:4)
我认为这里有一个范围问题,因为Node的范围在Chef :: Recipe下。因此,请尝试在定义中省略MyLib,看看它是否有效。我有一个以这种方式定义的库:
class Chef
class Recipe
def my_library_method
#access node stuff here should be fine
end
end
end