gpt4 book ai didi

ruby - 如何将此 case 语句更改为 if 语句?

转载 作者:数据小太阳 更新时间:2023-10-29 07:46:42 28 4
gpt4 key购买 nike

我想检查节点属性的值。此 case声明是我到目前为止所拥有的,并且它有效:

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]} 

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

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

最佳答案

您正在混合多种不同的条件变体,其中大部分是 Chef 的一部分,而不是 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 语言的一部分,您可以在其中编写 Recipe 。

您提到的其他选项实际上是 Chef 在 Ruby 之上定义的 API 的一部分。这通常被称为 Chef DSL(它代表领域特定语言,即语言的扩展或改编,在这种情况下是针对特定使用领域的 Ruby,在这种情况下是配置管理。)
platform? method 是 Chef 定义的一种方法,用于检查当前平台是否是传递的值之一。您可以阅读更多相关信息(以及类似的方法,例如现在在 Chef 文档中推荐的 platform_family? 方法 recipes in general 和一些 often used ruby idioms

作为旁注:您可能会对 Ruby 允许 ? 的事实感到惊讶。和 !字符出现在方法名称的末尾,这使得 Ruby 在这方面的同类语言中相当独特。这些字符只是方法名称的一部分,对语言没有特殊意义。它们仅用于程序员的约定,以更好地识别方法的目的。如果一个方法有 ?最后,它用于检查某些条件,并期望返回真值或假值。带有 ! 的方法最后经常执行一些有潜在危险的操作,例如更改对象到位,删除内容,......同样,这只是一个约定,不被语言解释。

你提到的最后一个选项, only_if并通过扩展 not_if用于在 Chef 资源上定义条件,以确保它们仅在特定条件为真时(或使用 not_if 时,如果为假)才执行。由于这些属性仅用于 Chef 资源,因此它们自然也由 Chef 定义。

要了解它们为何有用,有必要了解 Chef 运行的工作原理。详情可在 Anatomy of a Chef Run的说明中找到。 .重要的是,您基本上有两个执行阶段:资源编译和收敛。在第一步中,执行定义资源的实际代码。在这里,还有您的 case 中的代码语句将被运行。在加载了所有配方并定义了所有资源后,Chef 进入第二阶段,即收敛阶段。在那里,运行执行更改(创建文件和目录、安装包等)的资源的实际实现。只有在这个阶段, 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它们或多或少是可以传递以供以后执行的代码段。

关于ruby - 如何将此 case 语句更改为 if 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14170184/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com