いざ要素名や属性名などを変えたくなった時にソースの中をあちこち探し回ったり巧みな正規表現を考えるために頭をひねったりしなくても済むようにするテク宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。Shadowのコード(textshadow.js)を教材にして拡張機能開発のノウハウを解説していくシリーズ。Firefoxの拡張機能で、DOM要素ノードを動的に生成したり、編集したり、そうして生成したノードを後でまた収集したり、といった操作を行うような物を作る時は、必然的に、ソースの中に要素名や属性名が登場してくる。this.processBox(nodes.snapshotItem(i));}こういう操作が一カ所だけにしか登場しないんなら別にいいけど、複数箇所で、似たような操作が何度もある場合は、要素名であるとか属性値・属性名であるとかノード検索の条件であるとかを、コードの冒頭で定数(定数プロパティ)として定義しておくことをお薦めしたい。'/descendant::*[@class="my-custom-box"]',(略)すると、さっきのような箇所はこうなる。this.processBox(nodes.snapshotItem(i));}textshadow.jsの冒頭箇所を見てみると、動的に生成するIDのプレフィクスとか、途中で生成する要素のクラス名であるとか、XPath式の中に埋め込む検索条件だとかを、片っ端から定数としてまとめて定義していることが分かるはずだ。しておくと、いざクラス名が他の拡張機能とかぶっていたと判明した時なんかでも、ソースの頭の方をちょこっと書き換えるだけで済む。class属性の値として文字列リテラルが書かれている箇所を片っ端から探すようなことはしなくていい。確かにたいていの場合はそうなんだけど、でもそれじゃ解決できない時もある。}},(略)ここで「myAttribute」という属性名が他の拡張機能とかぶってた!ということに気がついた時、このJavaScriptファイルの中を「myAttribute」→「myExtensionCustomAttribute」と一括置換したとする。すると、この箇所はこうなるだろう。}},(略)属性名と同じ文字列があったメソッド名の定義の部分まで変わってしまったことに気がついただろうか。このメソッドがこのファイルの中でしか呼ばれていない物なんだったら別にいいけど、他のファイルで元の「myAttributeCheck」というメソッド名を参照してる箇所があったら、エラーになってしまうじゃないですか。}},(略)これはもう問答無用でエラーになってしまう。いう例を見ても分かるとおり、一括置換というのは注意深くやらないと思わぬ所で問題を引き起こしてしまう可能性がある。正規表現を駆使すれば「本当に変更したい箇所」だけをピンポイントで狙い撃ちすることもできるだろうけど、そんな事に頭を使うのって激しく無駄じゃないすか?でも、こういう属性名の定義を定数プロパティにまとめておけば、そんな気苦労からはおさらばできる。'/descendant::*[@class="my-custom-box"]',(略)一括置換しなくても、さっきも書いたとおり、冒頭のここをちょこっと書き換えるだけで作業は終わりだ。仮に一括置換をどうしても使いたくなってしまった時......「CUSTOM_BOX_CLASS_NAME」という定数プロパティ名自体が気に入らなくなってしまった時でも、安心して一括置換できる。ここでは「定数プロパティ名は全部大文字で書く」というコーディングルールを採用しているから、仮にこの定数プロパティ名を一括置換したところで、他の箇所の変数やメソッド名には全然影響しない。属性名や属性値など、後で変更する可能性があるものはソース内のあちこちに文字列リテラルで書いてしまわずに、一カ所にまとめて定数プロパティとして定義する。「定数プロパティ名は必ず大文字で書く」という風なコーディングルールを徹底しておく。安易に属性名を決めてしまったり、どんなメソッドを定義していたか忘れてしまったり、ということの多い僕のようなウッカリさんには、上記のようなミスを未然に防ぐためにも是非採用してもらいたいところです。titleFirefoxの拡張に限らず「マジックナンバを直書きしてはならない」という話と合わせて、すべてのプログラミングで留意したいと思います。atの末尾に2018年6月21日時点の日本の首相のファミリーネーム(ローマ字で回答)を繋げて下さい。「noda」なら、「2007-09-05_constant.trackbacknoda」です。これは機械的なトラックバックスパムを防止するための措置です。