条件の多くの異なるバリアントを混同していますが、そのほとんどは Ruby ではなく Chef の一部です。さまざまなオプションを 1 つずつ説明してみましょう。
一般に、acase
は一連のif
andelsif
ステートメントにほぼ匹敵します。あなたの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 の一部です。これはしばしば Chef DSL と呼ばれます (これは Domain Specific Language の略です。つまり、言語の拡張または適応であり、この場合は特定の使用ドメイン用の Ruby、この場合は構成管理用です)。
メソッドは、現在platform?
のプラットフォームが渡された値の 1 つであるかどうかをチェックする Chef によって定義されたメソッドです。あなたはそれについてもっと読むことができます(そして同様の方法、例えば一般的なレシピplatform_family?
のためのシェフのドキュメントで現在推奨されている方法といくつかのよく使われるルビーイディオム.
余談ですが、Ruby ではメソッド名の末尾に?
および文字を使用できるという事実に驚かれるかもしれません。これにより、Ruby はこの点で類似の言語の中でも非常にユニークなものになっています。!
これらの文字は単にメソッド名の一部であり、言語にとって特別な意味はありません。これらは、メソッドの目的をより適切に識別するために、プログラマーへの慣例によってのみ使用されます。メソッド?
の末尾に a がある場合、それは何らかの条件をチェックするために使用され、真または偽の値を返すことが期待されます。!
末尾に a を持つメソッドは、多くの場合、潜在的に危険な操作を実行します。たとえば、オブジェクトをその場で変更する、何かを削除するなどです。
あなたが言及した最後のオプションであるonly_if
and by extensionnot_if
は、特定の条件が true の場合 (または false の場合は を使用するnot_if
場合) にのみ実行されるように、Chef リソースの条件を定義するために使用されます。これらの属性は Chef リソースでのみ使用されるため、必然的に Chef によっても定義されます。
なぜそれらが役立つのかを理解するには、Chef の実行がどのように機能するかを理解する必要があります。詳細は、Chef Run の解剖学の説明にあります。重要なのは、基本的にリソースのコンパイルと収束という 2 つの実行フェーズがあることです。最初のステップでは、リソースを定義する実際のコードが実行されます。case
ここでは、ステートメント内のコードも実行されます。すべてのレシピがロードされ、すべてのリソースが定義された後、Chef は 2 番目のフェーズである収束フェーズに入ります。そこで、変更を実行するリソースの実際の実装 (ファイルとディレクトリの作成、ストール パッケージなど) が実行されます。このフェーズでのみ、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
ファイルは作成されません。
ただし、2 番目のバリアントでは、only_if
変換中に評価されるチェックが行われます。ここで、最初の実行で両方のファイルが作成されることがわかります。
条件の定義が Ruby の観点からどのように機能するかについてもう少し詳しく読みたい場合は (必ずそうすべきです)、後で実行するために渡すことができる多かれ少なかれコードの断片であるRuby ブロックについて読むことができます。