LimeChatを携帯電話から操作するスクリプト「keitairc.js」

前に上げたスクリプトは POE 1.0003 を想定したワークアラウンドを入れることで,上手く動くようにしていた.今日,久方振りにActivePerlを新調したところ,POE 1.0002に下げられてしまった.CPANで無理に入れた物体なので,下げられるのは仕方ない.まあ,keitairc.jsの使用には問題ないだろうと高をくくっていたが,いざ使ってみるとワークアラウンドで回避したはずの問題が再発生してしまった.
selectで3600秒待ってしまう問題なんだけど,POE 1.0003では,POE::Loop::Select->loop_reset_time_watcherでイベント発生時間を改ざんすることで,0秒にすることが出来た.しかし,POE 1.0002では,loop_reset_time_watcherが空箱になっているため,この回避策が無効になってしまった.POE 1.0002のPOE::Loop::Selectは,POE::Kernel::get_next_event_time関数から次のイベント発生時間を得ているので,こいつを乗っ取って,即座にイベントが発生すると偽れば,0秒待ちに出来るはずだ.
しかし,ただの一るびいすとが,perlでどうやってモジュールメソッドを乗っ取るかとか,そんな濃ゆいネタを知っているわけがない.そこで,グーグル先生に教えを乞うてみると,すぐに答えが出てきた.
404 Blog Not Found:perl - パッチなしでパッチする
なるほど,perlではこうやって乗っ取るのね.

sub poe_kernel_fix {
	package POE::Kernel;
	no warnings 'redefine';
	if (POE::Loop::Select->VERSION > 1.2222) {
		# for POE 1.0003
		*run_one_timeslice_old = \&POE::Kernel::run_one_timeslice;
		*run_one_timeslice = sub {
			my $self = shift;
			$self->loop_reset_time_watcher(time());
			$self->run_one_timeslice_old();
		};
		*POE::Kernel::run_one_timeslice = \&run_one_timeslice;
	} else {
		# for POE 1.0002
		*get_next_event_time = sub { time(); };
		*POE::Kernel::get_next_event_time = \&get_next_event_time;
	}
}

アスタリスク+識別子は型グロブ,バックスラッシュ+識別子はリファレンスと呼ばれることを初めて知った.あと,それらの意味も.
で,不具合を直した keitairc.js 0.01 for LimeChat,っと.
Download (from MediaFire)