大河ドラマの篤姫
もともと篤姫役の宮崎あおいが好きで見たいたんだけど、 途中から宮崎あおい演じる篤姫が良くなった。
ここ数話は高橋英樹、松坂慶子とのからみが中心だった。 ベテラン俳優に触発され何かが変わったのかそうでないのかわからないけど、面白くなった。
[プラポケ]第一回イベント終了のお知らせ
プラポケのステージ11のポイントの集計が終わりました。
入賞者は次の通りです。
- jowcol(土) …… Amazonギフト券5000円プレゼント
- testman(風) …… Amazonギフト券2000円プレゼント
- moriq(土) …… Amazonギフト券500円プレゼント
おめでとうございます。 参加してくださった皆様どうもありがとうございました。
次回のイベント開催を予定しています。次回はステージ14がイベントステージになる予定です。
- ステージ12 …… 20日間
- ステージ13 …… 20日間
- ステージ14 …… 20日間
上記スケジュールは暫定なので変更される予定があります。
[Bilbo]ぼちぼちやりたいと思っていること
- tDiaryからコメントデータをインポート
- コメントスパムのフィルタリング機構を作る
- コメント用RSSはなぜ更新してないやつまでLDRに上がってくるんだろう
- CodeReposにBilboをリリース
[Bilbo]BilboのMVC
http://mt.endeworks.jp/d-6/2008/03/db-1.html
BilboはDBを使わないけどMVCで実装している。
良い機会なのでBilboの超シンプルなMVCの実装を紹介。 このMVCを実現してるコア(bilbo.rb)は81行。
モデル
日記の記事はモデルとして管理される。具体的にはEntryクラスが記事を扱うモデルである。
entries = Entry.find('200803', :limit => 5)
こんな風にすると2008年3月の記事オブジェクトを5個取り出すことができる。
このEntryクラスの実装は30行。 この30行には、記事をHTMLに変換するコンパイラの登録と変換処理も含まれている。 このEntryクラスはBilboにとって最大の機構。30行なんて長すぎるのでコードは省略。
記事オブジェクトは次のようにしてHTML化できる。
entries.first.to_html
原稿のコンパイラは設定ファイル(bilborc)で指定する。 次のコードはHikiDocを登録する例。
require 'misc/hikidoc.rb' Entry.add_compiler('.txt') {|entry| HikiDoc.to_html(entry.body, :level => 2) }
拡張子「.txt」の原稿をHikiDocでHTML化する。
ビュー
ビューはいたってシンプル。4行で実装されている。
def render_view(name, b = binding) erb = Plugin.views[name] || (chdir(:views) { File.read("#{name}.html.erb") }) ERB.new(erb).result(b) rescue "<h3>ViewError in #{h name}</h3>#{h $!}<pre>#{$@.join("\n")}</pre>" end
HTMLテンプレートをERBにてレンダリング。
コントローラ
これも短いので、コードを全行貼ってしまったほうが話が早い。
class Controller def list @entries = Entry.find(params[:date] || '20', :limit => (params[:limit] || config[:limit] || 5).to_i, :page => (params[:page] || 0).to_i) render(:list) end def render(action) render_view(:layout) { render_view(action) } end end
デフォルトのアクションとしてlistを定義してあって、あと基本描画にレイアウトファイル(layout.html.erb)にアクション用のテンプレートを埋め込む。
そしてこのコントローラを呼び出すのが以下の部分。 CGIから渡されたactionパラメータをもとにControllerクラスに定義されているメソッドを呼び出す。
def default_action :list end def action_name # support: ruby 1.8 and 1.9 action = (params[:action] || params.index(nil) || 'list').to_sym Controller.instance_methods(false).map(&:to_sym).include?(action) ? action : default_action end def bilbo_context Plugin.load Controller.new.__send__(action_name) end
プラグインの中でControllerクラスのインスタンスメソッドを定義してやれば、 それがアクションとしてすぐに呼び出せてしまう。 よってプラグインによる機能追加かがとっても容易。
Star Rubyを使ってみる
フォントとテクスチャーを表示してみる。APIがいい感じだ。 Rubyを知っている人間にとってはMyGameより使いやすい。
Colorの生成は、Color[255, 255, 255]と書けないのかな。
require "starruby" include StarRuby font = Font.new("fonts/ORANGEKI", 12) white = Color.new(255, 255, 255) texture = Texture.load("images/star") Game.title = "Hello, World!" angle = 0 Game.run(320, 240) do Game.terminate if Input.keys(:keyboard).include?(:escape) Game.screen.clear Game.screen.render_text("Hello, World!", 8, 8, font, white) Game.screen.render_texture(texture, 100, 100, :alpha => 200, :angle => (angle += 4) / 180.0 * Math::PI, :center_x => 8, :center_y => 8, :scale_x => 8.0, :scale_y => 8.0) end
starruby-0.1.16-win32.zipのインストーラでこける
http://code.google.com/p/starruby/downloads/list
...\starruby-0.1.16-win32>ruby install.rb install.rb:14: syntax error, unexpected kDO, expecting $end Dir["dll/*.dll"] do |path| ^
>ruby -v ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
[Bilbo]コメントオン
Bilboでテスト運用中の本ブログにコメントプラグインを投入。 まだ実験段階なので、不都合があると消すことがあるかも。 スパムに対しても何の対策もしてないので、スパムが大量に来た場合も一括削除しちゃうかも。
スパム対策はスパムが来てから考える。
あと、RSSでコメントを配信するようにしてる。本文とまぜちゃうとスパムが来たときに問題がありそうなので、コメント用に専用のRSSを用意してみた。
http://dgames.jp/dan/?rss_comments
必要な機能をさくっとプラグインで簡単に追加できるというのが夢だったのだけど、いまのところうまくいっている。 今回コメントのRSS配信用に追加したコードは以下。
class Controller def rss_comments generate_rss(Comment.find('20*'), :title => "Comments - #{config[:title]}") end end class Comment def rss_description(n = 128) body[0, n] end def rss_tile name end def date Date.parse(@filename.to_s[/\A\d{8}/]) end end Plugin.add_hook(:header) { %Q!<link rel="alternate" type="application/rss+xml" title="RSS" href="?rss_comments">! }
[Bilbo]記事タイトルをページタイトルに付加する
permalinkアクションで記事タイトルをグローバル変数に保存し、フック処理から呼び出す。
$permalink_title = nil class Controller def permalink @entry = Entry.find(params[:date], :limit => 1, :complete_label => true).first $permalink_title = @entry.title render(:entry) end end Plugin.add_hook(:before_header) { if $permalink_title "<head><title>#{$permalink_title} - #{config[:title]}</title></head>" end }
うーん、グローバル変数を使わずに、アクションメソッド内の変数をフック処理に渡せないものか……。
あ、これでいいのか。
class Controller def permalink @entry = Entry.find(params[:date], :limit => 1, :complete_label => true).first Plugin.add_hook(:before_header) { "<head><title>#{@entry.title} - #{config[:title]}</title></head>" } render(:entry) end end
[Bilbo]後方互換と前方互換
BilboはtDiaryスタイルのURLに対する後方互換性をサポートする。
- tDiary …… http://dgames.jp/dan/?date=20080123#p01
- Bilbo …… http://dgames.jp/dan/?permalink&date=20080123
2008年1月23日の1つ目のエントリのURLは上のようになる。 BilboはtDiaryスタイルのURLも受け付けるけど、正式なパーマリンクはtDiaryとは異なる。 Bilboは同日に複数のエントリが合った場合、それぞれのエントリを個別に管理する。 だからコメントも日付単位じゃなくて個別のエントリに対して付けることができる。
で、当然なんだけどtDiaryはBilboに対する前方互換性がない。 本サイトでBilboのテストをしているわだが、すでにBilboスタイルのパーマリンクに対して外のサイトがリンクしていて、 tDiaryに戻すと問題が発生することに気がついた。 まあたぶん戻さずに済みそうだけど。
仕事は1日3時間
http://q.hatena.ne.jp/1203667934
自分の場合、自分が1日に働ける時間が3時間しかないことに気づいたのが大きかったかな。 90分を2本。これが限界。これよりあとは仕事をしてる気分になるだけで仕事はあまり進まない。 集中力よりも単に時間をかけることが重要なときもあるので、これはあくまで個人作業を理想状態でできるときの話しだけど。
自分にとってのポイントは2つあって、ひとつは集中できる状態でしかコードを書かないようにすること。 集中力の切れた状態でコードを書くとバグがバグを呼ぶようなひどい状態になる。 半日悩んだ問題が、翌日冷静に考えてみれば、根本的に不要な作業だったりとか。 これは勝手にいらん仕事作って勝手にはまってる状態。 最高の集中状態でしかコードを書かないこと。 質の低いコードをプロジェクトに混入させないことで、生産性が高くなる。
もうひとつは、なんというか、遅延実装。必要になるギリギリまでコードを書かない。 仕様は常に変わるので、今必要と思われる機能が本当に必要かどうかは怪しい。 だから実装は限界ギリギリまで先延ばしする。 ただし、現在の仕様を実装するのにどれだけの時間が必要かを正確に見積もっておくことが必要。 技術的に問題になりそうな部分は、あらかじめすべて解決しておかなければならない。 検証はしっかりやるけど最後まで実装はしない。 暇だからって「こんなのあったら便利そうだから作っとくか〜」みないな事は絶対にやらない。 コードが増えるとメンテナンスのコストが増える。 あと問題の解決に常に最善の策を追求すべきで、暇に任せて必要かどうかわからないコードをコミットしちゃいけない。 一度書いたコードとかツールは、なんとなく使いたくなって、プロジェクトが余計な実装に引きづられる。 最善の解決方法を追求する妨げになりえる。 でもこっちは仕事のタイプによりけりかも。
仕事をしている気分になること(あと他人から仕事をしているように見えること)と実際の仕事を混同しちゃいけない。 というのが今現在の自分の考え。
[Bilbo]Bilbo試験中
試験的に本日記をBilboで運用してます。
コメント機能はアツイので切ってあります。少ししたら実験的にコメント機能を有効にします。
tDiaryの記事を全部インポートしたときの動作速度が心配だった(最適化はやってない)のだけど、特に問題なさそうだなあ。
[Bilbo]だいぶ形になってきた
これまでずっと日記をブラウザから書いてたんだけど(このエントリもブラウザから書いている)、日記の記事をテキストファイルにしてSubversionで管理したいというのがことの始まりだったかな。
一年くらい前に軽く実装して、それきり拡張することなく職場での個人的なログ管理にだけ使っていた。ここ数日いろいろ手直しして、だいぶ形になってきた。ここ数日でかなり改造したつもりだったけど、コアのbilbo.rbはほとんど書き換えずにすんだから、なかなか良い実装なのかもしれない。
とりあえずサービスだけ公開して、少し様子を見てからCodeReposに突っ込む予定。本当ももっと早く形にしたかったのだけど、ごく最近まで余裕がなかった。
[ruby][Debian]Rubyのアップデート
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p114.tar.bz2 tar -xvjpf ruby-1.8.6-p114.tar.bz2
RubyGemsを入れてから、
gem install rails gem install sqlite3-ruby
これでプラポケは動く。
[開発ログ]プラグインのフック
複雑なので修正。
before
@@hook_plugins = Hash[ *%w( before_content after_content before_entry after_entry before_entries after_entries ).inject([]) {|t, e| t << e.to_sym; t << []; t } ] def self.add_hook(key, priority = 128, &block) @@hook_plugins[key] << block end def self.render_hook(key, *args) %Q!<div class="#{key}">#{ @@hook_plugins[key.to_sym].map {|e| e.call(*args) }.join("\n") }</div>! end
after
@@hook_procs = {} def self.add_hook(key, priority = 128, &block) @@hook_procs[key] ||= [] @@hook_procs[key] << block end def self.render_hook(key, *args) @@hook_procs[key] or return '' @@hook_procs[key].map {|e| e.call(*args) }.join("\n") end
存在しないエントリーポイントに対して、render_hookしたときにエラーにしたかったんだけど、その機能はカット。
divタグで囲むのをやめた。 divタグなしのフックエントリを挿入できなくて悩んでたけど、 その辺はビューで解決すべきと判断した。
priorityは未実装。 プラグインの実行順序は、ファイル名で操作できるからいらない気もする。
after2
@@hook_procs[key] or return '' @@hook_procs[key].map {|e| e.call(*args) }.join("\n")
上の部分はもうちょっとなんとかならないか。
@@hook_procs[key] ? @@hook_procs[key].map {|e| e.call(*args) }.join("\n") : ''
1行になった。
(a = @@hook_procs[key]) ? a.map {|e| e.call(*args) }.join("\n") : ''
ちょっと短くなった。
(@@hook_procs[key] or []).map {|e| e.call(*args) }.join("\n")
さらに短くできた!
(@@hook_procs[key] or []).map(&:call, *args).join("\n")
こうは書けないんだよなあ。 Symbol#to_procに引数を渡すのできないよね?