私はハンガリー語が何を意味するか知っています-変数、パラメーター、または型に関する情報をその名前の接頭辞として与えます。場合によってはそれが良い考えのように思われるかもしれませんが、誰もがそれに激しく反対しているようです。有用な情報が提供されていると感じた場合、利用可能な場所に配置しない方がよいでしょうか。
私はハンガリー語が何を意味するか知っています-変数、パラメーター、または型に関する情報をその名前の接頭辞として与えます。場合によってはそれが良い考えのように思われるかもしれませんが、誰もがそれに激しく反対しているようです。有用な情報が提供されていると感じた場合、利用可能な場所に配置しない方がよいでしょうか。
回答:
ほとんどの人はハンガリー語の表記を間違った方法で使用しており、間違った結果を得ています。
Joel Spolskyによるこの優れた記事を読んでください。
つまり、変数名の前にtype
(文字列)を付けるハンガリー語表記(システムハンガリー語)は役に立たないため、不適切です。
作成者が意図したハンガリー表記kind
(変数名の前にJoelの例を使用:安全な文字列または安全でない文字列)であるため、Apps Hungarianと呼ばれる用途があり、依然として価値があります。
vadjHungarian注釈を使用すると、ncodeの読み取りが困難になります。
ジョエルは間違っています、そしてここに理由があります。
彼が話しているその「アプリケーション」情報は、型システムでエンコードする必要があります。安全なデータを必要とする関数に安全でないデータを渡さないようにするために、変数名の反転に依存すべきではありません。型エラーにして、不可能にする必要があります。安全でないデータには、安全でないとマークされた型が必要です。そのため、安全な関数に渡すことはできません。安全でないものから安全なものに変換するには、なんらかのサニタイズ機能による処理が必要です。
ジョエルが「種類」と言っていることの多くは種類ではありません。実際にはタイプです。
ただし、ほとんどの言語に欠けているのは、このような区別を強制するのに十分な表現力を持つ型システムです。たとえば、Cに「強力なtypedef」の種類がある場合(typedef名には基本型のすべての演算がありましたが、基本型に変換できませんでした)、これらの問題の多くは解消されます。たとえば、あなたが言うことができれば、strong typedef std::string unsafe_string;
unsafe_string
、std :: stringに変換できない新しい型を導入するために(そして、オーバーロードの解決などに参加するために)言うことができる場合は、ばかげたプレフィックスは必要ありません。
したがって、ハンガリー語はタイプではないもののためのものであるという中心的な主張は間違っています。タイプ情報に使用されています。確かに、従来のC型の情報よりも型情報が豊富です。オブジェクトの目的を示すために、ある種の意味の詳細をエンコードするタイプ情報です。しかし、それはまだ型情報であり、適切な解決策は常にそれを型システムにエンコードすることでした。それを型システムにエンコードすることは、適切な検証とルールの適用を実現するための最善の方法です。変数名は単にマスタードを切りません。
言い換えれば、「開発者に間違ったコードを間違って見せること」を目的とすべきではありません。それは「間違ったコードをコンパイラに間違って見えるようにする」であるべきです。
Joel is wrong
、そしてWhat most languages lack, however, is a type system that's expressive enough to enforce these kind of distinctions.
ほとんどの言語があるためそうはない区別のこれらの種類を強制する表現十分に欠け、ジョエルがある右。正しい?
私はそれがソースコードを大いに散らかしていると思います。
また、強く型付けされた言語ではあまり効果がありません。タイプ不一致のtomfooleryを実行すると、コンパイラーがそれを通知します。
ハンガリー語の表記は、ユーザー定義型のない言語でのみ意味があります。最新の関数型言語またはオブジェクト指向言語では、値の「種類」に関する情報を変数名ではなくデータ型またはクラスにエンコードします。
いくつかの回答がJoelsの記事を参照していますます。ただし、彼の例はVBScriptにあることに注意してください。VBScriptは、ユーザー定義クラスをサポートしていません(少なくとも長い間)。ユーザー定義型を使用する言語では、HtmlEncodedString型を作成して同じ問題を解決し、Writeメソッドにそれのみを受け入れさせます。静的に型付けされた言語では、コンパイラはエンコーディングエラーをキャッチします。動的に型付けされた言語ではランタイム例外が発生しますが、いずれの場合も、エンコードされていない文字列の書き込みから保護されます。ハンガリー語の表記は、プログラマーを人間のタイプチェッカーに変えるだけです。
Joelは「systems hungarian」と「apps hungarian」を区別します。「systems hungarian」はintやfloatなどの組み込み型をエンコードし、「apps hungarian」は「kind」をエンコードします。これはより高レベルのメタ情報です。変数については、マシンタイプに依存します。オブジェクト指向または現代の関数型言語では、ユーザー定義のタイプを作成できるため、この意味でタイプと「種類」の区別はありません。どちらもタイプシステムと「アプリ」で表すことができます。ハンガリー語は、「システム」ハンガリー語と同じくらい冗長です。
だからあなたの質問に答えるために:システムハンガリー語は、たとえばfloat値をint変数に割り当てるとシステムがクラッシュする、安全ではない弱く型付けされた言語でのみ役立ちます。ハンガリー語の表記法は、特に60年代にBCPLで使用するために発明されました。今日一般的に使用されている言語にこの問題があるとは思いませんが、この表記法は一種のカーゴカルトプログラミングとして存続しています。
レガシーVBScriptや初期バージョンのVBなど、ユーザー定義型のない言語で作業している場合、ハンガリーのアプリは理にかなっています。おそらく、PerlとPHPの初期バージョンも。繰り返しますが、現代の言語でそれを使用することは、純粋な貨物カルトです。
他の言語では、ハンガリー語は醜く、冗長で壊れやすいだけです。型システムから既知の情報が繰り返されるため、自分で繰り返すことはできません。型のこの特定のインスタンスの意図を説明する変数の説明的な名前を使用します。型システムを使用して、不変条件と変数の「種類」または「クラス」に関するメタ情報をエンコードします。タイプ。
Joelsの記事の一般的なポイント-間違ったコードを間違って見えるようにすること-は非常に良い原則です。ただし、バグに対するより優れた保護は、可能な場合は常に、コンパイラによって誤ったコードが自動的に検出されるようにすることです。
私はすべてのプロジェクトで常にハンガリー語の表記法を使用しています。何百もの異なる識別子名を処理しているときに、それは本当に役に立ちます。
たとえば、文字列を必要とする関数を呼び出すと、「s」と入力してcontrol-spaceを押すと、IDEで、「s」で始まる変数名を正確に表示できます。
もう1つの利点は、unsignedの場合はuを、signed intの場合はiを前に付けると、潜在的に危険な方法で符号付きと符号なしが混在している場所がすぐにわかることです。
75000行の巨大なコードベースで、ローカル変数にそのクラスの既存のメンバー変数と同じ名前を付けたためにバグが発生した回数を思い出せません(私も他の人も)。それ以来、私は常にメンバーの前に「m_」を付けます
それは味と経験の問題です。あなたがそれを試すまで、それをたたかないでください。
この情報を含める最大の理由を忘れています。プログラマーであるあなたとは何の関係もありません。会社を辞めてから2、3年後にその人を読む必要のある人と関係があります。
はい、IDEはタイプをすばやく識別します。ただし、「ビジネスルール」コードの長いバッチをいくつか読んでいるときは、各変数を一時停止する必要がなく、それがどの型であるかを調べる必要があります。strUserID、intProduct、guiProductIDなどを確認すると、「ランプアップ」の時間がはるかに簡単になります。
MSがそれらの命名規則のいくつかに行き過ぎていることに同意します-私はそれを「あまりにも良いこと」の山に分類します。
命名規則は、あなたがそれらに固執する限り、良いことです。私は、以前のジョブで呼び出されたように、「ラクダのケーシング」をプッシュするほど多くの同じような名前の変数の定義を常に見直さなければならない十分な古いコードを調べました。現在私は、VBScriptで完全にコメント化されていない数千行の古典的なASPコードを使用している仕事に取り組んでおり、それを理解しようとするのは悪夢です。
Joel Spolskyがこれについて良いブログ投稿を書いています。 http://www.joelonsoftware.com/articles/Wrong.html 基本的に、適切なIDEから変数のタイプを思い出せない場合は、適切なIDEでコードが読みにくくなります。また、コードを十分に区分化すると、変数が3ページ上で宣言されたものを覚えておく必要がなくなります。
これらの日を入力するよりもスコープは重要ではありません、例えば
* l for local
* a for argument
* m for member
* g for global
* etc
型を変更したために古いコードをリファクタリングし、シンボルの検索と置換を行う最新の手法では、コンパイラーは型の変更をキャッチしますが、スコープの誤った使用をキャッチしません。賢明な命名規則がここで役立ちます。
ハンガリー語の表記法を正しく使用してはならない理由はありません。これは、特にWindows APIでのハンガリー語表記の誤用に対する長期にわたる反発によるものです。
昔、DOSにIDEに似たものが存在する前に(Windowsでコンパイラを実行するのに十分な空きメモリがなかったため、開発はDOSで行われていました)、何の助けも得られなかった変数名の上にマウスを移動します。(マウスがあると仮定します。)対処しなければならないのは、すべてが16ビット整数(WORD)または32ビット整数(ロングワード)として渡されるイベントコールバック関数です。次に、これらのパラメーターを特定のイベントタイプに適したタイプにキャストする必要がありました。実際、APIのほとんどは事実上型なしでした。
結果、次のようなパラメーター名を持つAPI:
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
wParamとlParamの名前は、かなりひどいですが、param1とparam2に名前を付けることほど悪くはありません。
さらに悪いことに、Window 3.0 / 3.1には、nearとfarの2種類のポインターがありました。したがって、たとえば、メモリ管理関数LocalLockからの戻り値はPVOIDでしたが、GlobalLockからの戻り値はLPVOID(長い場合は「L」)でした。ひどい表記は、次にように拡張得たことLオングP列ointerが接頭たLPを単にmallocされた文字列からそれを区別するために、。
この種のことに対して反発があったのは当然のことです。
ハンガリー語表記は、特定の変数がどのように使用されているかを開発者がすぐに思い出すことができるため、コンパイル時の型チェックなしの言語で役立ちます。パフォーマンスや動作には影響しません。コードの可読性を向上させることになっており、ほとんどの場合、好みとコーディングスタイルの問題です。このため、多くの開発者から批判されています。すべての人が同じ脳内配線を持っているわけではありません。
コンパイル時の型チェック言語では、ほとんど役に立たない-数行上にスクロールすると、宣言が表示され、型が表示されます。グローバル変数またはコードブロックが複数の画面にまたがっている場合は、設計と再利用性に重大な問題があります。したがって、批評の1つは、ハンガリー記法は開発者が悪いデザインを持ち、それを簡単に回避できることを可能にするということです。これが恐らく嫌われている理由のひとつでしょう。
一方、コンパイル時の型チェック言語でさえハンガリー表記法の恩恵を受ける場合があります- (win32 APIのvoidポインターまたはHANDLE)のます。これらは実際のデータ型を難読化し、そこでハンガリー表記法を使用するメリットがあるかもしれません。それでも、ビルド時にデータのタイプを知ることができる場合は、適切なデータタイプを使用してはどうでしょう。
一般に、ハンガリー語表記を使用しないという明確な理由はありません。これは、いいね、ポリシー、コーディングスタイルの問題です。
Pythonプログラマーとして、ハンガリー記法はかなり速くバラバラになります。Pythonでは、何かが文字列であるかどうかは気にしません-それが次のように動作できるかどうか気にします文字列のかどうか(つまり___str___()
、文字列を返すメソッドがあるかどうか)です。
たとえば、整数としてfooがあるとします12
foo = 12
ハンガリー語の表記は、それが整数であることを示すために、iFooまたは何かを呼び出す必要があることを示しています。これにより、後でそれが何であるかを知ることができます。Pythonを除いて、これは機能しません。つまり、意味がありません。Pythonでは、使用するときに希望するタイプを決定します。文字列が欲しいですか?まあ私がこのようなことをすると:
print "The current value of foo is %s" % foo
%s
-文字列に注意してください。Fooは文字列ではありませんが、%
オペレーターはfoo.___str___()
結果を呼び出して使用します(それが存在すると想定)。foo
はまだ整数ですが、文字列が必要な場合は文字列として扱います。フロートが必要な場合は、フロートとして扱います。Pythonのような動的に型付けされた言語では、ハンガリー記法は意味がありません。何かを使用するまでは何の型でもかまいません。特定の型が必要な場合は、その型にキャストしてください(例:float(foo)
ください。これを使って。
PHPのような動的言語にはこの利点がないことに注意してください。PHPは、ほとんど誰も記憶していないあいまいなルールのセットに基づいてバックグラウンドで「正しいこと」を行おうとしますが、予期せぬ破滅的な混乱を招くことがよくあります。この場合、$files_count
またはのようなある種の命名メカニズム$file_name
が便利です。
私の見解では、ハンガリー記法はヒルのようなものです。おそらく以前は便利だったかもしれませんし、少なくとも便利だと思われたかもしれませんが、今日では、それほど多くの利点がないために、追加の入力が多くなっています。
.ToString()
ため、すべて印刷できます
IDEはその有用な情報を伝えます。ハンガリー語は、IDEがそれほど高度ではなかったときに、ある種の(全体ではないが、ある種の)何らかの意味をなしていたかもしれません。
プログラマーではなくエンジニアとして、私はすぐにJoelのApps Hungarianのメリットに関する記事「Make Wrong Code Look Wrong」を読みました。Apps Hungarianが好きなのは、工学、科学、数学が、下付きおよび上付きの記号(ギリシャ文字、数学演算子など)を使用して方程式や数式を表す方法を模倣しているからです。ニュートンの普遍的な重力の法則の特定の例を見てみましょう。最初に標準の数学表記で、次にAppsハンガリー語の疑似コードで:
frcGravityEarthMars = G * massEarth * massMars / norm(posEarth - posMars)
数学的表記では、最も顕著な記号は、変数に格納されている情報の種類を表すものです:力、質量、位置ベクトルなど。これはまさにハンガリーのAppsが行っていることです。それはあなたにその種類を教えています最初に変数に格納されてのこと詳細に進みます。最も近いコードについては、数学的表記を行うことができます。
明らかに強い型付けは、Joelのエッセイの安全な文字列と安全でない文字列の例を解決できますが、位置ベクトルと速度ベクトルに別々のタイプを定義することはありません。どちらもサイズ3の二重配列であり、一方に対して行う可能性が高いことは、もう一方にも適用される可能性があります。さらに、(状態ベクトルを作成するために)位置と速度を連結するか、それらの内積をとることは完全に理にかなっていますが、おそらくそれらを追加しないことです。タイピングでは最初の2つを許可し、2つ目を禁止します。そのようなシステムは、保護したいすべての可能な操作にどのように拡張されますか?タイピングシステムのすべての数学と物理学をエンコードする意思がある場合を除きます。
その上、多くのエンジニアリングは、Matlabなどの弱く型付けされた高水準言語や、Fortran 77やAdaなどの古い言語で行われます。
したがって、派手な言語とIDEがあり、Appsハンガリー語が役に立たない場合は、それを忘れてしまいます。多くの人がそうしているようです。しかし、私にとっては、弱く型付けされた言語または動的に型付けされた言語で作業する初心者プログラマーよりも悪いので、Apps Hungarianを使用すると、使用しない場合よりも速くより良いコードを書くことができます。
それは信じられないほど冗長であり、ほとんどの最新のIDEでは役に立たないので、型を明確にするのに優れています。
さらに、私にとっては、intI、strUserNameなどを表示するのは面倒です。
私の経験では、それは悪いです:
1-変数の型を変更する必要がある場合(つまり、32ビット整数を64ビット整数に拡張する必要がある場合)、すべてのコードを中断します。
2-型がすでに宣言に含まれているか、実際の型がそもそもそれほど重要ではない動的言語を使用しているため、これは役に立たない情報です。
さらに、一般的なプログラミングを受け入れる言語(つまり、一部の変数の型が関数の作成時に決定されない関数)または動的型付けシステム(つまり、コンパイル時に型が決定されない場合)では、どのように名前を付けますか変数?そして、ほとんどの現代の言語は、制限された形式であっても、どちらか一方をサポートします。
でジョエル・スポルスキの作る間違ったコードルック間違った彼は何皆が(彼はシステムハンガリーを呼び出す)ハンガリアン記法は、それが本当に(彼はアプリハンガリーを呼んでいるもの)であることを意図したものではありませんとの考えていることを説明しています。「I'm Hungary」という見出しまでスクロールして、この議論を見てください。
基本的に、システムハンガリー語には価値がありません。コンパイラやIDEが教えてくれるのと同じことを教えてくれるだけです。
Apps Hungarianは、変数が何を意味するのかを教えてくれ、実際に役立ちます。
私は常に、適切な場所に1つまたは2つの接頭辞があっても害はないと考えていました。IEnumerableのように、「これはインターフェイスです。特定の動作を当てにしないでください」などの有用な情報をすぐに伝えることができれば、私はそれを行うべきだと思います。コメントは、1つまたは2つの文字記号だけではなく、物事を混乱させる可能性があります。
IDEのアルファベット順のプルダウンリストにコントロールのリストが表示される場合、フォーム上のコントロール(btnOK、txtLastNameなど)に名前を付けるのに便利な規則です。
私はASP.NETサーバーコントロールでのみハンガリー記法を使用する傾向があります。それ以外の場合は、フォーム上のコントロールが何であるかを理解するのが難しすぎます。
次のコードスニペットを使用します。
<asp:Label ID="lblFirstName" runat="server" Text="First Name" />
<asp:TextBox ID="txtFirstName" runat="server" />
<asp:RequiredFieldValidator ID="rfvFirstName" runat="server" ... />
誰かがハンガリー語なしでそのコントロール名のセットを持つより良い方法を示すことができるなら、私はそれに移動したくなるでしょう。
Joelの記事はすばらしいですが、重要な点が1つ省略されているようです。
ハンガリー語は、特定の「アイデア」(種類+識別子名)をコードベース全体(非常に大きなコードベースであっても)で一意またはほぼ一意にします。
これは、コードのメンテナンスにとって非常に大きなものです。これは、優れたolの単一行テキスト検索(grep、findstr、「すべてのファイルで検索」)を使用して、その「アイデア」のすべての言及を見つけることができることを意味します。
コードの読み方を知っているIDEがあるのに、なぜそれが重要なのでしょうか。彼らはまだそれがあまり得意ではないので。これは小さなコードベースではわかりにくいですが、大きなコードベースでは明らかです-「アイデア」がコメント、XMLファイル、Perlスクリプト、およびソース管理外の場所(ドキュメント、wiki、バグデータベース)で言及されている場合。
ここでも少し注意する必要があります。たとえば、C / C ++マクロでトークンを貼り付けると、識別子の言及を隠すことができます。このような場合は、コーディング規約を使用して処理でき、いずれにしても、コードベースの少数の識別子にのみ影響を与える傾向があります。
PS型システムとハンガリー語の使用について要点を述べます。両方を使用するのが最善です。コンパイラがそれをキャッチしない場合にのみ、間違ったコードが間違って見えるようにする必要があります。コンパイラーにキャッチさせることができない場合がたくさんあります。しかし、それが可能である場合-はい、代わりにそれをしてください!
ただし、実現可能性を検討するときは、タイプを分割することの悪影響を考慮してください。たとえば、C#では、組み込みではない型で 'int'をラップすると、大きな影響があります。そのため、状況によっては意味がありますが、すべての状況では意味がありません。
タイプが、ある値を別の値から区別するすべてのものである場合、それは、あるタイプから別のタイプへの変換にのみ使用できます。タイプ間で変換されている同じ値がある場合、変換専用の関数でこれを行う必要がある可能性があります。(ハンガリー語のVB6の残りは、JSONオブジェクトを逆シリアル化する方法を理解できなかったか、null許容型を宣言または使用する方法を適切に理解できなかったために、すべてのメソッドパラメーターで文字列を使用することを確認しました。)ハンガリー語の接頭辞。これらは1つの形式から別の形式への変換ではないため、その意図を詳しく説明する必要があります。
ハンガリー語の表記法では、変数名に怠惰になることがわかりました。彼らにはそれを区別する何かがあり、彼らはその目的を詳述する必要がないと感じています。これは、ハンガリーの表記コードと最新のコードで一般的に見られるものです:sSQLとgroupSelectSql(または以前の開発者が入力したORMを使用しているため、通常はsSQLはありません)、sValueとformCollectionValue(または通常はsValueもありません。これらはたまたまMVCにあり、モデルバインディング機能を使用する必要があるためです。)、sTypeとpublishSourceなど。
それは読みやすさではありません。ハンガリー語で書かれたVB6の残りからのsTemp1、sTemp2 ... sTempNが他のすべての人よりも多いことがわかります。
これは、2のおかげです。これは誤りです。
マスターの言葉で:
http://www.joelonsoftware.com/articles/Wrong.html
いつものように、興味深い読み物。
抽出物:
「誰か、どこかで、シモニーの論文を読んだ。彼は「タイプ」という言葉を使い、コンパイラーが行う型チェックのように、型システムのようなクラスのような型を意味すると思った。彼はそうしなかった。彼が「タイプ」という言葉で何を意味していたかはわかりませんが、それは役に立ちませんでした。
「しかし、Appsハンガリー語には、コード内の配置を増やし、コードの読み取り、書き込み、デバッグ、保守を容易にし、最も重要なことに、間違ったコードを間違って見えるようにするという大きな価値があります。」
Joel On Softwareを読む前に、時間があることを確認してください。:)
いくつかの理由:
誰もがそれに激しく反対しているとは思いません。静的型のない言語では、これは非常に便利です。まだタイプに含まれていない情報を提供するために使用される場合、私は間違いなくそれを好みます。Cと同様に、char * szNameは、変数がnullで終了する文字列を参照することを示します(char *では暗黙的ではありません)。もちろん、typedefも役立ちます。
Joelは、ハンガリー語を使用して、変数がHTMLエンコードされているかどうかを判断する優れた記事を掲載しています。
http://www.joelonsoftware.com/articles/Wrong.html
とにかく、私の知っている情報を伝えるためにハンガリー語が使われると、私はハンガリー人を嫌う傾向があります。
もちろん、99%のプログラマーが何かに同意するとき、何かが間違っています。彼らがここで同意する理由は、彼らのほとんどがハンガリー語の表記法を正しく使用したことがないためです。
詳細な議論については、この件について私が作成したブログ投稿を参照します。
http://codingthriller.blogspot.com/2007/11/rediscovering-hungarian-notation.html
ハンガリー語の表記法は、特にMicrosoftによって悪用され、変数名よりも接頭辞が長くなり、特にタイプ(Win16では異なるタイプ/サイズの悪名高いlparam / wparam、Win32でも同じ)を変更した場合に、非常に厳密であることが示されました)。
したがって、この乱用とM $による使用の両方が原因で、それは役に立たないとされました。
私の仕事では、Javaでコーディングしますが、創始者はMFCの世界から来たので、同様のコードスタイルを使用します(中かっこを揃え、これが好きです!、メソッド名の大文字、それに慣れています、m_のような接頭辞をクラスメンバーに(フィールド)、静的メンバーへのs_など)。
そして、彼らはすべての変数がそのタイプを示すプレフィックスを持つべきだと言いました(例えば、BufferedReaderはbrDataと名付けられています)型は変更できるが名前が付いていないか、コーダーがこれらの接頭辞の使用に一貫性がないため(これはaBuffer、theProxyなども表示されます!)、これは悪いアイデアであると示されました。
個人的には、有用だと思ういくつかの接頭辞を選択しました。最も重要なのは、ブール変数に接頭辞を付けるbです。これは、if (bVar)
(一部の値のtrueまたはfalseへのオートキャストを使用しない)ような構文を許可する唯一の接頭辞であるためです。Cでコーディングするとき、後で解放する必要があることに注意して、mallocで割り当てられた変数のプレフィックスを使用しました。等。
したがって、基本的に、この表記を全体として拒否することはありませんが、自分のニーズに合っていると思われるものを採用しました。
そしてもちろん、プロジェクト(作業、オープンソース)に貢献するときは、規約をそのまま使用します!