2015-10-27 37 views
4

我編碼在Ruby的一些地方,從一個方法調用給定的值foo輸出乾淨的方法,我想:紅寶石 - 如果truthy返回一個值,或執行任意代碼

  • 返回foo如果foo is truthy
  • 如果foo是僞造的,則記錄錯誤並返回默認值。

實現這個最簡單幼稚的方法可能是:

foo = procedure(input) 

if foo 
    foo 
else 
    log_error 
    default 
end 

但由於foo重複三次這種感覺過於冗長,而這種風格是非常必要的。

寫這個最乾淨,最習慣的方法是什麼?

(性能matters--我們假設foo在絕大多數情況下truthy。)

回答

5

靠着Ruby的Perl傳統:

foo = procedure(input) and return foo 
log_error 
default 
2

你可以寫,如果log_error返回真值

foo || log_error && default 

如果不是:

foo || (log_error; default) 
+2

'FOO ||的log_error;默認' - 將評估'foo || log_error;'作爲一個語句,'default'作爲另一個語句 - 這可能不是你的意圖。 –

+0

我沒有意識到你可以將Ruby語句組合在一起(帶圓括號),但它是完全合理的。 POLA再次奪冠!我想知道它與'begin'..''end'塊有什麼不同? – mwp

3

這是一個罕見的情況下Ruby的匿名塊實際上是有用的:

foo = procedure(input) || begin 
    log_error 
    default 
end 
+0

是的!爲了整個社區的緣故,我可以用最多的選票接受答案是最有意義的,但這正是我個人所期待的。我只是測試了一下,看起來你可以在沒有賦值的情況下編寫它。我不知道你可以在Ruby中做到這一點。出於好奇,是否可以用'{...}'而不是'begin ... end'來編寫匿名塊? –

+0

不,但您可以使用parens per @ Arsen的答案。 :-) – mwp

0

爲了完整起見(且因爲沒有人貼吧還)我會在一個答案加我原來的嘗試:

procedure(input) || proc { 
    log_error 
    default 
}.call 

我想不出任何理由超過@ MWP的答案用這個:

procedure(input) || begin 
    log_error 
    default 
end 

因爲抽的涉及創建Proc對象的開銷(性能和可讀性)。雖然一些快速基準測試顯示,在大多數情況下性能差異應該可以忽略不計,因爲除非procedure(input)是虛假的,否則Proc對象似乎不會創建。

0

所有的事情考慮,我會去:

foo = procedure(input) 
return foo if foo 
log_error 
default