kなんとかの日記 このページをアンテナに追加

2008-12-24

速報: Merb と Rails が統合

| 11:01 |  速報: Merb と Rails が統合 - kなんとかの日記 を含むブックマーク

悪い冗談としか思えないんだけど、MerbRails が統合されるらしい。


実は 1 週間前に、DHH が Merb の信者にうんざりさせられているという話があったんだけど、あれはみんなを騙すための fake だったのか。やられたぜ。


詳細は追って連絡する。


追記: だいぶ事情が分かってきた。簡単に言えば、Rails 3 は Merb を吸収するということ。

  • Rails 3 == Merb 2。Rails 3 では、Merb の機能や特徴を大幅に取り入れる。
    • Rails core team に Yehuda Katz (Merb lead developer) が参加。
    • Rails 3 は Rack ベースになるだろう。Rack の重要性がますます高まる。
    • Rails 2 との互換性は一部失われることになるみたい。
  • component stack を自分で選択できるようになる。
  • 高速になる。
  • API が定義される。
    • 今までの Rails だと、API が固定されてないため、Railsバージョンアップすると plug-in が動作しなくなることがあった。Merb は使用可能な API が定義されているため、このような問題がなくなる。
    • まあ MerbRails とで同じ plug-in が使えるということだな。
  • リリース予定
    • Rails 2.3 は来年 1 月。そのあと DHH は Rails 3 に本格的に取りかかる。
    • Merb はしばらく bug fix release を続け、Rails 3 が見えてきたら徐々に移行できるようにする。
    • Rails 3 == Merb 2 の beta release は、RailsConf 2009 (2009 年 5 月 4〜7 日) が目標。
  • その他
    • MerbMRI 以外の Ruby 実装で動かすことにも力を入れているので、Rails 3 は JRuby や Rubinius でも動くようになるだろう。
    • RailsMerb では view helper とかが違うんだけど、これも merb-helpers と rails-helpers を選択して使えるようにするんじゃないかな。'<% end =%>' の運命やいかに?
    • ActiveRecord を DataObjects ベースにしてくんないかな。
    • 最大の懸念は ActiveSupport vs. Extlib なんだけど、どうなるんだろう。

個人的には、なんか Python の歴史をなぞっているとしか思えん。


こうなったら、あとは framework 全体で Session の共通化をしてほしいな。Rails の session 情報が Ramaze とか Sinatra でも読めるようになってほしい。

→ Session 部分を Rack middleware に切り出すことも検討中らしい。


追記2: ここにも詳しい情報があります。

MerbはRails3にマージされる事になった (Hello, world! - s21g)


追記3: merb-book ML で、誰もが一部の人にはたいへん気になる質問が出てしまいました。

But the point here is: should we continue to write/translate that book?

Google グループ

ほんと、どうすんだろね。


追記4: 冒頭のリンクに Katz と Ezra を追加、また人物の説明書きを追加。記事もちょっとだけ追加。


追記5: Merb 界隈は混乱中。技術的な問題もさることながら、Rails に merge されると肥大化するのは目に見えているので、small & compact な framework を求めていた人からは否定的な声も (←全力で同意)。また Mack framework の作者のように寡占化を心配する意見も出ている。ただ、全体的には歓迎ムードのよう。

でも、DHH はよく決断したよなー。こんなの、なかなかできることじゃないよ。


追記6: DHH のブログエントリがこちらで日本語に翻訳されていますGJ です。Katz のブログも翻訳してくださるそうなので、期待して待ちましょう。

ところでこれを機に DHH は Rails から黒魔術をなくしてくれるんでしょうか。「黒魔術を使わない」というのは Merb の大きな利点なので、DHH が改心してくれることを望みます。Symbol#to_proc なんかウンコ。

lchinlchin 2008/12/25 11:20 一週間前にもこのニュースの予兆があったけど、気づいた人がほとんどいない:Ezraがこうコメントした:「patch -p0 rails-3.0 < merb-core.patch; done, there no more merb vs rails problems」
http://twitter.com/ezmobius/status/1059391701

kwatchkwatch 2008/12/25 20:07 その一週間前はまさにDHHがMerb信者に困ってるという話題がでた時なんですよね。それがこれですもん。こんなの、誰も気づかないですよねー。

2008-12-17

Merb 1.0.6.1 リリース

| 02:12 |  Merb 1.0.6.1 リリース - kなんとかの日記 を含むブックマーク

Merb 1.0.6.1 がリリースされました。1.0.5 が出て、すぐに 1.0.6 が出て、さらに 1.0.6.1 が出たそうです。

2008-12-16

MerbDay の動画

| 01:02 |  MerbDay の動画 - kなんとかの日記 を含むブックマーク

MerbDay というイベントが先日アトランタであったらしい。その動画が公開されてる。なんかやたら解像度が高くて、プレゼン画面の文字がクッキリハッキリみえる。どうしてこんなに解像度が高いのだろうか。

ちなみに、動画のリスト。

  • Keynote (by Yehuda Katz, Merb lead developer)
  • Merb Slices (by Mark Percival)
  • Hey, it's HAML! (by John Schult)
  • Merb Router (by Bryan Ray)
  • CouchDB (by Adam Dill & Hosh Hsiao)

なおテンプレートオタクとしては、HAML は嫌いだといっておこう。


Extlib は DataMapper 由来

| 01:02 |  Extlib は DataMapper 由来 - kなんとかの日記 を含むブックマーク

しかしながら、extlib という名前は一般的すぎていささか池沼な香りがするし、せめて merb-extlib にして欲しいと思うのが人情であるが、実際は両方の gem が存在する。なるほど、いよいよ自分の愚かさに気付いて、extlib -> merb-extlib に変名したのかと思いきや、その逆の変遷を辿っているのが現実である。どうやら、merb 用の拡張ライブラリとして作っていたが、かなり汎用的なので名前も汎用的にしてみました、という流れのようだ。

404 Not Found

Extlib はもともと DataMapper と Merb とで共通するクラスをくくりだしたもののはず。DataMapper でも Merb でも、単数系と複数形の相互変換といった機能が必要なので、じゃあ共通化するかね? という話がついて、Extlib は誕生したんだったと思う。ソースは自分の記憶。

ちなみに extlib@github では『General Ruby extensions for DataMapper and DataObjects』と説明されているし、Extlib がリリースされるときはだいたい DataMapper と一緒にリリースされる。なので、Extlib は Merb 由来ではなく DataMapper 由来と考えていいだろう。

まあ『名前は一般的すぎ』るというのは同意。つーか、Extlib は C で書かれてるんだと最近までずっと信じてた。紛らわしい名前だよな。

2008-12-15

DataMapper で「Unknown column 'XXX_id' in 'field list'」というエラーが出たとき

| 00:30 |  DataMapper で「Unknown column 'XXX_id' in 'field list'」というエラーが出たとき - kなんとかの日記 を含むブックマーク

たとえば Book : Author が Many to Many の関係だったとする。このとき「Book.first.authors」を実行すると、「Unknown column 'author_id' in 'field list'」というエラーが出た。

$ merb -i
irb>  Book.first.authors
 ~ SELECT `id`, `title`, `author_id` FROM `books` ORDER BY `id` LIMIT 1
 ~ Unknown column 'author_id' in 'field list' (mysql_error_code=0001)
 ....

で、この原因がさっぱり分からず苦労したんだけど、何のことはない、Author クラスの定義で「:through=>:writing」を「:thorugh=>:writing」のように typo していただけだった。

class Author
  include DataMapper::Resource
  property :id,   Serial
  property :name, String, :nullable => false
  has n, :writings
  has n, :books, :thorugh => :writings  # 正しくは :through
end

これが、「Book.first.authors」ではなく「Author.first.books」だと、「ArgumentError: Unknown property 'thorugh'」というエラーメッセージがでるので、わかりやすい。

irb> Author.first.books  
 ~ SELECT `id`, `name` FROM `authors` ORDER BY `id` LIMIT 1
ArgumentError: Unknown property 'thorugh'
        from /usr/local/lib/ruby/gems/1.8/gems/dm-core-0.9.7/lib/dm-core/query.rb:414:in `append_condition'
  ...

というわけで、DataMapper で「Unknown column 'XXX_id' in 'field list'」というエラーが出た人は、association の定義をチェックしてみるといいと思うよ。

2008-12-14

DataMapper での 1+N 問題

| 22:07 |  DataMapper での 1+N 問題 - kなんとかの日記 を含むブックマーク

DataMapper では、いわゆる 1+N 問題は起こらないと言われている。

たとえば次のような例。ActiveRecord なら 1+N コの SELECT 文が発行されるけど、DataMapper では 1+1 コの SELECT 文だけを発行する。

$ merb -i
irb> IRB.conf[:MAIN_CONTEXT].echo = false   # エコーバックを切る
irb> employees = Employee.all
irb> employees.each {|emp| p emp.department }   # 1+1 コの SQL 文
 ~ SELECT `id`, `name`, `department_id` FROM `employees` ORDER BY `id`
 ~ 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">

これは belongs_to の場合だけど、has n の場合も同じように 1+N を避けて 1+1 に動作する。

$ merb -i
irb> IRB.conf[:MAIN_CONTEXT].echo = false   # エコーバックを切る
irb> departments = Department.all
irb> departments.each {|dept| p dept.employees }   # 1+1 コの SQL 文
 ~ SELECT `id`, `name` FROM `departments` ORDER BY `id`
 ~ SELECT `id`, `name`, `department_id` FROM `employees` WHERE (`department_id` IN (1, 3, 2)) 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>]

ただ、many to many にはうまくいかなくて、1+N コの SQL が発行されてしまう。

irb> authors = Author.all
irb> authors.each {|author| p author.books }
>> authors.each {|author| p author.books }
 ~ SELECT `id`, `name` FROM `authors` ORDER BY `id`   # 1+N コの SQL 文
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 1) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=1 title="Merb in Action">]
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 2) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=1 title="Merb in Action">]
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 3) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=1 title="Merb in Action">]
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 4) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=2 title="Beginning Merb">]
 ~ SELECT `books`.`id`, `books`.`title` FROM `books` INNER JOIN `writings` ON (`books`.`id` = `writings`.`book_id`) WHERE (`writings`.`author_id` = 5) GROUP BY `books`.`id`, `books`.`title` ORDER BY `books`.`id`
[#<Book id=2 title="Beginning Merb">]

現在の DataMapper では、これが限界。一応ここの改善も ToDo リストには入っているらしんだけど、対応されるのはずいぶん先になりそう。

問題は、これの回避策がないってことなんだよな。Author#books= とか Book#authors= とかが使えればいいんだけど、少なくとも DataMapper 0.9.8 では使えない。

irb> book1.authors = [author1, author2]
DataMapper::Associations::ImmutableAssociationError: You can not modify this association
        from /usr/local/lib/ruby/gems/1.8/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb:255:in `assert_mutable'
        from /usr/local/lib/ruby/gems/1.8/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb:117:in `replace'
        from /usr/local/lib/ruby/gems/1.8/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb:21:in `authors='
        from (irb):32
        from :0

Many to many での、いい解決方法があれば教えてください。