2005年12月03日
_ Haskell同好会
第2回 Haskell同好会 に行ってきた。
最初のほうはHaskellに関する文献に関する話をして、あとはずっと雑談。 最近は欧米方面でreactive programmingが注目されているとか。
昼食を食べたあたりからどうしようもなく眠くなってなにを言っているのか よくわからなくなってしまった。せっかくおもしろそうな話をしていた のにみなさんすみません。
2005年12月07日
_ RSS reader on w3m
w3mのlocal CGIを利用して動作するRSS readerを作ってみた。 <URL://www.kmc.gr.jp/~ohai/srss.tar.gz>。なんか問題があったら 適当に修正して使ってください。
2005年12月10日
_ Ruby
Rubyには「手抜きができるのは良いことだ」という価値観があるみたいです。 そういう価値観を持って別の言語をさわると面倒でいらいらしてくることが よくあります。
とりあえずプログラミング言語は構文砂糖を大量にぶっかけておく べきだと思います。
2005年12月12日
_ Feature Base Object Management
これはこういうことでしょうか。
class ObjManager def initialize @all_objs = [] @container = Hash.new{|h,k| h[k]=Array.new} end def add(obj) @all_objs << obj obj.features.each do |feature| @container[feature] << obj end end def objs(*features) case features.size when 0 @all_objs when 1 @container[features.first] else main, *subs = *features @container[main].find_all{|obj| subs - obj.features == []} end end end class ManagedObj class << self def def_features(*features) @features ||= [] @features.concat(features) end attr_reader :features end def features self.class.features end end # テスト class A < ManagedObj def_features :x, :y end class B < ManagedObj def_features :y, :z end mgr = ObjManager.new mgr.add A.new mgr.add B.new p mgr.objs p mgr.objs(:x) p mgr.objs(:y) p mgr.objs(:y, :z) p mgr.objs(:z, :x)
もうすこし工夫すれば継承が使えたりするようにはできるでしょう。
以前 Ruby でゲームを作るための思考実験として同様のシステムを作りました。 ただし上のやりかたそのままだと自分自身の消滅を扱うのが面倒なので、 毎フレームごとに自分自身を適切な分類に登録していくようにしました。 Template method パターンとクラスメソッドの併用で Rails 風味な仕組みでした。
2005年12月19日
_ RRBの Rename method について
Ruby は動的型付けな言語なので、Rename methodを正しく処理することは できません。よって、 RRB は二つのやり方を用意して、それをユーザに 選ばせることにしています。
一つめは、同名のメソッドをすべて変換する方法、もう一つは 選択したクラスに属していると明らかにわかるものだけを変換する方法です。
一つ目は説明の必要はないでしょう。で、二つ目ですが、ここで明らかに わかるというのは、定義部とselfを省略した呼び出しのみということです。 これは当然不完全です。 そこで RRB は以下のようなコードを、
class Heke def old_method : end end
次のように変換します。
class Heke def old_method raise "Heke#old_method is renamed to new_method" end def new_method : end end
これでテストを実行すると古いメソッドを呼びだした所で例外が 発生するわけです。あとはスタックトレースを確認して訂正すれば よいと考えているわけです。 リファクタリングする場合はすでにユニットテストは準備しているはずだ、 と仮定してよかろうという判断のもとこうしています。
また別の方法としては
class Heke def old_method warn "#{caller(1).first}: Heke#old_method is renamed to new_method" new_method end def new_method : end end
として警告を出すだけで新しいメソッドを呼ぶという手もあります。 ただこれは警告を見のがしてしまうというデメリットも考えられますので このやりかたは使っていません。
ちなみに Smalltalk のリファクタリングツールでは、上のようなコードを 埋め込み、ユニットテスト実行時にリネームしたメソッドの呼びだしが検出 されたとき、ソースのメソッド呼出し部を勝手に変更してしまうそうです。 実行環境と開発環境が密接に結びついた Smalltalk ならではのやりかた だと言えそうです。