2011-06-15 4 views
15

私は臭いの方法のように持っていますか?ルビー「リターンはゼロでない限り、」イディオム

return_unless_nil(&blk)の方法を書いてください。

(引数は、呼び出しごとに異なっているので、私は単純にそれらを反復処理することができないことに注意してください)

+0

「false」と記録することができますか、間違いなく実際のレコードかnilですか? –

+0

"または、私は' return_unless_nil(&blk) 'メソッドを書くべきですか?"それはそれを呼び出したメソッドから戻ってくるだろうか?私はそれが可能だとは思わない。 –

+0

私は自分のベルトの下で約10分間ルビーを学んでいますが、呼び出し側の価値を返す方法を書くにはどうすればいいでしょうか?潜在的な答えとして、私は非常に限定されたルビーの露出を与えて実際の答えとしてこれを置く不快感を感じる...あなたはルビーのようなことができますか?あなたがそれほど臭いがないかどうかわからない。 –

答えて

20

あなたはnil、ここfalseの違いを気にしますか?あなたはこのイディオムで慣れていない場合は

def search_record(*args)  
    expensive_operation_1(foo)  || 
    expensive_operation_2(foo, bar) || 
    expensive_operation_3(baz)  || 
    expensive_operation_4(foo, baz) 
end 

が、それは以下のようなものを説明することができます:あなたが唯一の各メソッドの戻り値があるかどうかを気にしている場合、「falsy、」これはそれを行うのはかなりRubyish方法があるルビーほとんどの言語のように、"short circuits" OR比較の場合、第1オペランドが "truey"と評価された場合、第2オペランドを評価することはありません(つまりnilまたはfalse以外が返された場合、expensive_operation_2はコールされません)これはブール演算の結果が真であることを既に知っているからです。

Rubyが行うもう1つの便利なことは、ブール演算からtrueまたはfalseを返す代わりに、評価する最後のオペランドを返します。この場合、expensive_operation_1nilを返した場合は、expensive_operation_2が呼び出され、値が返された場合(偽でない場合)、式全体がその値に評価されます。

最後に、これらのブール値をチェーンすることができます。結果的に、最初のオペランドの結果が返され、後続のオペランドは評価されません。 すべてのオペランドのがfalsyと評価された場合、それは最終オペランドを返します(私たちが知っているのは、falsyであり、おそらくnilです)。

+0

ヨルダンの簡潔な回答を展開する:ブール演算子の短絡(右側が必要ない場合は左辺のみを評価)を行い、演算子を満たす値を返します。 – Chuck

+0

チャックに感謝します。あなたがコメントしたとき私は私の答えを広げて忙しかった。 :) –

+0

警告は "あなたは無と偽の違いについて気にしていますか"というのは本当に重要です。これらの関数のいずれかがブール値を返す場合、このコードは実行しません。残念ながら、OPはAWOLになった。 – tokland

2

ヨルダンの答えを補う:これらの関数がブール値を返すとは考えられますが(とにかく検索機能はありません)、||は機能しません。 here

expensive_operation_1(foo).or_if(:nil?) do 
    expensive_operation_2(foo).or_if(:nil?) do 
    expensive_operation_3(foo).or_if(:nil?) do 
     expensive_operation_4(foo) 
    end 
    end 
end 
+0

Object#or_ifは、心に留めておくべき面白いイディオムです。ありがとう! – pithyless