DataMapper が予想以上に賢すぎる

なんか DataMapper が予想以上に賢かったので紹介してみる。

$ merb -i
### IRB のエコーバックをオフにする
irb> %w[a]             # エコーバックされる
=> ["a"]
irb> IRB.conf[:MAIN_CONTEXT].echo = false
irb> %w[a]             # エコーバックされないことを確認

### すべての従業員オブジェクトを検索した時点では、
### まだ SQL は発行されない
irb> employees = Employee.all

### オブジェクトにアクセスしてから初めて SQL が発行される
irb> employees.each {|emp| p emp }
 ~ SELECT `id`, `name`, `department_id` FROM `employees` ORDER BY `id`
#<Employee id=1 name="Kathy" department_id=1>
#<Employee id=2 name="Mike" department_id=1>
#<Employee id=3 name="John" department_id=2>
#<Employee id=4 name="Bill" department_id=3>

### 関連するオブジェクトも、必要になった時点で初めて SQL が
### 自動的に発行される。あらかじめ取得されるわけではない。
irb> employees.each {|emp| p emp.department if false }   # 発行されない
irb> employees.each {|emp| p emp.department }            # 発行される
 ~ SELECT `id`, `name` FROM `departments` WHERE (`id` IN (3, 1, 2)) ORDER BY `id
#<Department id=1 name="Sales">
#<Department id=1 name="Sales">
#<Department id=2 name="Marketing">
#<Department id=3 name="Development">


Employee.all の時点ではまだ SQL は実行されないのか。知らんかったわ。
なんか思ってた以上に凝ったことをしていて驚いてるんだけど、きっと最近の O/R Mapper はこんな感じなんだろうな。詳しくは知らんけど、Python の SQLAlchemy とかそんな気がする。

なお IRBエコーバックを off にしとかないと、DataMapper の挙動が変わるので注意。

$ merb -i
### エコーバックが on のとき
irb> employees = Employee.all   # この時点で SQL が発行されたように見えるが…
 ~ SELECT `id`, `name`, `department_id` FROM `employees` ORDER BY `id`
=> [#<Employee id=1 name="Kathy" department_id=1>,
    #<Employee id=2 name="Mike" department_id=1>,
    #<Employee id=3 name="John" department_id=2>,
    #<Employee id=4 name="Bill" department_id=3>]

### エコーバックが off のとき
irb> IRB.conf[:MAIN_CONTEXT].echo = false
irb> employees = Employee.all   # 実はこの時点では SQL は発行されてなくて、
irb> employees.inspect          # inspect のせいで SQL が発行されただけ
 ~ SELECT `id`, `name`, `department_id` FROM `employees` ORDER BY `id`