Learning from io 2

Posted by Aaron Feng Thu, 25 Sep 2008 04:09:00 GMT

io is a small, prototype based, dynamic programming language that is inspired by Smalltalk, Self, NewtonScript, Act1, LISP, and Lua. Need I say more? It has a very useful feature that any programmer can appreciate: the "?"

It's very common to want to check the existence of an object before accessing it.

if offer != nil
  offer.price
end

or

offer && offer.price

It gets even more tedious when you also need to traverse a couple objects deep.

offer && offer.price && offer.price.formatted_amount

Littering the "check" around the code can quickly cloud up the intention of the code. In io, you can do the following:

offer ?price
offer ?price ?formatted_amount

No more checking! However, I want to do that in ruby. An obvious solution is to open up the nil class and re-implement the method_missing to return nil. This is a very bad idea, since it applies to ALL objects in the system. It can hide serious errors within the application and make debugging very difficult. A better solution is to the following:

class Object
  def _?()
    self
  end
end

class NilClass
  def _?()
    SafeNil.new
  end
end

class SafeNil
  def method_missing(*args, &b)
    nil.send(*args, &b) rescue nil
  end
end

The above code is taken from this post The post didn't mention io, but I assumed it is inspired by it. In ruby you can't just use the "?" for your method name, therefore, _ is prepended before "?".Now you can do following without checking the parent object:

offer._?.price._?.formatted_amount

if offer or price is nil, nil is returned.

Comments

Leave a response

  1. Jonathan Tran Thu, 25 Sep 2008 06:05:41 GMT

    So what you're saying is... you implemented the Maybe monad in Ruby.

  2. Leslie P. Polzer Thu, 25 Sep 2008 12:37:54 GMT

    In Common Lisp you could just add a method specialized on NIL (or write a macro that does this automatically).

    An alternative would be using the MOP for this.

Comments