11月 082012
ものすごい必要だったので作った。
rubygemsに登録しておいたので
gem install event_emitterで使える。
ドキュメントはここ
Ruby EventEmitter
バグ、機能要望などは
githubのissueかtwitterかメールでお願いします
EventEmitterとは
Node.jsのコアライブラリ。lib/events.jsにある。
nvmでnodeをインストールすると ~/.nvm/src/node-v0.8.14/lib/events.js とかにある。
どんなオブジェクトにでも一発でonとemitという関数を追加できて、
obj.on(‘イベント名’, コールバック)でコールバック登録して
obj.emit(‘イベント名’, 引数)でイベントを発火させる。
nodeの全てのライブラリがイベント駆動するためによく使ってる機能。
addEventListenerとかよりも使いやすい。
ruby実装
onとemitをクラス宣言時にmix-inしたり、既存のクラスや特定のインスタンスに後から追加したりできる。
require "rubygems"userインスタンスに登録したイベントはuserインスタンスの中で実行されるので、”name”だけでuser.nameの中身の”shokai”が参照できている。
require "event_emitter"
class User
include EventEmitter ## mix-in
attr_accessor :name
end
user = User.new
user.name = "shokai"
user.on :go do |data|
puts "#{name} #{data[:place]}に行く"
end
user.emit :go, {:place => "かずすけ"}
# => "shokai かずすけに行く"
onのかわりにonceで登録すると、一度だけ実行されるイベントを登録できる。
user.once :eat do |data|
puts "#{name} -> #{data}"
end
user.emit :eat, "BEEF" # => "shokai -> BEEF"
user.emit :eat, "Ramen" # => 実行されない
ごく普通のインスタンスにEventEmitter.applyすると、on/emitが追加される。特異メソッド。
EventEmitter.apply インスタンス名
既存のクラスにapplyするとクラスが拡張される
EventEmitter.apply クラス名
イベント駆動じゃないクラスとかも強引にイベント駆動にできそうですね。
参考にした
JSだと全部オブジェクトなのでシンプルなんだけど、Rubyのクラスやインスタンスやら全部にon/emit追加できるようにするのちょっと理解が大変だった。
このへんの黒魔術を参考にした。