2013-01-05 99 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的更多或更少的代碼片段,這些代碼片段可以傳遞給稍後執行。