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 ならではのやりかた だと言えそうです。