Make a NullObject evaluate to falsy in Ruby

design-patterns, ruby

Solution

I think you have only halfway adopted that pattern, and have not correctly adopted its spirit. My understanding is that the very purpose of the pattern is to avoid `||`.

You should have some purpose for calling `current_user || redirect_out`, and that could be doing something with it, or getting some attribute of it. For example, suppose your code has:

(current_user || redirect_out).foo

When `current_user` is not an instance of `Null::User`, you wanted to call `foo` on it. In that case, what you should do is define `Null::User#foo` to be `redirect_out` (possibly followed by some more operations like `foo` on other classes).

class Null::User
  def foo; redirect_out ... end
end

and in place of `(current_user || redirect_out).foo`, you should just do

current_user.foo

When `current_user` is not a `Null::User` instance, it will call `foo`. When it is such instance, then the `redirect_out ...` routine will be called on it.

Problem

After implementing Null Object Pattern in a Rails application (also described in RubyTapas episode 112) I refactored out some code, but there's a syntax construct that seems to not work anymore. I used to write statements like `current_user || redirect_out`, where, if current_user was set it would return it, and if it was `nil` it redirects out, but now `current_user` may be an instance of `Null::User` and thus "truthy", and that snippet would never redirect out. I tried defining the `||` operator, but didn't work. Is there any way this syntax can still be used with null (but "truthy") objects?

Original source