I was going through the source code of Ryan Bates' gem called mustard when I stumbled upon this code:
module Mustard module ObjectExtension def must Must.new(self) end def must_not Must.new(self, true) end end end
true tells us nothing, we have to go the Must class definition to find out its responsibility:
module Mustard class Must def initialize(subject, negate = false) @subject = subject @negate = negate end end end
Ok, now we know it is used for negating.
We can improve the first piece of code by passing a speaking for itself symbol
:negate instead of just passing
Since symbols in Ruby are always true, passing
:negate is equialent to passing
true. But in case of
:negate, the intent is right in front of you, no need to jump to the method's definition.
There is one gotcha though - it won't work in cases where you directly compare your assigned variable to true/false. An example from the same gem:
def _assert(matcher) if @negate == !!matcher.match? message = @negate ? matcher.negative_failure_message : matcher.failure_message Mustard.fail(message) end end
@negate variable (which has a value of
:negate) is being compared directly to true/false. This code won't work as expected, because
:negate == true returns false. You only can use this trick if you do comparisons this way:
if @negate # ... end
Now that I'm thinking about it, maybe that's why the trick is not so popular :)
You're the 4047th person to read this article.