2010-12-30 11 views
5

を扱うには、おそらく既に尋ねたが、私はそれを見つけることができませんでした...ここ2一般的な状況です(私のためにしばらくのプログラミングレール...)Rubyで書くことがイライラしている:ルビー糖衣構文:NILS

"a string".match(/abc(.+)abc/)[1] 

この場合、文字列が一致しないためにエラーが発生するため、[]演算子はnilで呼び出されます。それは単に一致エラー

せずにnilを返さなかった場合は第2の状況はこの1つである、簡単で

temp="a string".match(/abc(.+)abc/); temp.nil? ? nil : temp[1] 

::私は何を見つけるしたいことは、次のよりよい代替案である

私はそれがnilでない場合にのみ、VARに何かを割り当てるこの場合
var = something.very.long.and.tedious.to.write 
var = something.other if var.nil? 

、私はsomething.otherを割り当てますnilをする場合には、それはだ...

任意の提案? ありがとう!最初の場合

+0

私は(はい、それは簡単なOR ..です)私はそれが愚かだった2番目の質問について謝罪非常に疲れている[OK]を、最初のものはしかし興味深いのまま.. – luca

+0

実は、第2のものも面白かった。私は簡単に間違っていました。なぜなら、「または」オペレータの優先順位を忘れていたからです。 'または'の誤用はかなり一般的な偽のパスであり、強調表示する価値があります。 –

+0

これはこの質問に非常によく似ています:http://stackoverflow.com/questions/4371716/looking-for-a-good-way-to-avoid-hash-conditionals-in-ruby/ – mpd

答えて

0

私はあなたがこれをしたい、二番目のを理解してわからないickmaybeandandに相当)

"a string".match(/abc(.+)abc/).maybe[1] 

をお勧めしますか?

var = something.very.long.and.tedious.to.write || something.other 
3

Ruby on Railsでは、どのオブジェクトでもtryメソッドを使用できます。 APIに従って:

通常のRuby Object#sendと同様に、シンボルメソッドで指定されたメソッドを呼び出し、指定された引数および/またはブロックを渡します。

ただし、このメソッドとは異なり、受信オブジェクトがnilオブジェクトまたはNilClassの場合は、NoMethodError例外が発生せず、代わりにnilが返されます。

"a string".match(/abc(.+)abc/).try(:[], 1) 

をそして、それはエラーなしであなたを[1]またはnilを与える次のいずれか

だから、最初の質問のためにあなたがこれを行うことができます。

+0

このコードは読みにくいですActiveSupportが存在する場合にのみ機能します。 –

+0

この質問はもともと、あなたがそれを修正する前にruby-on-railsでタグ付けされていたので、私はRuby on Railsに組み込まれた最もクリーンなソリューションを提示しました。そして読みにくい?ほとんどのRubyプログラマは、 "send"メソッドがどのように動作するかに慣れています。これは、外部Ickライブラリを使用して、受け入れられた答えよりも読みにくいです。あなたはあまりにもそれをdownvoteかもしれません、それは "Ickが存在する場合にのみ動作する"ためです。全体的に、不当なdownvote。 – icecream

+0

toklandの回答の後半が100%正しいことを考慮すると、それは不当なdownvoteになります。元の質問はタグ付きのルビー・オン・レールでしたが、その質問には何もレールとは関係ありません。不必要な依存関係は、Rubyのプログラマが最も不愉快な間違いの1つです。しかし、あなたの場合は、不要な依存関係を追加するだけではありません。あなたの実装では、不要で遅いsend-dispatchも導入されています。前述したように、読みにくいです。私は決してこのようなコードをコードレビューを通して生かすことはできません。そう、はい、下位投票。 –

0
"a string".match(/foo(bar)/).to_a[1] 

NilClass#to_a空の配列を返し、それ以外のインデックスはあなたにnil値を示します。

代わりに(私は何をすべきか)あなたが一致スプラットことができます。

_, some, more = "a string".match(/foo(bar)(jim)/).to_a 
+1

Ewww。しないでください。 –

+0

@BobAman詳細を教えていただけますか?どの部分に異議を唱えていますか?あなたが心配しているのがサブマッチである場合に、アンダースコア変数を使用して完全一致を黙って無視しますか?これは、誰も助けて "Ewww"と言って、捨て去り、遠ざかるのを助けます。 – Phrogz

+1

私は 'NilClass#to_a'メソッドと範囲外インデックスの使い方について言及しています。ダックタイピングが楽しいので、ここでは賢い方法です。賢い悪いです。とにかく、マッチをスプラットすると読みやすくなります。しかし、一度に複数のキャプチャグループを割り当てていた場合は、これだけを実行します。さもなければ 'String#[]'メソッドを使うべきです。 –

3
"a string"[/abc(.+)abc/, 1] 
# => nil 
"abc123abc"[/abc(.+)abc/, 1] 
# => "123" 

そして:

var = something.very.long.and.tedious.to.write || something.other 

or||||とは異なる演算子の優先順位があるべきであることに注意してください。この種の用途には好ましい。 or演算子は、ARGV[0] or abort('Missing parameter')などのフロー制御用です。

3

忘れてしまったのは、Python atavism!

"a string"[/abc(.+)abc/,1] # => nil 
+2

+1プログラミング関連の文脈で「atavism」という単語を使用する場合は+1。 – zetetic

+0

私が知っている 'match'の唯一の目的はhttp://stackoverflow.com/questions/4472848/is-there-a-shorthand-for-assigning-from-1-n-after-matching-in-ruby/4472857です#4472857 – Nakilon

+0

実際には、しばらく前に、 'match' /' captures'メソッドのペアでduck-typedのルーティング機構を書きました。これにより、ルーティングシステムにURIテンプレートマッチングを簡単に導入することができました。私は実際には、正規表現を実行するのに慣れない方法を用いることに多くの利点を見出しました。彼らは、あなたがメタプログラミングのコンテキストで、あるいはDSLを作成するときに書いたものになる傾向があります。 –

0

最初の質問では、ボブの答えは良いと思います。 2番目の質問については

var = something.very.long.and.tedious.to.write.instance_eval{nil? ? something.other : self} 
関連する問題