2013-01-05 54 views
3

我想检查节点属性的值。这case语句是我有什么,到目前为止,它的工作原理:如何将此case语句更改为if语句?

case node[:languages][:ruby][:host_cpu] 
    when "x86_64" 
    ... 
    when "i686" 
    ... 
end 

我想要做的是使用if语句。这是我试过的:

if node[:languages][:ruby][:host_cpu]?("X86_64") 
    ... 
end 

这是基于以下,哪些工作。

if platform?("ubuntu") 
    ... 
end 

但是,我的尝试没有奏效。它在if行上提供了一个语法错误,表示有预期的\n$end。我发现有两种方式执行if。第一个是我在上面演示的那个,它显然只适用于资源,而if_only适用于节点。像这样

if_only {node[:languages]} 

这似乎只适用于检查存在的节点,并在一个做的上下文。

如何使用if语句检查节点的值?一种方法检查值,但只检查资源,另一种检查节点,但只检查它们的存在,而不检查它们的值。

+0

最终的问题是,'平台?'是一个方法名,随机会附上'?'的事情不会总是(即,通常不会)工作。只留下问号。 –

+0

我是,如果语句的语法中使用的''作为符号,类似方式的部分则在Java中使用('INT X =(表达式)1:2;'?)的印象?。这种想法很难被认为是“随机加固”,即使它不正确。 – stanri

+0

这不是一个'if'语句,而是一个单独的问题。 Ruby语法指南可能会消除您的困惑,因为所有不是调用方法的基本示例都不包含问号,并且问号函数符号是泛型。对我来说似乎很随意;因人而异。 –

回答

7

您正在混合使用条件的许多不同变体,其中大部分是厨师的一部分,而不是Ruby。让我试着逐个描述不同的选项。

一般而言,case完全可以与ifelsif陈述相比较。你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_ifnot_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的更多或更少的代码片段,这些代码片段可以传递给稍后执行。