- PR -

shared な変数の参照

投稿者投稿内容
セラフ
ベテラン
会議室デビュー日: 2005/12/01
投稿数: 95
お住まい・勤務地: 東北の顔の形といえば
投稿日時: 2009-01-08 13:17
また未記入氏に怒られそうだが、Wikipediaではこんな定義も見受けられます。

ハンガリアン記法

「目的」を名前に含める方式(アプリケーションハンガリアン)と、「データ型」を名前に含める(システムハンガリアン)に分けられる

だそうです。「分けられる」って事は背反の関係だと思いますが、このスレッドのアプリケーションハンガリアンとシステムハンガリアンの定義とは違うようなので、こんな考え方もあるようですぐらいの発言の意図です。
ぼのぼの
ぬし
会議室デビュー日: 2004/09/16
投稿数: 544
投稿日時: 2009-01-08 23:38
なんか未記入さんの疑問が解決されないままに流れをぶった切るような発言をするのは心苦しい部分もあるのですが、自分の考えをまとめてみたくなったので空気を読まずに投稿します。

>他の方々
もしローカルで未記入さんの質問に対する回答をまとめられてる最中でしたら、私の発言は気にしないで頂いて結構です。


前の投稿で、「ハンガリアンに関しては、私の認識は未記入さんのに近い」と書きましたが、違うところが出てきました。

まず、同じ認識なのはまとめると以下のとこです。
  • 型だけでなくスコープやアクセス修飾子など言語仕様で規定されるシステマチックな要素を接頭辞にすることはシステムハンガリアンだ
  • アプリケーションハンガリアンとは、言語仕様などに基づいておのずと決まるものではなく、システム設計ドメインで定義しないといけない接頭辞のこと
  • 「何でもかんでもに付けるのではなく、区別しなければならないものにだけ付けます」を実践するとアプリケーションハンガリアンになるなんて主張はトンデモナイ(一部のものにだけ付けてもシステムハンガリアンはシステムハンガリアンだ)

で、違うとこは以下のとこです。
  • システムハンガリアンを使うべきではない

くれぐれも誤解しないで頂きたいのですが、単に「システムハンガリアンを使っても良い」という主張ではありません。簡単にまとめると
  • そのメリット・デメリットをしっかり理解した上で、デメリットを抑えるよう工夫されたルールなら、それが結果的にシステムハンガリアンであったとしても使って良い

となります。じゃあデメリットは何かって言うと、wikipediaからそのまま引用。
  • システムハンガリアンを使っているソースコードを修正してデータ型を変更した際、同時に変数名も変更するコストがかかる。変更を怠ると、たちまち不整合となり,保守の障害となるだけで一利もない。
  • システムハンガリアンに慣れているプログラマ以外にとっては可読性の低い記法である。
  • C++やC# のような言語では型付けが存在するためにシステムハンガリアンを使用することによる利点はない。
  • 移植性を阻害する。

まぁまさにその通りって感じのものばかりですが。

じゃあこれらのデメリットを抑える工夫ってのはどういったものかというと。

システムハンガリアンで接頭辞とする型に関しては、char*とかVectorとか言語依存度の強いものを使うのはNG。文字列・数値・真偽値など保守・移植の際使用する可能性のある言語の範囲内で共通している基本的なものに限る。
また、接頭辞は言語依存にならないように抽象的な名前を使う。例えば、CollectionとListとArrayにcoll,list.arrという別々の接頭辞を使うのはNG。
静的メンバにs_をつけたりインスタンスメンバにm_をつけたりするのもこの範疇に収まるのならOK。

といっても、型付けのある言語なら無理して使う必要は全然無いと思いますけどね。型付けのない、あるいは希薄な、旧VBとかスクリプト系の言語ではシステムハンガリアンはそれなりのメリットをもたらしてくれると思います。


また、アプリケーションハンガリアンにも些細なデメリットがあります。
アプリケーションハンガリアンで接頭辞とするのは意味や使用目的だとされてますが、これは通常変数名そのものを命名するときにも使うものです。なので、単一の意味や使用目的しか持たない変数は、接頭辞だけで変数名として完結してしまう。
なので、下手に全変数に適用するルールにしちゃうと、接頭辞だけで終わらせるわけにはいかないからじゃあ何つけようかってのを考えるのに余計な時間をとられたり、無意味な単語を無理矢理ひっつけちゃったり。システムハンガリアンの接頭辞とその後の部分を左右入れ替えただけみたいな名前になっちゃったり。
#よく考えたら私もworkStrとか普通に使ってますわw


なので、盲目的にアプリケーションハンガリアンは良いもの、システムハンガリアンは悪いものってわけでもないと思うのですよ。これは別にハンガリアンに限った話じゃないですが、どんな良い規則でも、あるいは悪い規則でも、使い方次第でって部分は少なからずありますやね。


最後に、「アプリケーション ハンガリアンは、間違えたコードを間違えて見えるようにする記法である。」という一文について。
これも、wikipediaの情報を単にまとめただけのものですが。

(1)シモニーさんが間違えたコードを間違えて見えるようにする記法を考えた
(2)どっかの誰かが誤解釈して考案者の意図とは違う使い方をした
(3)(1)をアプリケーションハンガリアン、(2)をシステムハンガリアンと呼んで区別する

で、自然に考えて、(2)の誰かがどうして(1)を採用したかっていうと、間違えたコードを間違えて見えるようにしたかったからですよね。
よって、システムハンガリアンも間違えたコードを間違えて見えるようにする記法たることを目的として当初は採用されたはずなのです。
そして、それが誤用だと気づかれないままある程度の量のソースコードが生産されたということは、部分的にはシステムハンガリアンもその目的を達成していたと考えられます。

従って、システムハンガリアンも「間違えたコードを間違えて見えるようにする」という特性を部分的には持っているのだと思います。前述したようなデメリットがあるためイコールで繋がるようなものではないですけどね。
未記入
大ベテラン
会議室デビュー日: 2008/02/07
投稿数: 115
投稿日時: 2009-01-09 09:38
引用:

で、違うとこは以下のとこです。
  • システムハンガリアンを使うべきではない




私の書き方が悪かったですね。説明不足でした。すみません。私も原理主義的にシステムハンガリアンの使用を禁止するという立場をとるつもりはありません。ぼのぼのさんが挙げているいくつかの例のようにシステムハンガリアンを使うのが妥当なケースもあると考えています。

実際に私自身もシステムハンガリアンを使います。私の場合は、変数名のベース部分が重複するような場合に、システムハンガリアンを使うことが多いですね。int hogeCode があるときに、これをゼロフィルした文字列表現を保持する変数が必要になった場合、sHogeCode としたり、実数表現と整数表現が同時に出てくる(ベース部分が同じ)ときに、dHoge と iHoge としたりします。

引用:

char*とかVectorとか言語依存度の強いものを使うのはNG。
CollectionとListとArrayにcoll,list.arrという別々の接頭辞を使うのはNG。


ぼのぼのさんもこのように書かれていますけど「絶対に使ってはいけない」という原理主義的な主張として「NG」と書いたのではありませんよね?あくまで原則論として NG と書いていると思います。私の書いた「使うべきではない」というのは、ぼのぼのさんが書いた「NG」と同じニュアンスだと思ってもらえば分かりやすいんじゃないでしょうか。

引用:

これは別にハンガリアンに限った話じゃないですが、どんな良い規則でも、あるいは悪い規則でも、使い方次第でって部分は少なからずありますやね。


goto の是非なんかも似たような話ですね。原則論として「gotoを使うべきではない」は正しいと思いますが、多重ループからの脱出など goto の使用がスマートな場面もありますから原理主義的に「一切 goto を使ってはいけない」という主張が出てくると議論になったりしますね。

他にはこれといって書くこともありません。ぼのぼのさんの書かれていることに全面的に同意です。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2009-01-09 13:45
記法Aが広義ハンガリアンであることをみたし、
あるアプリケーションにおいて、記法Aが間違えたコードを間違えて見えるようにしている場合、
記法Aのことをアプリケーションハンガリアンと呼ぶ、と理解しています。
「あるアプリケーション」は具体的過ぎますが、「あるチーム」とかでもよいでしょうか。
(「上記のようなアプリケーションが存在する場合、記法Aをどこでもアプリケーションハンガリアンとよぶ」という意味ではありません。)

引用:
で、自然に考えて、(2)の誰かがどうして(1)を採用したかっていうと、間違えたコードを間違えて見えるようにしたかったからですよね。
よって、システムハンガリアンも間違えたコードを間違えて見えるようにする記法たることを目的として当初は採用されたはずなのです。
そして、それが誤用だと気づかれないままある程度の量のソースコードが生産されたということは、部分的にはシステムハンガリアンもその目的を達成していたと考えられます。

私もそうおもいます。大雑把な言い方ですが、システムハンガリアンがかならず
アプリケーションハンガリアンだったときがあったといえるかもしれません。
(だからこそ、間違って広がったとも考えられます)
この場合「システムハンガリアンを使うべきではない」は確かに無意味であり、
実際「使ってよい」が優先されていました。

余談ですが、誰が作成したものかを表す接頭辞をつけた場合、これが間違いに気づかせるものでなければ
システムハンガリアンでもアプリケーションハンガリアンでもないハンガリアンだと思います。
(これを変数名に適用するのは現実的じゃないですが、社内で作ったクラスには必ずこの接頭辞をつける、
みたいなルールは何度か直面しています)

ハンガリアン自体このスレッドの主題ではないのであまり深くは書きません。

どんな方法(記法に限らず)でも重要なのは「メリットがあるかどうか」や
「メリットとデメリットのトレードオフを考えること」だと思います。
武史さんがローカル変数とSharedな変数の区別をつけたいのは、間違いに気づきやすくしたいというのが
理由のひとつにあると思いましたが、それでもメリットが見出せないものやデメリットのほうが
大きいものは、使ってよいという考え方が一般的かにかかわらず、使わない方がいいわけです。

実際「アクセス用のプロパティが趣旨にあうかもしれない」という考えにいたっていますね。
ところでこれは、どうやってアクセスするのか、どう区別するか(大文字はじまりか、小文字で区別できるからOK?)、
という考慮は必要な気がします。
未記入
大ベテラン
会議室デビュー日: 2008/02/07
投稿数: 115
投稿日時: 2009-01-09 15:34
引用:

システムハンガリアンでもアプリケーションハンガリアンでもないハンガリアン


そんなものは存在しません。それはただの接頭辞といいます。識別子を命名するときにサイコロを振って、無作為に a 〜 f の記号を先頭に付けたとしましょう。これは その他のハンガリアン ではなく、ただの接頭辞です。
武史
ベテラン
会議室デビュー日: 2007/09/21
投稿数: 71
投稿日時: 2009-01-09 17:03
さて、Me を使うのが大好きな私が言うのもなんですが、
インスタンス変数か、静的変数かどうかを区別するのは、
Jitta 氏も、「初級プログラマーにとってのみ、
s_ をつけるのは、アプリケーションハンガリアンである」という主旨の
事をおっしゃっていますし
Me をつけるか、クラス名をつけるかで判別すべきというのが、
ここまでの一定の結論として出ているのではないでしょうか。


引用:

べるさんの書き込み (2009-01-07 23:16) より:
もっとも、「誤りである」というものが機械的に定義できない以上は、
その1行が誤りであるかどうかは明確に定義できないと思います。

年をあらわす変数に y 接頭辞、月をあらわす変数に m 接頭辞をつけたとします。
普通、yValue1 + mValue2 のような演算は誤りだと判断できますが、
(占いかなんかで)誕生日の「年」と「月」を足すこともあるかもしれません。



例えば、ポインタに int を足すのは誤りでしょうか?
これは、年と月を足すようなものと似た面があると考えます。

つまり、必要のあるケースがある事は否定しないが、一般的には、
誤りであるなど、慎重に行うべきケースが多いという事です。
実際、IntPtr と、Integer の加算はできなくなっています。

そのため、先ほどの例については、アプリケーションハンガリアンを
利用するプロジェクトでは、コメントでしっかり書くか、
コード:
Total = CType( yValue1, Integer ) + CType( mValue2, Integer )


などと、するべきかと思います。


逆に、異なる接頭辞の演算が実際に誤りでない場合があるのは、確かです。
コード:
usString = sString1 & usString1 ' unsafe と、safe の文字列の連結だが、unsafe に代入しているので正しい。
wxPos = wxPos1 + dxSize ' Window 内座標と、幅の加算なので正しい。


また、同じ接頭辞の演算が誤りである場合もあります。
コード:
wxPos = wxPos1 + wxPos2 ' Window 内座標同士の加算は意味がない。




逆にシステムハンガリアンが、開発環境などの発達で不要になってきたように、
アプリケーションハンガリアンも、そのうち不要なものになってしまうのかも
しれないし。

例えば、
コード:
int with meter Length;   // メートルであらわした長さ
int with doller Price;   // ドルであらわした価格


とか。


IntPtr などもよい例の一つだと思います。
単なるポインタといういろんなものがあってややこしい型でしたが、
SafeFileHandle など、その意味が型の中に含まれてきています。

Safe, Unsafe なんてのも、アプリケーションハンガリアンを
使用すべきかと思いますが、本当は言語系で実装できると
いいですよね。taintperl なんて実装もありますし。


私は、「システムハンガリアンが、オリジナルの誤解で、
アプリケーションハンガリアンが正しい」
というのを、散見しますが、これこそが誤解だと思っています。

昔の C は、数値も、文字列も、ハンドルも全部 int 互換だったから、
システムハンガリアンが有用だったわけで。
だから、もとのハンガリアンの誤用でなく、応用だったと思っています。

むしろ、「システムハンガリアンは、オリジナルの応用で、
アプリケーションハンガリアンは、コンパイラの発展に伴って、
たまたま原点回帰しただけ」ではないでしょうか?


ちなみに、私はアプリケーションハンガリアンは、原則反対派です。
セラフ
ベテラン
会議室デビュー日: 2005/12/01
投稿数: 95
お住まい・勤務地: 東北の顔の形といえば
投稿日時: 2009-01-09 17:30
引用:

武史さんの書き込み (2009-01-09 17:03) より:
Me をつけるか、クラス名をつけるかで判別すべきというのが、
ここまでの一定の結論として出ているのではないでしょうか。




そこは違うと思います・・・

引用:

ぼのぼのさんの書き込み (2009-01-07 03:45) より:
元々は、ローカル変数とインスタンスメンバと静的メンバを見分けやすくしたいってとこから始まってるわけですよね。

で、武史さんは、静的メンバとローカル変数で記法をそろえるよりインスタンスメンバと静的メンバで記法をそろえる方が良いと思い、2003ではMeで見分けていたのですね。

私は、静的メンバにMeでアクセスすることにはすごく違和感を感じます。

なぜなら、冒頭でじゃんぬさんも触れられてる通り、Meは自のクラスのインスタンスを示すので、インスタンス化しなくてもアクセスできる静的フィールドは、領域的にMeの外側にいるわけで。意味合い的には2003のMeでアクセスできてしまう仕様は変で、警告が出るようになったのは改善だと思ってます。



のとおり、Meは自クラスのインスタンスを示すが一般的な考え方だと思うので、Meをつけるのはあまりお勧めしないってのが共通の認識のような気がしますが・・・そう思ってるのは私だけ??

というか、私的にはJitta氏の発言は、武史氏の「どうしても分けたい」をベースに
「静的変数をどうしても区別したい人にとってはアプリケーションハンガリアン」が結局言いたいことだと好意的に解釈しました。「初級プログラマーにとってのみ」ってのはちょっと表現があれです

そもそも、クラス名をつけて区別するのが唯一議論をよばない=みんなが幸せになれる答えのような気がします。
未記入
大ベテラン
会議室デビュー日: 2008/02/07
投稿数: 115
投稿日時: 2009-01-09 19:40
まず、はじめに言っておきますけど、セラフさんをイジメたいわけじゃないんですよ。退場して欲しいとかお気の毒なことを言われても意見を出す姿勢は決して嫌いではありません。

だけど、セラフさんまた誤読しているようなので指摘しておきます。

引用:

そこは違うと思います・・・


ここは、「静的メンバに Me かクラス名を付ける」ということを言っているのではないのです。良く読んでください。

引用:

インスタンス変数か、静的変数かどうかを区別するのは、(省略) Me をつけるか、クラス名をつけるかで判別すべき



「インスタンス変数の場合は Me を付け、静的変数の場合にはクラスメイを付けて区別する」と読むほうが妥当です。いままでの武史さんの発言からも Me にこだわり続けているようには思えませんから。

スキルアップ/キャリアアップ(JOB@IT)