2006/12/29

ハンガリアン記法ふたたび

随分とご無沙汰してしまいましたが、前回のハンガリアン記法の記事にコメントがありましたので、また、書いてみようかと思いキーボードをとる事にしました(うーん、筆を「とる」というのがあるが、キーボードの場合は、「打つ」だろうか?)

最近は、.NET関連の仕事が増え、JavaだのC#だのを使うことも多いので、非ハンガリアン(通りすがりさん紹介によると「システム・ハンガリアン」ですが)でコードを書く事が多い今日この頃です。

前回の記事で、通りすがりさんよりご紹介のあった記事にあるように、私が「悪なのか?」と考えたのは、「システム・ハンガリアン」の方です。

とりあえず、一読した限りの私の理解で、「アプリケーション・ハンガリアン」と「システム・ハンガリアン」の違いを説明すると(間違っていたらスイマセン)

プレフィクスが変数の意味を表すのが「アプリケーション・ハンガリアン」
プレフィクスが変数の型を表すのが「システム・ハンガリアン」

Charles Simonyi氏は「アプリケーション・ハンガリアン」を考えたが、他のMicrosoftのエンジニアが誤解、「システム・ハンガリアン」として使ったのが広まったというのが真相で、Simonyi氏の意図は、決して型をプレフィクスに書くものではなかったとの事です。

つまり、型は同じであっても、使途が違っていればプレフィクスを使って区別するというのが「アプリケーション・ハンガリアン」の意図だったという事です。この考え方は、理にかなっていると思います。「システム・ハンガリアン」の場合でも、

char * pcBuffer ;
char * pszString ;

のような使い方は、同じ型であっても格納しているデータが違っていることを表しているという点では、「アプリケーション・ハンガリアン」に近い使い方と言えるかもしれません。もちろん、「アプリケーション・ハンガリアン」であれば、格納しているデータについて、もっと詳細な分け方をするだろう(格納する文字列がパスワードを示すなら"passwd"だとかという具合)事は用意に想像できます。

さて、紹介された記事では、変数を見た時点で型が解かっても、「有用なことをほとんど何も教えてくれない」ので、「はなはだ煩わしくほとんど役立たず」であるとしています。

「システムハンガリアンにも、バグを見つけやすくする特質がなくはない。少なくとも、システムハンガリアンを使うなら、変数の型がその使われているその場でわかる。しかしそれはアプリケーションハンガリアンの有用性には遠く及ばない。」

とも記されています。

私個人としては、「変数の型がその使われているその場でわかる」事が、「システム・ハンガリアン」の有用性だと思っています。たとえそれが、「アプリケーション・ハンガリアン」の有用性には遠く及ばなくても、否定する事にはなりません。

例えば、ポインタであるか否かを一見で区別出来るは便利だと思うのですが、どうでしょうか?

決して「アプリケーション・ハンガリアン」を否定しているのではありません。そもそも、変数名には無意識に、意味を付け加えている。紹介された記事では、

「アプリケーションハンガリアンは有用で意味のあるプレフィックスを使う。配列インデックスを表す"ix"や、個数(count)を意味する"c"、2つの数の差(difference)を意味する"d"などだ(たとえば"dx"は幅を表す)。」

と記されているが、おそらく、殆どのプログラマは無意識に、

int nHogeIndex ;
int nHogeCount ;
int nHogeDiff ;

といった書き方をしているのではないでしょうか?

「変数の型がその使われているその場でわかる」という事だけの為に、わざわざプレフィクスを使うのは、「繁雑」で「馬鹿らしい」というのも理解できます。もちろん、そう考える人は「システム・ハンガリアン」を使う必要はありません。前回書いたように、「デメリット」が「メリット」を超えているからです。

だからと言って「システム・ハンガリアン」は「悪」とは言えません。(もちろん、紹介の記事も、そんな事は言っていないと思います)実際、私も、JavaやC#を使う場合は、流儀に従ってCamel記法やPascal記法を使います。その場に合わせて最適なものを選べば良いのだと思いますが、如何でしょうか。

| | コメント (0) | トラックバック (0)

2005/02/21

ハンガリアン記法は悪なのか?

最近、D言語の解説書が出ていたので買ってくる。個人的にはD言語には懐疑的ではある。「カレーライス(C++)とハンバーグ・ステーキ(JAVA)とナポリタン・スパゲッティ(C#)を混ぜたら、とても美味しい。」的な発想に思えてならないからだ。確かに、それなりに美味いかもしれないが、合わせるために、デミグラス・ソースは省いて、ケチャップは使わないで…、となっては、結局、単品よりは美味しくならない気がするのだ。だからといって、全部を混ぜるのは味のバランスが崩れて、非常に不味いものになる可能性もある。(ひょっとしたら、飛び切り美味くなる可能性も、あるにはあるが)

まぁ、開発途上の言語なので、それはそれで見守っていけばよいのだろうが、パラパラと本を捲っていると、「ハンガリアン記法は使わない」と書いてあった。この記述だけがあり、使ってはいけない理由が記述されていなかった。で、インターネットで調べてみたのだが、D言語を紹介しているページを見ると、「絶対、使っちゃダメ」と記載されていた。これまた、理由が記載されていない。

ハンガリアン記法とは、MicrosoftのCharles Simonyi氏発案の記法で、変数名の前に、型を示す前置文字(プレフィックス)を置くやり方の事を指す。もちろん、メリットもデメリットもある方法ではあるが、インターネットのサイトのいくつかは、感情的に否定している様に見受けられる(「悪名高きハンガリアン記法」、「ソースにハンガリアン記法使っているから、お里が知れる」等)。これは、「Microsoft=悪、Windows=悪。ゆえにMicrosoftが発明しWindowsプログラミングで使われているハンガリアン記法も当然悪だ。」と言っているように思えてならない。

私も、Microsoftは好きではないし(どちらかと言えば、仕事を増やすので嫌い)、可能なら(これまた、いらん仕事を増やすので)Windowsとかかわりたくない人だが、だからといって、全否定するのは、どうかとも思う。もちろん、全てにハンガリアン記法を強制しようとは思わないし、ハンガリアン記法が適さない場合も多くある。だが、頭からハンガリアン記法を否定するのは教条的過ぎるような気がする。

ハンガリアン記法の便利な点は、宣言を見なくても型が特定出来る点であろう。これは、これで慣れると便利なものだ。

「暗号めいた名前」という記述も見受けられた。私が、よく使う前置文字は、

nサイズを気にしない符号付き整数型(int)
uサイズを気にしない符号なし整数型(unsigned int)、または符号なし整数を示す
cchar型
shshort型
llong型
ffloat型
ddouble型
pポインタ
a配列
sz文字列
byBYTE型
bbool型
fn関数型
m_構造体、クラスのメンバ変数
Cクラス名
S構造体名
E列挙名

あたりだが。「暗号」と言われるのは、これらが組み合わされた場合を言っているのだろう。

int anArray[ 10 ] ;
char * pszFileName ;
char * apszArgv[] ;

確かにapとpaでは表す意味が違うので混乱する場合もあるだろう。ただ、複雑な宣言に対しては複雑な前置が付く。つまり、元々の宣言が複雑な場合が多いように思う。

欠点は、利点の逆だと言る。例えば、実際の型と違う名前を付けると大混乱となる。例えば、

int szFileName ;

等と書いていれば、確実に変数の型を誤認するだろう。しかし、ちゃんと統一して書かなければ、どんな記法でも混乱するのは当り前ではないだろうか?

char pszName ;
char szName[ 10 ] ;
...
pszName = szName ;

これも、よくやる間違い。(ハンガリアン記法でpを付けたので安心して、実際に*を付けていない)

また、その変数の型が変わった場合、プログラム中の全変数名をリネームしなければならないのも欠点だと言える。(ただ、型依存のコードを書いている場合には、逆にチェック対象にしやすいとは言えるのだが)

もう一つの欠点は、基本データ型以外には適用し難い事があげられる。C++の場合、クラスのインスタンスにはハンガリアンが適用し難い。私の場合、ハンガリアン記法は絶対だと思っていないので、Pascal記法(最初の文字が大文字)で記述している。だが、これでは、ハンガリアンの恩恵は受けられない。

CHogeHogeClass HogeInstance ;

私個人の意見としては、長所と欠点を知った上で、使い易いものを使えばよいのではなかと思っている。盲信的に、ある書き方に拘るのは馬鹿げている。同様に、誰が考えたかとか、何処で使っているからという理由から不当に扱ったり、自身の記法と違うから排斥したりするのも馬鹿げている。要は、最も生産性が上がる方法を採れればよいのだ。

Microsoftは、長くハンガリアン記法を採用してきた。が、.NETでは使わない事になった。これを見て、「ほら、Microsoftも使わなくなった」という意見もある。「Microsoftしか使っていなかったんだから、そこが使わないなら使わんでもいいだろう」という事だと思うが、一つ間違えば、「Microsoftが使えば標準で、使わなければ非標準」という話になりかねない気がする。メリットが無くなったから(またはデメリットが大きいから)使わないのだという論点が必要なのではないだろうか。

D言語では、Camel記法とPascal記法を使うという事に異論はない。それには、そうするだけの訳があったろうから。ただ、その訳を知りたいと思うのは、私だけだろうか。

| | コメント (4) | トラックバック (2)