setterの返り値

Ruby でコードを書くときにいつも迷うのが setter の返り値。
一般的には nil を返すみたいなのですが、
self を返したほうがよいような気もするのであって。
ちなみに、他の言語では、
JavaBeans では void、XPCOM では nsresult、Python でも一般的には None …なので、
やっぱり setter というのは返り値を返さないものらしい。
ちなみに、Haskell で setter を Monad として実装して遊んでる人もいるみたいですが、
(参考: http://d.hatena.ne.jp/everpeace/20080326)
まあ、それはおいといて。


でも僕は、setter は this とか self を返すほうが便利だと思うのです。


そもそも setter の式、即ち、

hoge.set("a")

という式を評価した「結果」には以下の2種類があるのです。

  • "a" が hoge において無事に set された
  • "a" が hoge において不幸にも set されなかった

で、一般的な nil を返すという方法では、

  • 成功: returns nil
  • 失敗: raises Exception

という方法でこの2種類の帰結を実装しているのですが、

sock.write(hoge.set("a").to_s)

というような表現ができなくて不便だと思うのです。
また、そもそも hoge.set("a") という式を評価した値が nil というのも
どうも納得のいかないものなのです。
だって、

nil.to_s

hoge.set("a").to_s

がレシーバ (この場合は to_s) にとっては等価であるというのは、
どうも僕には不自然に思えてならないのです。
hoge.set は nil とは違うやろ


とはいえ、その自然な感覚に忠実な

  • 成功: returns self
  • 失敗: returns nil

というシンプルな実装にも、
常に NullPointerException に頼ることになるため、
発生したエラーを区別することが不可能になるという欠点があるのです。


ということで、僕はこれらの折衷案、すなはち、

  • 成功: returns self
  • 失敗: raises Exception

これが最も便利だと思うのです。
これなら、レシーバに最も多くの情報を渡すことができ、また、
発生した Exception を追いかけることが可能になります。


結論から言えば、僕は Ruby という言語を全然理解できていないということなのです。
本当にどうして setter が nil を返すのだろうか。
そもそも、式を評価するという概念自体が間違っているのだろうか。
…よくわからない