MaybeモナドっぽいRubyの書き方

Haskellを勉強しながら、ほとんどの機能はRubyでも似たようなことが出来るな、と感じている。
でも、無限リストや無限木構造の遅延評価とか、Rubyではできないこともやっぱりある。
これはうらやましい!と思った機能の一つに、Maybeモナドがある。

hogeにdo_itして、その結果にdo_thatして、さらにその結果にjust_do_itした結果、というのを

hoge >>= do_it >>= do_that >>= just_do_it

というように表せるのだが、このプロセスの途中で結果がNothing (nilみたいなもの)になる場合があっても、そんな場合をハンドリングするコードを加えないで、

hoge >>= do_it >>= do_that >>= just_do_it

のままでOK。なぜなら、プロセスの途中でNothingになった場合は、Nothingにその後どんな操作をしてもNothingというルールがあるので、結局、式全体の結果もNothingになるだけで、エラーにならない。これは書くのが楽だ。

Rubyでいうなら、

hoge.do_it.do_that.just_do_it

といった感じか。
でもRubyだと、途中でnilが返る可能性があるときは、nilのハンドリングを
無視するわけにはいかず、

(x=hoge.do_it).nil? ? nil : (y=x.do_that).nil? ? nil : y.just_do_it

とか、かっこわるいことになってしまう。
そこで、RubyでMaybeモナドっぽい書き方をする方法を考えてみた。

まず、どんなメソッドを呼ばれても、nilを返すオブジェクト"NULL"を用意する。

class NullClass
  def method_missing(message, *arg)
    nil
  end
end
NULL= NullClass.new

で、こうする。

((hoge.do_it || NULL).do_that || NULL).just_do_it

まあ完全にnilハンドリングが消えたとはいえないけど、だいぶましなんじゃないでしょうか?
このやりかたのいいところは、とりあえず何も考えずに、

hoge.do_it.do_that.just_do_it

といったコードを書いておいて、あとからnilハンドリングが必要なところを、
( ... || NULL)で括っていけばよい、ということです。

このワザで自分のコード中のメソッドをモノによっては半分程度に短くすることに成功しています。

P.S.
上のNULLの定義の代わりに、どんなメソッドを呼んでも自分自身(NULL)を返すオブジェクトというのも有用かも、
と思った。

class NullClass
  def method_missing(message, *arg)
    NULL
  end
end
NULL= NullClass.new

これの論理値評価をfalseに出来れば||と組み合わせて使えるのでかなり便利かも、と思ったけど、
nil, false以外のオブジェクトの論理値評価をfalseにする方法が調べた限り見つからなかった。

P.P.S
ぼんやり考えてる人から、

class NilClass
  def method_missing(message, *arg)
    nil
  end
end

で、

hoge.do_it.do_that.just_do_it

ってかけるよ、という指摘が。
ううーん、確かに。これはかなり強力なワザかも。