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)