Home > Latest topics

Latest topics > swapBrowsersAndCloseOtherの変更への追従と、メソッドの動的な書き換えのメリット・デメリット

宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

swapBrowsersAndCloseOtherの変更への追従と、メソッドの動的な書き換えのメリット・デメリット - Apr 30, 2009

以前書いたtabbrowser要素のswapBrowsersAndCloseOther()メソッドの上書きの話で書いてたサンプルが使えなくなっていたので直した。というか自作アドオンの機能を使おうとして正しく動かなかったのでコードを改めて見てみて、メソッドの書き換えの対象になってる箇所に変更があった事に気付いた(4月16日に変更が行われていたようだ)。

以下は、Shiretoko 3.5b5preに合わせて修正した後のバージョンのサンプルコード。

if ('swapBrowsersAndCloseOther' in aTabBrowser) {
  eval('aTabBrowser.swapBrowsersAndCloseOther = '+
    aTabBrowser.swapBrowsersAndCloseOther.toSource().replace(
      '{',
      '$& MyAddonService.destroyTab(aOurTab);'
    ).replace(
      'if (aOurTab == this.selectedTab) {this.updateCurrentBrowser(',
      'MyAddonService.initTab(aOurTab); $&'
    )
  );
}

if (aOurTab == this.selectedTab)を目印にして「タブを入れ換えた後の再初期化処理」を入れてたんだけど、同じif文がこれより前の位置に増えたせいで、コードの挿入位置がずれてしまい、本来期待していた順番とは異なる順番で処理が行われてしまっていた。if文の中まで目印に含めるようにして一応回避したけど、これはこれで、if文の中を書き換えるアドオンがあると破綻してしまう可能性があるわけで……何かいい方法はないものだろうか。

今回の場合に限らず、「メソッドの入れ替えではなく動的な書き換えを行う」やり方には、こういう変更に逐一追従しなくてはならないという弱点がある。メソッドのインターフェース(引数の数や返り値)はそうそう変わらなくても、中身は結構頻繁に変わる。なので、気をつけておかないといけない。

もう1つの弱点として、書き換え対象のメソッドの中で参照されている変数がそのメソッドが定義された変数スコープからしか参照できないものであった場合に、それへの対処も必要となる。その変数の値がグローバルな名前空間からアクセス可能なものであれば、メソッドの書き換え時にその変数を同時に宣言し直してやればいいんだけど……

(function() {
  var attrName = 'foo';
  window.ExampleAddonService = {
    method : function(aNode) {
      aNode.setAttribute(attrName, true);
    }
  };
})();

// メソッドの書き換えには成功するが、attrNameという変数が
// 見つからなくなってしまうので、実行時にエラーになる
eval(
  'window.ExampleAddonService.method = '+
  window.ExampleAddonService.method.toSource().replace(
    '{',
    '{ AnotherAddonService.preProcess(aNode);'
  )
);

この例のような場合になると、もうお手上げ。

それでも動的なメソッドの書き換えの方を僕が積極的に使う最大の理由は、同じやり方でメソッドを書き換える他のアドオンとの互換性を維持するためだ。別名で元のメソッドを保持しておくやり方の場合、他のアドオンが元のメソッドの名前で関数オブジェクトを取得しても、その関数の内容は元のメソッドとは全然違うから、書き換えられなくて動かなくなる、という事態が起こり得る。それを避けるためには、上の例のようなお手上げな事例を除き、可能な限り元のメソッドを動的に書き換えた方が良いということになる。

分類:Mozilla > XUL, , , , , , 時刻:00:53 | Comments/Trackbacks (0) | Edit

Comments/Trackbacks

TrackBack ping me at


の末尾に2020年11月30日時点の日本の首相のファミリーネーム(ローマ字で回答)を繋げて下さい。例えば「noda」なら、「2009-04-30_swapBrowsersAndCloseOther.trackbacknoda」です。これは機械的なトラックバックスパムを防止するための措置です。

Post a comment

writeback message: Ready to post a comment.

2020年11月30日時点の日本の首相のファミリーネーム(ひらがなで回答)

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき