Archive for September, 2014

The core of this problem is a lack of combinators. In order to propogate the reason why something is falsy, you need to add a lot of logic to each method, which noises up the code considerably.

So we start with a pseudo-falsy base class for all our possible “reasons”:

class WhyFalsy
# This is so you can convert to bool with !!
def !@
true
end
def blank?
true
end
end

Now we can make objects that represent particular reasons, like:

class NoConfirmedAt < WhyFalsy; end

And use them in conditionals with only a little syntax pain:

!!NoConfirmedAt.new ? "confirmed at" : "not"

Now that we have these objects, we can create methods that let us combine them without throwing away the information we care about:

class WhyFalsy
def or
yield
end
def and
self
end
end
class Object
def or
self
end
def and
yield
end
end
class FalseClass
def or
yield
end
def and
self
end
end
class NilClass
def or
yield
end
def and
self
end
end

The normal && and || operators cannot be overloaded, so we define our own very similar methods, which allow us to write code like this: