はじめに
Matlabにはイベントとリスナーという機能がある。筆者は先日、無線機の自動ゲイン調整部のシミュレータを作ったときにこれを利用した。しかし実はリスナーの登録手続きに罠がある。筆者はこの罠にハマり、30分程の時間を溶かしてしまった。備忘録として、また同様の犠牲者が出ないよう、ここに書き残しておく。
問題と解決策
クラスのプロパティとして保持しているメンバー同士でイベントとリスナーを結び付けるパターンはドキュメントには例が無く、その他の普通の場合と同じやり方をすると、登録時は問題無いが実行時にコールバック関数が見つからないエラーが出る。
問題のコードを以下に示す。まずイベントを表すクラス。
次にイベントを発行するクラス。
そしてイベントを受け取るクラス。
最後に、PublisherとListenerをメンバーに持つトップのクラス。
成否を握るのは次の2行である。
%addlistener(obj.publisher, 'StateChange', @obj.listener.handleStateChangeEvent); %NG
addlistener(obj.publisher, 'StateChange', @(src,event) obj.listener.handleStateChangeEvent(src,event));
NGとコメントした方を使うと次のようなエラーが生じる。
Warning: Error occurred while executing the listener callback for event StateChange defined for class Publisher:
Undefined function 'obj.listener.handleStateChangeEvent' for input arguments of type 'Publisher'.
> In Publisher/setState (line 37)
In TopClass/test (line 20)
Warning: Error occurred while executing the listener callback for event StateChange defined for class Publisher:
Unable to find function @(src,event)obj.listener.handleStateChangeEvent(src,event) within C:\Users\PC1901-19\Desktop\matlab_ev_li_pitfall\TopClass.m.
> In Publisher/setState (line 37)
In TopClass/test (line 20)
Warning: Error occurred while executing the listener callback for event StateChange defined for class Publisher:
Undefined function 'obj.listener.handleStateChangeEvent' for input arguments of type 'Publisher'.
> In Publisher/setState (line 37)
In TopClass/test (line 21)
Warning: Error occurred while executing the listener callback for event StateChange defined for class Publisher:
Unable to find function @(src,event)obj.listener.handleStateChangeEvent(src,event) within C:\Users\PC1901-19\Desktop\matlab_ev_li_pitfall\TopClass.m.
> In Publisher/setState (line 37)
In TopClass/test (line 21)
回避するにはNGでない方の行の書き方をする必要がある。無名関数を丁寧に定義しているのだが、これは公式ドキュメントに記載が無い。