您正在混合使用条件的许多不同变体,其中大部分是厨师的一部分,而不是Ruby。让我试着逐个描述不同的选项。
一般而言,case
完全可以与if
和elsif
陈述相比较。你case
以上
case node[:languages][:ruby][:host_cpu]
when "x86_64"
...
when "i686"
...
end
因此大致相当于
if node[:languages][:ruby][:host_cpu] == "x86_64"
...
elsif node[:languages][:ruby][:host_cpu] == "i686"
...
end
作为一个方面的话,case
实际使用===
运营商这往往是不可交换的,但功能更强大。对于简单的比较,它的工作原理与==
相同。这两种变体都是Ruby语言的一部分,您可以在其中编写食谱。
您提到的其他选项实际上是Chef在Ruby之上定义的API的一部分。这通常被称为厨师DSL(它代表领域特定语言,即语言的扩展或适应,在这种情况下Ruby为特定的使用领域,在这种情况下为配置管理)。
platform?
方法是由Chef定义的方法,检查curent平台是否是传递的值之一。你可以阅读更多有关(和类似的方法,例如,在厨师的文档现在建议platform_family?
方法recipes in general和一些often used ruby idioms
作为一个侧面一句话:你可以通过这样的事实感到惊讶的是红宝石允许?
和!
字符出现在方法名称的末尾,这使得Ruby在这方面在类似语言中相当独特。这些字符只是方法名称的一部分,对语言没有特殊含义。它们仅被惯例用于程序员以更好地识别方法的目的。如果一个方法具有?
在端部,它是用来检查一些条件和预期返回一个truthy或falsy值。最后使用!
的方法经常执行一些潜在的危险操作,例如,改变对象,删除东西,...再一次,这只是一个约定,不会被语言解释。
你提到的最后一个选项,only_if
并通过扩展not_if
的(使用not_if
时,如果是假的或)用来定义厨师的资源条件语句,以确保他们只是在执行时有一定条件为真。由于这些属性仅用于厨师资源,他们自然也由厨师定义。
要理解他们为什么有必要了解一个厨师运行工作有所帮助。详细信息可在Anatomy of a Chef Run的说明中找到。重要的是,你基本上有两个执行阶段:资源编译和收敛。在第一步中,执行定义资源的实际代码。在这里,您的case
声明中的代码也会运行。在所有配方加载完毕并确定了所有资源后,厨师进入第二阶段,即融合阶段。在那里,运行执行更改的资源(创建文件和目录,在失速包中...)的实际执行。只有在此阶段中,才会检查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
和
file "/tmp/helloworld"
action :create
content "hello world"
end
file "/tmp/foobar"
action :create
content "foobar"
only_if{ File.exist?("/tmp/helloworld") }
end
之间的差异在第一变,资源在编译过程中检查条件。在资源编译期间检查/tmp/foobar
。目前,用于实际创建/tmp/helloworld
文件的代码尚未运行,因为它只在“转换”步骤中进行。因此,在第一次运行时,/tmp/foobar
文件不会被创建。
在第二变型然而,检查与only_if
完成该转换过程中进行评价。在这里您会注意到两个文件都是在第一次运行时创建的。
如果您想了解更多有关条件的定义在Ruby方面的工作方式(您绝对应该这样做),您可以阅读关于Ruby Blocks的更多或更少的代码片段,这些代码片段可以传递给稍后执行。
最终的问题是,'平台?'是一个方法名,随机会附上'?'的事情不会总是(即,通常不会)工作。只留下问号。 –
我是,如果语句的语法中使用的''作为符号,类似方式的部分则在Java中使用('INT X =(表达式)1:2;'?)的印象?。这种想法很难被认为是“随机加固”,即使它不正确。 – stanri
这不是一个'if'语句,而是一个单独的问题。 Ruby语法指南可能会消除您的困惑,因为所有不是调用方法的基本示例都不包含问号,并且问号函数符号是泛型。对我来说似乎很随意;因人而异。 –