Cumulo Nimbus
Cumulo Nimbus

Reputation: 9685

Coffeescript Unexpected Conditional Evaluation

.js.coffee:

code = "mw"
console.log code == "mw"                     # true
console.log code == ("ac" || "mw" || "ga")   # false
if code == ("ac" || "mw")
  console.log "inside if"                    # never reached

Why am I not making inside the if?

Upvotes: 0

Views: 58

Answers (2)

mu is too short
mu is too short

Reputation: 434615

CoffeeScript's || is JavaScript's || and from the fine manual for ||:

expr1 || expr2
Returns expr1 if it can be converted to true; otherwise, returns expr2.

So expr1 || expr2 evaluates to the first truthy value (from left to right) in the overall expression. A non-empty string is truthy so this:

("ac" || "mw")

is just a complicated way to say:

"ac"

and this:

if code == ("ac" || "mw")

is equivalent to:

if code == "ac"

and since you assign code = "mw", you're saying:

if "mw" == "ac"

and your console.log will never be executed because "mw" and "ac" are not equal.


In your answer you say that the solution is to say:

if code == "ac" || "mw"

but == has higher precedence than || so you're really saying:

if (code == "ac") || ("mw")

and that will always be true because:

  1. If code == 'ac' then it is true.
  2. Otherwise the expression evaluates to 'mw' and non-empty strings are also true.

If you want to say:

code is either "mw" or "ac"

then say exactly that:

if code == "mw" || code == "ac"

If you have several codes to check then you could use an array to hold the codes you're looking for and indexOf (or includes depending on what JavaScript versions you care about):

codes = [ 'mw', 'ac', ... ]
if codes.indexOf(code)
  #...

# or the CoffeeScripty version, `in` is an `indexOf` call in disguise
codes = [ 'mw', 'ac', ... ]
if code in codes
  #...

If there are a lot of values and you think an linear array search will be too slow then you could use an object to hold the values (as in the comment on your question):

codes = { mw: true, ac: true, ... }
if codes[code]
  # ...

Upvotes: 2

Bwaxxlo
Bwaxxlo

Reputation: 1880

This is the section to look at

if code == ("ac" || "mw")
  console.log "inside if"

It evaluates to if code == "ac" //this is false so it doesn't print anything

Upvotes: 1

Related Questions