-1

Can anyone offer some guidance on why this works:

self.primary_format == "Single" || self.primary_format == "EP"

But this doesn't

self.primary_format == "Single" || "EP"

Is there a more concise way of doing this?

I need to perform the following and would like to make it as neat as possible. Based on the above, i'm not confident the below will work properly.

self.release.primary_genre.id ==  3 || 6 || 8 || 12 || 18

Many thanks!

EDIT: I should have pointed out that these are part of an if statement.

Raoot
  • 1,751
  • 1
  • 25
  • 51

3 Answers3

1

In ruby nil and false are considered as Boolean false means your condition will get failed only if its value is either false or nil.

self.primary_format == "Single" || self.primary_format == "EP"

In above statement you are checking that primary_format should be either "Single" or 'EP' and if not it will get failed.

self.primary_format == "Single" || "EP"

In above statement you have two statements self.primary_format == "Single" and "EP" So your condition get passed when any of these is correct. But as per the ruby any object other than the nil and false is considered as true in Boolean statement.here in this case no matter what value of the self.primary_format the condition always returns true

So you have to use include? method of an array

[3, 6, 8, 12, 18].include?(self.release.primary_genre.id )
Salil
  • 46,566
  • 21
  • 122
  • 156
  • primary_format and primary_genre don't return an array, just a single value from the database that can be any of the values i'm trying to check for. This does seem to work on primary_format, but not for primary_genre though. – Raoot Sep 24 '12 at 12:48
  • i got that....i just explain your 1st statement only return true if `primary_format` is any on of the `"Single"`, `"EP"` but your 2nd statement always return true no matter what is the value of the `self.primary_format` – Salil Sep 24 '12 at 12:52
1

This is the normal semantic of ||. You are comparing self.primary_format to "Single". If it is different you are checking "EP" in a boolean way (if it is not nil and not false).

My preferred way to express what you mean is

["Single", "EP"].include? self.primary_format
[3, 6, 8, 12, 18].include? self.release.primary_genre.id

Instead of include? you can also use the equivalent member?.

If you want to write the condition in the more natural order, read the answers in Is there an inverse 'member?' method in ruby?.

Community
  • 1
  • 1
undur_gongor
  • 15,657
  • 5
  • 63
  • 75
1

Let's tear down the first example.

self.primary_format == "Single" || self.primary_format == "EP"

If you apply operator precedence and add parentheses, you get this:

(self.primary_format == "Single") || (self.primary_format == "EP")

Since #== is a method, you get this:

(self.primary_format.==("Single")) || (self.primary_format.==("EP"))

Let's fill in a value for self.primary_format. How about "EP".

("EP".==("Single")) || ("EP".==("EP"))

Call the #== method on both sides and you get

(false) || (true)

Since the left hand side is falsy, we return the right hand side:

true


Now let's tear down the second example.

self.primary_format == "Single" || "EP"

If you apply operator precedence and add parentheses, you get this, because == binds more tightly than ||:

(self.primary_format == "Single") || ("EP")

Once again, let's switch #== to its method call variant:

(self.primary_format.==("Single")) || "EP"

Let's fill in a "EP" for self.primary_format again.

("EP".==("Single")) || "EP")

Call the #== and you get

(false || "EP")

Since the left hand side of || is falsy, the right hand side is returned. So the value is:

"EP"

Which is itself truthy, because it is neither false nor nil.


So in summary, you need to think about how an operator like || or == groups together the expressions on its sides.

The first example says "If this value is equal to 'Single', tell me 'true'. If it's not, if it's equal to 'EP' tell me 'true', otherwise tell me 'false'"

The second example says "If this value is equal to 'Single', tell me 'true'. If it's not, tell me 'EP'".

I hope that helps!

Grant Hutchins
  • 4,275
  • 1
  • 27
  • 32