Ruby : Touching The Obj-C Void : nil is nil
Posted in News by CM8295.Com on the 2007-10-22
A long time ago, in Objective-C on the NeXT, one could often remove nil checks, because all messages to nil would immediately return nil (or 0 depending on the caller’s method signature).
How many times have we seen this in Ruby?:
def foo
bar && bar.baz && bar.baz.caz("x")
end
Or even worse, avoiding redundant execution?:
def foo
(temp = @bar) &&
(temp = temp.baz) &&
temp.caz("x")
end
In Objective-C this could be written as:
- foo {
return [[bar baz] caz: "x"];
}
So in Ruby:
class ::NilClass
def method_missing(*args)
nil
end
end
@bar = nil
def foo
@bar.baz.caz("x")
end
foo
# => nil
Assuming that most of the time bar is not nil, NilClass#method_missing => nil makes for cleaner code that also runs faster than checking for nil along the way.
An additional benefit is that nil can also be used as an immutable empty collection sink by defining NilClass#size => 0, NilClass#empty? => true, etc.
Obviously, it breaks code that expects exceptions to be thrown for messages to nil.
Introduce a method that explicitly checks for nil:
module ::Kernel
def not_nil; self; end
end
class ::NilClass
def not_nil; raise("not_nil failed"); end
end
@bar = nil
def foo
@bar.baz.caz("x").not_nil
end
foo
# => RuntimeError: not_nil failed
Comments?

Responses to “Ruby : Touching The Obj-C Void : nil is nil”