您正在混合使用條件的許多不同變體,其中大部分是廚師的一部分,而不是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語法指南可能會消除您的困惑,因爲所有不是調用方法的基本示例都不包含問號,並且問號函數符號是泛型。對我來說似乎很隨意;因人而異。 –