Skip to content

Comment on If you gaze into nil, nil gazes also into youparent

Comments

In Ruby nil can receive any method and return nil:

  class NilClass; def method_missing(*args); nil; end; end
The problem? It makes code fail late and siltently, which can happen with a simple mispeling of key names on hashes.

In ruby, Andand allows you to solve this more locally: http://andand.rubyforge.org/

andand doesn't seem any different than using try(:method), which is defined in Rails 2.3+ for the Object class:

  > nil.try(:name)                     #==> nil
  > User.first.try(:name)              #==>"john doe"
  > nil.try(:name).try(:upcase)        #==> nil
  > User.first.try(:name).try(:upcase) #==>"JOHN DOE"

It's a question of taste. Some people's taste works like this: If it's in Rails, it must be the right thing to use. Other people's taste works like this: #try is simpler than #andand, and simpler is better. Others prefer andand's more natural syntax regardless.

For example, I prefer #andand's syntax for methods with parameters:

  User.first.andand.max_attempts = 5
  Phone.first.andand.dial(last_number)
#andand handles methods with blocks:
  Supervisor.first.andand.oversee do
    ...
  End
foo.andand.into { ... } is a common pattern, so #andand bakes it in:
  Student.where( ... ).first.andand { |valedictorian| ... }
For some strange reason, I feel like I've been using it longer than anybody alive on the planet.

Thanks for pointing out the try method (it is important to note that it is avaible to anyone using Active Support, not only Rails apps).

It is mildly different (syntax mostly). All of these are attempts to recreate the elvis operator tha Groovy[1] (nowadays present as the The Existential Operator in Coffescript[2]) have.

For better chaining, the Maybe monad can be implemented in Ruby[3]. However they really shine on Haskell and Scala because they have, respectively, do notation and for comprehensions, which effectively work (on this restricted case of handling nulls) as a scope were nulls are ignored.

Doing this with ruby is possible, but requires AST metaprogramming[4], which is the sort of thing that LISP macros do (and is quite suitable to accomplish in LISP[6], as it is homoiconic[5], while Ruby isn't).

[1] http://groovy.codehaus.org/Operators#Operators-ElvisOperator...

[2] http://jashkenas.github.com/coffee-script/#operators

[3] http://pretheory.wordpress.com/2008/02/14/the-maybe-monad-in...

[4] http://metaphysicaldeveloper.wordpress.com/2010/10/31/rubyun...

[5] http://en.wikipedia.org/wiki/Homoiconicity

[6] http://onclojure.com/2009/03/06/a-monad-tutorial-for-clojure...

Thanks for the links. Some ruby food for thought . . .

  > x = nil || 5                   #behaviorally equivalent to elvis?
  > [nil,4,3].compact.map(&:to_s)  #null-ignored scope

You are welcome. The second line is the essential notion of Maybe monad as a restriction of the Sequence monad (Some of x works like [x] and None works like [], using ruby's [] notation for lists).

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.