Jewel-mmo開発日記

RubyでMMORPGを作る過程を記録する日記。 Yokohama.rb 発起人。
2007-07-28

[Bilbo]そこそこ動くようになった

職場の作業ログ、以前はtDiary、春まではBitChannelを改造して使っていた。 今回はいい機会なので自作ブログシステムのBilboを導入してみた。 もうだいたい動く状態だったんだけど、多少手を入れてまずまず使えるようになった。現在コアは81行だったかな。100行以内という縛りは守られている。

少しだけ手を入たけど、コアの実装はだいぶ安定している。

必要な機能のほとんどはプラグインによって実装するというコンセプト。ちっちゃくてシンプルなコアがあって、ほしい機能は自分でさくっと付け足す。例えばエントリの頭に日付を表示したければ次のようなプラグインを書く。

# showdate.rb
require 'date'
class Entry
  def date
    if m = /\A(\d\d\d\d)(\d\d)(\d\d)/.match(label)
      Date.new(m[1].to_i, m[2].to_i, m[3].to_i)
    end
  end
end

Plugin.add_hook(:before_entry) {|entry|
  %Q!<div class="date">#{ entry.date }</div>!
}

Entryは記事を抽象化したクラス。labelは記事の名前を示す"20070727"のような文字列。Plugin.add_hookはいくつかのエントリポイントにhtmlの断片を挿入する。

パーマリンクを追加する例。

# permalink.rb
class Controller
  def show
    @entry = Entry.find(params[:date], :limit => 1, :complete_label => true).first
    render(:show)
  end
end

Plugin.add_hook(:after_entry) {|entry|
  %Q!<span class="permalink">#{ link_to 'permalink', :action => :show, :date => entry.label }</span>!
}

コントローラにアクションをひとつのエントリを描画するshowアクションを追加しちゃう。 書き方がRailsに似てるけどRailsじゃないよ。cgi.rbで動かしているけどでもコアはcgi.rbに依存していない。

  • Entry.findはコアで定義しているメソッドで記事を返す
  • render(:show)はviews/show.rhtmlを呼び出す
  • link_toもRails風に定義したものを用意しているだけ

cgiに依存してないってのはこんなindex.cgiをコアとは別に用意して動かしてるから。

#!/usr/bin/env ruby
require 'cgi'

def params
  @params ||= CGI.new.params.keys.inject({}) {|t, k| t[k.to_sym] = CGI.new.params[k][0]; t }
end

def cgi_out
  CGI.new.out do
    begin
      yield
    rescue Exception
      $!.to_html
    end
  end
end

cgi_out do
  load './bilborc'
  setup_environment
  bilbo_context()
end

実装を小さくするのは設計とアイデアだなと思う。あと局所的なRubyのテクニックも必要かな。いくら時間をかけてもうまく出来るもんじゃない。集中してよく考えて、あとプリントアウトしたソースをいつも持ち歩いてペンで添削を繰り返す(A4用紙の印刷するのには100行がぴったり)。そんな中から設計のアイデアが生まれてくる。最近はもっぱらこんな開発スタイル。