Unless you are new to the world of ruby you're probably familiar with unless
. It's the inverse of if
. The code is executed when the condition is not true.
cry unless happy?
Is equivalent to
cry if !happy?
This is a preferred usage where I work as well as in the Ruby Style Guide.
I like to disagree.
My main issue with it is that I always have to negate the condition in my head. If the condition has multiple parts the cognitive load is even higher.
There is literally no benefit to it. The only argument I've heard so far in favour of unless, is that it makes the code more readable. Maybe, but the code needs to be understandable, if readability is at the expense of understandability, that is a bad thing.
Also there is a very easy way to remove the exclamation mark. Define a negated method:
def sad?
!happy?
end
Or we can do some meta programming:
module Negator
def negate(method_name, negated = nil)
negated_name = negated || "not_" + method_name.to_s
define_method(negated_name) { !send(method_name) }
end
end
With this we can set up a negated method with either the default name being a not_
prefix to the positive method name, or a custom one.
Let's set up a simple class to test it.
class Mood
extend Negator
attr_reader :happy
negate :happy, :sad
def initialize(happy: true)
@happy = happy
end
def sing
puts 'Don\'t worry, be happy' if happy?
end
def cry
puts 'cry a lot' if sad?
end
end
We got a Mood class with a happy boolean argument and 2 public methods, singing when happy, and crying when sad using the negate method.
3.0.0 :114 > mood = Mood.new(happy: false)
=> #<Mood:0x00007fd01314deb8 @happy=false>
3.0.0 :116 > mood.cry
cry a lot
So we went from using
def cry
puts 'cry a lot' unless happy?
end
to
def cry
puts 'cry a lot' if sad?
end
Have a great day and don't forget to be awesome!