石橋秀仁です。こんばんは。

どうでもいい観念的な話です。
#得意分野(笑)

タイトル:
一行野郎と、Rubyのmethod chainの優位性についての考察


Hideto ISHIBASHI <hideto-i / rr.iij4u.or.jp> wrote:

> あるいは、同じ内容を一行野郎で、
>  ruby -r oracle -e 'Oracle.new("scott", "tiger").exec("select * from foo") { |r| print(r.join("\t"), "\n") }'
> と書けるのが僕にとっては嬉しい点です。

Rubyのmethod chainは「左から右に連鎖」します。
「左から右にコードをタイプ」するのと一致しています。
考えながら書ける。それが「自然なコーディング」や
「楽しさ/嬉しさ」という感覚につながっている気がします。
# Perlで同じことを書くと「右から左に連鎖」するからヤです。
# 例えば gets.chop.split("\t").each{|e| foo(e)} のような処理。


Rubyのmethod chainは、考える順に書くことができて、すごく自然です。
考えながら書く=考える道具として優秀だと思います。メソッドの動作を
確認するために、コマンドラインで一行野郎(one-liner)を書くときとか。


たとえば、一行野郎の
  'Oracle.new("scott", "tiger")
    .exec("select * from foo") { |r| print(r.join("\t"), "\n") }'
を書くときに、ぼくの頭の中では
  Oracle.new("scott", "tiger") で生成した Oracle オブジェクトに、
  メッセージ exec("select * from foo") を送って、
  ブロック { |r| print(r.join("\t"), "\n") } をコールバックしてもらう
とイメージしながら、同時に手を動かしています。


一行野郎で書けない場合は、どうなるかというと、
  'conn = Oracle.new("scott", "tiger");
    cur = conn.exec("select * from foo");
     cur.fetch { |r| print(r.join("\t"), "\n") }'
と書くことになります。このときのイメージは、
  Oracle.new("scott", "tiger") で生成した Oracle オブジェクトを
  conn に代入して、conn に exec("select * from foo") を送って
  生成された Oracle::Cursor オブジェクトを cur に代入して、
  cur に fetch を送ってブロック { |r| print(r.join("\t"), "\n") }
  をコールバックしてもらう
となります(僕の場合)。

イヤなのは、代入により思考がいったん「逆向き」になることです。
バックトラックというか。心の中のモノローグ:
  Oracle.newしたやつを何かに代入しよう。
  名前は・・・connでいいや。
  じゃ、代入文を書こうかな・・・
  って、カーソル左に戻さなきゃなんね〜(怒)
ってなかんじですね。だから途中で生成される個々のオブジェクト
について代入文を書くのは、とても苦痛です。

何度も書いた定型文なら、最初から代入文として書くかもしれません。
しかし、まず代入文を書くというのは、思考の順序として自然ではない
と思います。まず右辺に何らかの文があって、その結果を左辺に代入する
のですから、右辺が先で、左辺があとです。そもそも右辺が確定しなければ、
左辺に代入されるオブジェクトの型も分からないので、順序はあると思います。


仮に、最初から "conn = Oracle..." と書き始めて、
後戻りせずに全部書ききるためには、数手先まで
読んでいなければいけません。

これは、思考スピードとタイプスピードの不一致を起こすので、
勘違いやミスタイプの可能性が上がると思います(仮説)。
思考スピードが速ければよいかというと、そうではなくて、
思考とタイプのスピードが一致していないことは、
それだけで問題だと思います。
#仮説の前提:一行野郎なのでカーソルを右往左往させず一気に書きたい。
#まあbashをviモードで使えばあんまり苦じゃないような気も。

また、最初に全体の構成を考えるということは、
考えながら書くことができないということです。
気軽さが損なわれています。


結論:
method chainは考えながら書く一行野郎に最適

蛇足:
イテレータも簡潔に書くのに最高


試案:
  文の結果 → 代入する変数
のような構文があればよい?
  Oracle.new("scott", "tiger") -> conn
やっぱりきもちわる〜いですね (^^;;;


--
Hideto "rubyholic" ISHIBASHI  http://www.rr.iij4u.or.jp/~hideto-i/