我想检查节点属性的值.这个case陈述是我到目前为止所做的,它有效:
case node[:languages][:ruby][:host_cpu]
when "x86_64"
...
when "i686"
...
end
Run Code Online (Sandbox Code Playgroud)
我想做的是改用if声明.这是我试过的:
if node[:languages][:ruby][:host_cpu]?("X86_64")
...
end
Run Code Online (Sandbox Code Playgroud)
这基于以下内容,其中有效.
if platform?("ubuntu")
...
end
Run Code Online (Sandbox Code Playgroud)
但是,我的尝试没有用.它if在行上给出了一个语法错误,说有一个意外的\n并且$end是预期的.
我发现有两种表现方式if.第一个是我上面演示的那个,(显然)只适用于资源,并且if_only与节点一起工作.像这样
if_only {node[:languages]}
Run Code Online (Sandbox Code Playgroud)
这似乎仅用于检查节点的存在,以及在do上下文中.
如何使用if语句检查节点的值?一种方法检查值,但仅检查资源,另一种方法检查节点,但仅限于它们的存在,而不是它们的值.
你正在混淆许多不同的条件变体,其中大多数是Chef的一部分,而不是Ruby.让我试着逐一描述不同的选择.
通常,a case与一系列if和elsif陈述大致相当.你的case上面
case node[:languages][:ruby][:host_cpu]
when "x86_64"
...
when "i686"
...
end
Run Code Online (Sandbox Code Playgroud)
因此大致相当于
if node[:languages][:ruby][:host_cpu] == "x86_64"
...
elsif node[:languages][:ruby][:host_cpu] == "i686"
...
end
Run Code Online (Sandbox Code Playgroud)
作为旁注,case实际上使用的===操作符通常不是可交换的,但更强大.对于简单的比较,它的工作原理与之相同==.这两种变体都是Ruby语言的一部分,您可以在其中编写烹饪书.
您提到的其他选项实际上是Chef在Ruby之上定义的API的一部分.这通常称为Chef DSL(代表域特定语言,即语言的扩展或改编,在本例中为特定用法域的Ruby,在本例中为配置管理.)
该platform?方法是由Chef定义的方法,用于检查curent平台是否是传递的值之一.您可以阅读更多相关信息(以及类似的方法,例如,现在推荐platform_family?的Chef文档中的方法,一般用于配方和一些常用的红宝石成语.
作为旁注:您可能会对Ruby允许?和!字符出现在方法名称的末尾这一事实感到惊讶,这使得Ruby在这方面在类似语言中相当独特.这些字符只是方法名称的一部分,对语言没有特殊意义.它们仅按惯例用于程序员以更好地识别方法的目的.如果一个方法最后有一个方法?,它将用于检查某些条件,并且预计会返回真值或假值.!最后使用a的方法通常会执行一些潜在的危险操作,例如更改对象,删除内容,......再次,这只是一种约定,不会被语言解释.
您提到的最后一个选项,only_if扩展名和扩展名not_if用于定义Chef资源上的条件,以确保它们仅在某个条件为真时执行(或者在使用时执行not_if,如果为false).由于这些属性仅用于Chef资源,因此它们自然也由Chef定义.
要了解它们有用的原因,有必要了解Chef运行的方式.详细信息可以在Chef Run的Anatomy中找到.重要的是,您基本上有两个执行阶段:资源编译和融合.在第一步中,执行定义资源的实际代码.在这里,您的case语句中的代码也将运行.在加载完所有配方并定义了所有资源后,Chef进入第二阶段,即Convergence阶段.在那里,运行执行更改的资源的实际实现(在存储包中创建文件和目录,......).仅在此阶段,检查only_if和not_if条件.
事实上,你可以观察到它们之间的区别
file "/tmp/helloworld"
action :create
content "hello world"
end
if File.exist?("/tmp/helloworld")
file "/tmp/foobar"
action :create
content "foobar"
end
end
Run Code Online (Sandbox Code Playgroud)
和
file "/tmp/helloworld"
action :create
content "hello world"
end
file "/tmp/foobar"
action :create
content "foobar"
only_if{ File.exist?("/tmp/helloworld") }
end
Run Code Online (Sandbox Code Playgroud)
在第一个变体中,/tmp/foobar在资源编译期间检查是否存在的条件.此时,/tmp/helloworld尚未运行实际创建文件的代码,因为它仅在转换步骤中执行.因此,在第一次运行期间,/tmp/foobar将不会创建该文件.
然而,在第二种变型中,完成检查only_if,在转换期间对其进行评估.在这里,您会注意到第一次运行时都会创建这两个文件.
如果你想更多地了解条件的定义如何在Ruby方面工作(你肯定应该),你可以阅读Ruby块,这些块或多或少的代码片段可以被传递以供以后执行.