web-dev-qa-db-ja.com

Coffeescriptのステートメントが長い複合if文を適切にフォーマットする方法

単に審美的な目的でオーバーフローさせたくないという複雑なifステートメントがある場合、coffeescriptはこの場合のステートメントの本体としてリターンを解釈するため、それを分割する最もコーシャ的な方法は何でしょうか?

if (foo is bar.data.stuff and foo isnt bar.data.otherstuff) or (not foo and not bar)
  awesome sauce
else lame sauce
68
Evan

CoffeeScriptは、行が演算子で終わる場合、次の行をステートメントの本文として解釈しないため、これで問題ありません。

# OK!
if a and
not 
b
  c()

にコンパイルされます

if (a && !b) {
  c();
}

ifは次のようにフォーマットできます

# OK!
if (foo is 
bar.data.stuff and 
foo isnt bar.data.otherstuff) or 
(not foo and not bar)
  awesome sauce
else lame sauce

または、行がandまたはorまたはisまたは==またはnotなどで終わる限り、その他の改行スキームオペレーター

インデントに関しては、本文がさらにインデントされている限り、ifの最初以外の行をインデントできます。

# OK!
if (foo is 
  bar.data.stuff and 
  foo isnt bar.data.otherstuff) or 
  (not foo and not bar)
    awesome sauce
else lame sauce

あなたができないことはこれです:

# BAD
if (foo  #doesn't end on operator!
  is bar.data.stuff and 
  foo isnt bar.data.otherstuff) or 
  (not foo and not bar)
    awesome sauce
else lame sauce
86
nicolaskruchten

これにより、コードの意味が多少変わりますが、いくつかの用途があります。

return lame sauce unless foo and bar
if foo is bar.data.stuff isnt bar.data.otherstuff
  awesome sauce
else
  lame sauce

CoffeeScriptでis...isntが合法であるように、a < b < cチェーンは合法であることに注意してください。もちろん、lame sauceの繰り返しは残念であり、すぐにreturnにしたくないかもしれません。別のアプローチは、ソークを使用して書くことです

data = bar?.data
if foo and foo is data?.stuff isnt data?.otherstuff
  awesome sauce
else
  lame sauce

if foo andは少し洗練されていません。 fooundefinedである可能性がない場合は、破棄できます。

3
Trevor Burnham

他の言語と同様に、そもそもそれらを持たないことによって。異なる部分に名前を付けて、別々に扱います。述語を宣言するか、いくつかのブール変数を作成するだけです。

bar.isBaz = -> @data.stuff != @data.otherstuff
bar.isAwsome = (foo) -> @isBaz() && @data.stuff == foo
if not bar? or bar.isAwesome foo
  awesome sauce
else lame sauce
2
John Nilsson

改行をエスケープすると、最も読みやすくなります。

if (foo is bar.data.stuff and foo isnt bar.data.otherstuff) \
or (not foo and not bar)
  awesome sauce
else lame sauce
2
Cees Timmerman

低レベルのボイラープレートが大量に発生する場合は、抽象レベルを上げるにする必要があります。

最適なソリューションは次のとおりです。

  • 適切な名前の変数と関数を使用する

  • if/elseステートメントの論理規則

論理ルールの1つは次のとおりです。

(AでもBでもない)== not(AまたはB)

最初の方法変数:

isStuff              = foo is bar.data.stuff
isntOtherStuff       = foo isnt bar.data.otherstuff
isStuffNotOtherStuff = isStuff and isntOtherStuff
bothFalse            = not (foo or bar)
if isStuffNotOtherStuff or bothFalse
  awesome sauce
else lame sauce

この方法の主な欠点は、速度が遅いことです。 andおよびor演算子機能を使用し、変数を関数に置き換えると、パフォーマンスが向上します。

  • C = AおよびB

Aがfalseの場合operator andwouldnt call

  • C = AまたはB

Aがtrueの場合operator orwouldnt call

2番目の方法。機能:

isStuff              = -> foo is bar.data.stuff
isntOtherStuff       = -> foo isnt bar.data.otherstuff
isStuffNotOtherStuff = -> do isStuff and do isntOtherStuff
bothFalse            = -> not (foo or bar)
if do isStuffNotOtherStuff or do bothFalse
  awesome sauce
else lame sauce
0
Nikita