def has_query? self.param_search_query && self.param_search_query != "Eventname" end
I found this in some code I was working on today. This is a pretty standard “predicate method”, which, by convention, should always return either true or false. Strangely, as I was exploring the code with Pry, I noticed the method return nil.
It turned out that param_search_query was actually nil, which, when mixed with the logical AND (&&) operator returns something the author clearly did not expect:
mike@sleepycat:~☺ irb irb(main):001:> nil && true => nil
This was actually surprising to me too. I would have thought that nil would have been falsey and that the expression would return false. Definitely something I am going to remember next time I am using the && operator.
So the next question is, what to do about it.
One way to ensure a boolean return value that I have seen is to use the bang operator twice. This works because !nil is true and !!nil is false:
irb(main):003:0> !!nil => false
So we could use that to fix the method like so:
def has_query? !!(self.param_search_query && self.param_search_query != "Eventname") end
I’m not a fan of this because I think it obscures the intention of the author.
In the end, since this was in a Rails app I went with the present? method:
def has_query? self.param_search_query.present? && self.param_search_query != "Eventname" end
The tests pass and I’m back to hunting bigger game…