2011-07-06 64 views
2

我正在開發一個針對ruby的C擴展,我正在訪問的C庫中的一個函數接收一個選項結構,它似乎很自然地轉換爲ruby-world中的選項哈希。在ruby C擴展中鍵入檢查選項哈希值時的最佳做法是什麼?

當ruby方面的散列未定義給定選項的值時,結構正在使用已知默認值進行初始化。在C面我沿着這些線路一些:

VALUE tmp; 

tmp = rb_hash_aref(r_hash, rb_str_new2("opt1")); 

if(TYPE(tmp) == T_STRING){ 
    strcpy (c_learn_param->opt1, StringValuePtr(tmp)); 
}else{ 
    strcpy (c_learn_param->opt1, "default value 1"); 
} 

現在我的問題是,當一個選項的定義值,但紅寶石式無厘頭的C.

應我甚至提高類型的錯誤爲可選值?這看起來過於誇張,我應該回到默認?回落到默認值的問題是,通過{「opt1」=> 123}的用戶會看到相同的行爲,就好像他沒有定義opt1這似乎是一個壞主意,我是否應該回退並打印紅寶石警告? (人們甚至讀過它們嗎?)。

+1

如果您閱讀TypeError的RDoc:「遇到不屬於預期類型的​​對象時引發。我認爲這就是你在這裏發生的事情。回落到默認值只會導致混淆。如果你正確地記錄了引發TypeError的方法和條件,那麼它就沒有什麼不好了。 – emboss

+0

是的,我確實在函數的常規參數(非可選)上做了這個。我在想,如果在選擇性參數上做同樣的事情會不會太嚴格,但是,你說得對,最好是失敗而不是結果出乎意料的價值。 – Camilo

回答

0

您應該至少接受符號或字符串,因爲它們在實踐中幾乎可以互換使用(因此ActiveSupport::HashWithIndifferentAccess)。

根據具體情況,您可以在tmp上撥打to_s並讓其中的任何內容以這種方式轉換爲字符串。但是,如果只接受一個字符串或符號是有意義的,那麼引發一個TypeError是一件非常明智的事情。

您的輸入儘可能靈活,但對輸出嚴格要求通常是一個不錯的主意,並且適合友好的圖書館。

如果人們沒有閱讀警告,那麼當事情出錯時,這是他們自己的錯,而且你有權利傻笑並說「我已經告訴過你」。

+0

哦,我並不是說數組鍵,接受字符串和符號鍵是個好主意。問題出在哈希的值部分,如果我需要一個字符串並且有人傳遞了一個對象。當我期待的值是一個字符串時,to_s的想法聽起來像是我可能最終做的事情,但如果我需要的值是C側的double值,某個人傳遞了一個對象,那麼沒有明顯的方式來處理它。 – Camilo

+1

@Camilo:所以你的問題是與價值而不是關鍵?在這種情況下,如果您無法將值轉換爲您所需的值,那麼引發TypeError似乎是合理的。 –

相關問題