複数のプログラミング言語やフォーマットにおいて、同じ名前を使いたいことがしばしばあります。しかし、プログラミング言語やフォーマットを横断して名前を揃える作業は思いのほか難しいですね。「同じ名前」「名前が同じ」という概念をキッチリ定義しないといけません。
どこでも使える安全な名前
そもそも、どのプログラミング言語/フォーマットでも共通に使える名前とはどんなものでしょう。次の定義は非常に保守的で、それゆえ安全なものです。
- 使える文字は英字と数字だけ。
- 最初の文字は数字ではない。
正規表現で書けば:
- [a-zA-Z][a-zA-Z0-9]*
この定義では、大文字小文字が区別されます。しかし、ドメイン名、メールやHTTPのヘッダーフィールド名、古い仕様のプログラミング言語やAPIなどでは、大文字・小文字が区別されません。そこで、さらに安全のために、正規形は小文字だけにすると約束しましょう。
- [a-z][a-z0-9]*
こりゃ、テッパンに安全。
名前を語に切り刻む話
しかしなー、こりゃイクラナンデモだよね。XMLHttpRequest は xmlhttprequest、getElementsByTagName は、getelementsbytagname ですからねー。複数の単語の切れ目が判断できないのは辛すぎる。
単語の切れ目を表すには、アンダスコア('_')、ハイフン('-')、ピリオド('.')などが使われます。例を出せば:
- xml_http_request, get_elements_by_tag_name
- xml-http-request, get-elements-by-tag-name
- xml.http.request, get.elements.by.tag.name
しかし残念なことに、ハイフン、ピリオドを識別子に使えない例は多くあります。アンダスコアはだいたい使えるのですが、使えないケースがないと断言できないし、文化圏によっては「システムで使う特殊な識別子はアンダスコアではじめる」なんて習慣もあります。それと、ある名前が特定の環境の予約語とバッティングしたときの回避策として、先頭か末尾にアンダスコア(別な非名前文字でもいいが)を付けることがあります。アンダスコアは、いざというときに使う文字として温存しておいたほうがいいでしょう。
んじゃ、単語の切れ目の判断は絶対にできねーじゃん; ちょっと発想を変えて、「同じ名前」を「ほんとに同じ綴り」とは解釈しないで、各環境ごとの綴りを“正規化した構造”が同じなら「同じ名前」とみなすことにしましょう。
正規化された構造とは、[a-z][a-z0-9]* で規定される綴り(「語」と呼ぶことにします)の空でないリスト、例えば ["xml", "http", "request"] だとします。この形に正規化される以前の綴りは環境ごとの「ネイティブな名前」と呼ぶことにします。
キャメルケースのときはどうする
アンダスコアなどの区切り記号を使ったネーミングからの正規化は簡単です。区切り記号を目安に切り刻むだけですから。ネイティブな名前がキャメルケースのときはどうでしょう。大文字を語の先頭と解釈すると:
- XmlHttpRequest → ["xml", "http" "request"]
- XMLHttpRequest → ["x", "m", "l", "http", "request"]
ありゃ、2番目は切り刻みすぎ。もう少し注意深く考えて:
- 名前の先頭は常に語の先頭
- 直前の文字が小文字である大文字は語の先頭
- 直後の文字が小文字である大文字は語の先頭
- それ以外は語の先頭ではない。
このルールだと:
- XmlHttpRequest → ["xml", "http" "request"]
- XMLHttpRequest → ["xml", "http", "request"]
- XmlHTTPRequest → ["xml", "http", "request"]
- xmlHttpRequest → ["xml", "http", "request"]
- XMLHTTPRequest → ["xmlhttp", "request"]
けっこう自然でしょう。区切り記号と大文字・小文字混合を併用した XML-HTTP-Request のようなネーミングでも問題はありません。問題が出るケースとしてすぐ思い浮かぶのは、先頭のIを interface の略としているネーミングです。
- IIOManager → ["iio", "manager"]
["i", "io", "manager"] とはなりません。でも、この流儀で INode (Nodeインターフェース)という名前を見ても、僕は「ファイルシステムのinode」だと思うから、人間でもわかんない例でしょ。
結論
以上に述べた正規化と、正規形から環境固有のネイティブな名前への変換を組み合わせると、異なった環境における「同じ名前」の概念をハッキリと定義できます。