トップ «前の日記(2004-03-17) 最新 次の日記(2004-03-19)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2004-03-18

_ COMの再入問題

Excelが終らない件とは関係ない話。

STAでメッセージポンプを回すCOMのサーバーを作ったとする。

HRESULT foo()

{

m_pOuterProcess->bar(); // 外部プロセスサーバーへ問い合わせ

return S_OK;

}

この場合、外部プロセスサーバーの呼出し中にメッセージポンプが回る。ここでは他のメッセージを受け入れる。なぜならば、コールバック(イベントの呼び出し)が行われる可能性があるから。

しかし、もし、fooというこのメソッドの呼び出しがシリアライズされなければならないとしたら、話がいきなり厄介になる。

同期させるわけだからと、

HRESULT foo()

{

m_criticalSection.lock();

m_pOuterProcess->bar(); // 外部プロセスサーバーへ問い合わせ

m_criticalSection.unlock();

return S_OK;

}

とやっても、なんの役にも立たない。というのは、STAなんだから、外部からの呼び出しは、このスレッドに対して行われるからだ。自スレッドの同期オブジェクトのロックは待ち状態になるわけにはいかないから単純にスルーされてしまう(ロックカウントは上がるはずだけど)。

つまり、再入されてしまう。

ここで、fooがインスタンス変数をいじるととてもまずいことになる。で、それに対応できない場合は、再入不可能だから気をつけて下さい、とクライアント側が同時に呼び出さないことを求めることになる。

これを回避するには、IMessageFilterインターフェイスを実装して、メッセージポンプに介入する必要がある。が、今度はデッドロックの可能性が出てくる。ASRですな。

_ ものを作るってこと

町工場・スーパーなものづくり (ちくまプリマーブックス)(小関 智弘)

まあ、とある事情があって、待ち状態になる機会が結構な頻度である。たまたま、数10冊ほど本が置いてあるから、最初のうちは矢野徹が翻訳(とは思えないから下訳の日本語化ということだろうが)した子供用モンテクリスト伯とか読んでたんだが、あるときから見えなくなったもんで、何気なく町工場がどうしたってのを読み始めた。

ら、こいつが結構、ツボにはまった。

たとえばこんなエピソード。

プロペラの依頼が来たんだが、すごく固い上に薄く削る必要があったり大変なんで、忘れちゃったけどなんかの合金で固めて旋盤かける方法を考え付いて(この合金がミソなんだが忘れた: 3/22追記 Uアロイという合金。なお、このエピソードは198898の本の中で、今から20年ほど前のこと、とされている。あおしまさんの指摘が正しいと思う。センジュはメーカー名だから)削ってたら、別の町工場の親父が見てる(町工場ってのは表から中が見えるらしい)。で、近づいてきて削られたクズをペロリとなめて、鉛が少ねぇな、だか、変な半田だな、とか(3/22追記 実際には噛んでみて「錫が少ねぇ」。錫は噛むと鳴るので熟練すると噛んだだけでわかるらしい。またその親父は勝手に覗いていたんではなく、まだ珍しかったNCマシンの見学のために来ていた)。

そんな芸当をするのは、年期が入った職人だけだから、そりゃまじめに相手をせざるを得ない。で、いや、こりゃ半田じゃなくて、プロペラ削るんでいろいろ探して見つけたなんちゃらって合金で、こいつを使うとこれこれって理由で具合がいいんだ。どう具合がいいかっていうと、最後の仕上げの時になにかをするとぱかっと割れてプロペラだけが取り出せる、とか説明すると、親父、そりゃいい話を聞かせてもらった、じゃ、おいらのやつも教えてやる。

新幹線の下につけるステンレスの箱を作れと依頼が来たんだが、話を聞くと箱じゃねぇ。穴がそこら中にあいてるから、早い話が網なんだな、これが。

で、穴をあけたらうまく折曲がらない。先に折ると穴がうまくあかねぇ。鉄板に付けたらうまく曲がるがうまく取れない。で、おめぇさんならどうする?

うーん、考えないとわからんな。

そうよ。で、おいらも考えながら歩いていたら、表具屋の店先ではたと気付いた。で、和紙を買ってきてだな、表具屋に張ってもらったのよ。これで自由に加工できるようになったってわけだ。ありゃ、丈夫だからな。で、最後は水にどぼんだ。

なるほど、そういや、障子の張り替えは昔は川でやったもんだったな。

そのとおり。お前さんのその合金と同じだよ。

Amazonのブックレビューを読むと眠たいことが書いてあるが、デペンデンシインジェクションとかハリウッドメソッドなんてのは、まさにこういうことだ。加工しにくい素材を扱う場合は、外し易い補助材を使うっていうデザインパターンだな(それだけじゃなくて素材の発見っていうストーリーもあるな)。

_ 今思ったこと

jni.hはきれいだ。
たとえば、jvalueという共用体が定義されているが、jdoubleはdだし、jintはiだ。
こういう名前って、センスが無いやつにやらせると平気でdoubleValueだのintValueだの馬鹿気た名前をつける。もっとも全体の長さに合わせるべきだから、java.lang.IntegerのintValueとかはしょうがないとは思うが。
というわけで、たまに、次のようなゴミのようなプログラムを見ることがある。
if (hoge) {
  long currentDepositAmount = accountInfo.getDepositAmount();
  newAccoutInfo.setDepositAmount(currentDepositAmount + ビジネスルール);
}
バカですか?
たかだか数行のスコープで、しかも、ゲッタとセッタのpublicメソッドから、何をつかんでいるかは明々白々にもかかわらず、long currentDepositAmountなんて馬のイバリみたいな名前をつけるなんて、なんの意味もありませんな。
もし、こう書かなければ理解できないとしたら、それを書いたヤツはpublicインターフェイスの名称がどういう意味を持つかわかってないと思いこんでいるのか、さもなきゃ、ソースを読むやつをバカにしているかのどちらかだ。
まともな人間なら、現在のアカウント情報に保持されている供託金を新規アカウントの供託金にビジネスルールを適用して突っ込んでるとわかる。もしわからないと仮定するのであれば、accountInfoだのgetDepositAmountだのって名称そのものがそもそも無意味だってことだ。
当然、こんな場合は
if (hoge) {
  long l = accountInfo.getDepositAmount();
  newAccoutInfo.setDepositAmount(l + ビジネスルール);
}
のほうが遙かに良い。こんな短いスコープの変数に時間を0.05秒でも余分に使う閑があったら、目でも休ませてなってことだ。
つまりだ、これは「メリハリ」をつけるってことだ。
子供の作文ってのがある。 「朝起きて、歯を磨いて、顔を洗って、ごはんを食べて、牛乳を飲んで、頭をかいて、靴下のにおいをかいで、猫を撫でて、ヘリコプターに乗って、へそでチャをわかして、学校に来て、先生に挨拶をして……」
すべてを同じ調子でやってたら、バグが入ってても見つけにくいじゃないか。
ここぞってとこは強調し、どうでも良いところは見えなくする。
それがメリハリをつけるってことだ。
ローカル変数なんてのは、そのブロック内だけでしか意味を持たないどうでも良いものなんだから、そんなものに有意味な名前をつけてはいけない。
もちろん、例外はあって、
for (int outer = 0; outer < dendekodennsuke.getFukusuke(); outer++) {
  for (int inner = 0; inner < denndekodensuke.denkihaTaisetuni(); inner++) {
 ....
 innerループがある特定の数でかつouterループの何番目かの時点では非常に特殊なことをする
 ...
  }
}
ってような場合に、int iとint jってのは「非常に特殊なこと」をする条件がわかりにくくなる。こんな場合には、コンテキストが明白になる名前をつけるべきだ。
しかし、「こんな場合には……べきだ」ってのはルールとするのは曖昧だ。
曖昧なことはルール化できない。であれば、原則論を主としなきゃならないのは当然の帰結となる。
したがって、ローカル変数は、1文字か2文字にして、ブロック毎に作れ。ブロックはできるだけ5行長くても10行。それを越えたらルールを単位としたメソッドとして別立てにし、メソッドコメントとしてルールを記述せよ、ってことになる。ちなみにメソッドレベルのローカル変数はもうちょっと長くしたほうが良い。この例だとdepositAmtとか。まあ、currentDpositAmountでもいいけど。でもdepositは長すぎるから3文字短縮語辞書を作っておいたほうがいいだろうな。curDepAmtとかだな。つまり、3文字略語の複合がメソッドレベルのローカル変数にはちょうどリズムが良い。
まあ、ローカル変数名が5文字を越えてたら、バグの前兆ってことだ。

_ 1文字変数名の規則

i, j これは古いFortlan(綴り忘れたから違うような)から持ち込まれた由緒正しい変数名の規約で、整数に使用する。その後、iterationの意味も含まれるようになったため、for文のインデックス値に利用する。

c これは一般には文字に使用するが、別解として、counterの略でint c = 0; ... c++;なものに(iterationの場合は、i)に利用する。

ただし、C/C++のようにポインタのサイズが重要になる場合には、

cb (counter of bytes), ci (counter of ints), cs (counter of shorts)などとする。このへんは由緒正しいハンガリアン由来。

n ニューメリック一般だが、iがiterationに取られるため、intを示す。

o, d, f, l わからないやつは言語仕様を読め。というくらい当然のように利用する。

p pで始まるすべてだが、oと異なり途中で参照が変更される可能性を持つオブジェクトを示す場合に使用する。

e 例外

r rで始まるすべてだが、特にレコードの概念を示す場合に利用する。

f これはboolean。bはbyteに利用する。この場合のfはflag valueの意味。これも由緒正しいハンガリアン由来。ただしFileの概念を持つ場合にはそちらに優先的に与え、同一ブロック内で真偽値が必要になる場合には、例外として意味的な名称(continueToReadなど)を真偽値に与える。というか、制御に利用する変数名は実際には長い名前にしたほうが良い。そのほうが妙な修正による誤った流用を回避できる。ただし、つい流用したくなるってのはブロックがでか過ぎる証拠。

x, y, z ……i, j が不足した場合に利用しても良いが、そんなにfor文を重ねてはいけない。むしろ、数値計算の過程で利用する。

np, lp, これは使うべきではない。あまりにも歴史的。

これ以上ローカル変数が必要になるとしたら、書き方がおかしい。それはブロックやメソッドを分割しなければならない。

追記:まあ、まじめに考えればすぐにわかることだが、オブジェクトはアイデンティティによって区別されるんであって、変数名で区別されるわけじゃない。そこがわからないと馬子にも衣装とばかりに変数名に凝ってしまうんだろう。だが、値が入ってるならともかく(というか、値自体がテンポラリな存在なわけで)しょせん参照に過ぎないわけで、まったくオブジェクトそのものとは関係は無いわけだ。したがって、読みやすさと記述力を優先するのは当然。

_ >900

よっしゃわかった。じゃあ、longの先頭2文字で

long lO = 10;

とか(大文字のOは勘弁だな)。

#実際には、longを取る値であれば、入る内容の略語を使ってcntとかamtとかqtyとかすることが個人的には多い気がする。あと、ニュートラルな場合(intでもlongでもどっちでもいいけど大きいことはいいことだでlongとなっているような場合)にはnが多いな。

ちなみに、jni.hでは、jobjectがlで、jlongはj (iの次だからか?)となっている。

っていうか、ローカル変数まで長い名前を付けたがるのは、メインフレーム方面から流れてきた連中なんじゃなかろうか。だから、Sunのコーディング規約(多少のブレはあるが、Unix流儀)に文句をつけるんじゃなかろうかね。

古いCOBOLにはローカル変数っていう概念がないから、なんでもかんでもグローバルな変数と同一の流儀で変数名をつけようとしでかすんじゃなかろうか。

ちゃんとスコープを理解してるのかなぁ。

略語の問題は、人によってln, len, lgth, lg, とかいろいろあるから困ると言われているが、スコープが限定された変数はなんでも良いってのが最初にあるわけだから、どれでも構わない。つまり、困らない。

あたりまえだが、インターフェイス名やそのメソッド名にCalAMt#ccとかするのはだめでしょう。やっぱりCalendarAmateur#CCompileとか付けなければわからないし。

本日のツッコミ(全24件) [ツッコミを入れる]
_ なひ (2004-03-18 13:08)

略語禁止。

_ arton (2004-03-18 13:28)

略語ガンガン。

_ arton (2004-03-18 13:35)

ちなみに、ちゃんとディクショナリーがあるから、なひさんが読む場合は、フィルターを通すことで、50文字くらいの変数名がちゃんと生成されるんで大丈夫でしょう。ActualSalesUnitPrice.Quantity.MeasurementOfQuantityとか。

_ なひ (2004-03-18 13:58)

略さずにかつ短いのが理想、長いのはbad smellでリファクタリングのチャンス、というのがなひの立場です。静的に型付けされる言語では型の名前も活用できますね。

_ arton (2004-03-18 14:57)

あ、それは理想。問題は、XMLボキャブラリーと一致させたい場合。本当に、MeasurementOfQuantityみたいな要素名の3段重ねとかあるんですよ。<br>というのとは別に、ブロックレベル=文字レベル、メソッドレベル=略語レベル、クラスレベル=フルスペルっていうスコープと文字数の見た目の一致はソースの読みやすさに大きく貢献すると実際に読んでいて感じてるけど。ちなみにブロックレベルでもlenは3文字もあってすごく長いけど慣習上、許可してます。

_ あおしま (2004-03-18 22:33)

センジュアロイですよね?<br>お湯で解けるほどの低融点なので加工後にお湯に漬けて<br>融けたのを回収するとか。ハンズなんかでも売ってたと思います。<br>http://www.senju-m.co.jp/j/index.htm

_ あおしま (2004-03-18 22:34)

http://www.zairyo-ya.com/product_u-aloy.htm

_ arton (2004-03-18 22:42)

そんなやつです。どうもそのページにはセンジュアロイってのは出てないみたいですが、お湯につければ融けるし、また使えるというようなことが書いてあったのでそれだと思います。

_ arton (2004-03-18 22:47)

ありがとうございます。そうそう、スプリンクラーヘッドに使われているのを見つけてとかあったような……なんでスプリンクラーヘッドなんだろう?

_ wildcats (2004-03-18 23:17)

s/Fortlan/Fortran/<br><br>ローカル変数の命名はオブジェクトだと特に悩まないんですけど、プリミティブは名前付けのセンスが無いので若干悩んだりします。<br>longはだいたいlngとかってつけたりしますかね?(ダサ)<br>intのループ変数はi,j,kだけど意味合いを持たせるような場合は一応名前考えています(^^;<br>ただ個人的にはあまり略語は好まないタイプなほうです。

_ sugi (2004-03-18 23:26)

自分の場合、非複合語(単独の単語)なら、<br>思いきって1字にするか全く略さないかのどちらかですね。<br>3文字略語にはどうしても違和感を感じてしまって、<br>cntみたいなのがあると、どうしてもそこで一瞬止まってしまいます。<br><br>あ、でもlenとかstrとかmsgは違和感ないな…

_ kjana (2004-03-18 23:29)

i, j, k.... は数学屋の記法から来てて、Fortran の暗黙の型指定はそれをなぞったもの、<br>っていう意見をつい最近どこかで見ました。何で i かと言うと多分 index の i。

_ arton (2004-03-19 00:10)

コメントありがとうございます。<br>>lng<br>いいんじゃないですか。char chが許される(少なくても僕は許します)んだから。<br>#やっぱり、略語は人気ないですね。<br>>非複合語<br>それも一理あると思います。<br>>数学屋の記法から<br>そうなんですか(う、やっぱりrだったか)。indexのiというのはすごく納得です。iterationのiっていうのは2chで見かけて実は違和感を覚えたから逆に鮮明だっていうのがあって。

_ えぐち (2004-03-19 11:45)

ウッド合金では、ビスマス/鉛/錫/カドミウムの合金です。<br>でも半田とは間違えないし、最後の成分が舐めるのには向いてません。

_ arton (2004-03-19 13:59)

今度の月曜に、またそこ行くので、実際の合金名を覚えてきて追記しておきます。<br>#でもね、ここで重要な点(僕がこの本を読んでツボを突かれた点)は、別の開発者のマシンの前を通りかかったら妙なクラス構成を取ってるので訊いてみたら……で、デザインパターンの発見をお互いに確認するっていようなのに通じる世界なんだな、というような似たような世界を思いもかけぬ場で見つけた親近感であるとか、するってことは職人大いに結構ですなとか、ではそれをいかに形式知にすることが可能か(おいらはライターでもあるから)とか、そっちなんだけどね。

_ えぐち (2004-03-19 16:33)

本題と離れたところですみません。>合金名<br>職人は「技を盗んで憶える」という面もあるので形式知とは対極にあるようにも思えます。<br>#和算の一子相伝みたいに

_ arton (2004-03-19 18:34)

違うのではないですか? 形式知化する価値がないために、盗んで覚えろというように方法論の確立を放棄しただけだと思いますよ(教育コストに見合わないのは、見習いのうちは無料で使える労働力だったという点があり、戦前の悪習として8年という奉公期間について該当書では論難しています)。<br>和算はわかりませんが、戦国時代には一子相伝であった剣法にしても市場が成熟した幕末では町人に教える町道場が盛んになったように教育産業が成立できなかったのも原因ではないかと思います。

_ えぐち (2004-03-21 09:51)

「形式知とは対極」は曖昧な言い方でした。「暗黙知の典型」と言う意味です。形式知は暗黙知をマニュアル/特許/標準などの形で文書にしたもの・する事と言う理解で言えば、一子相伝も媒介に「虎の巻」があれば立派な形式知ですね。

_ arton (2004-03-21 17:03)

そんなに突き詰めて結論を出すつもりはないのですが、僕は以下のように考えています。<br>・町工場の親父たちとプログラマー(設計含む)の共通点:確かにセンスという変な言葉でくくられる形式化不能な領域はある。<br>・しかし、それがすべてではない。該当書では、実際には入門3年で(忘れた。胡蝶削りっていったかな? 旋盤の面を微細に削る技法)をマスターさせてうまくやっている町工場の話とか、引用した加工しにくい素材の取り扱いパターンの情報交換の話のように、こちらの思い込み(まさに町工場の旋盤工ってのは暗黙知の典型――だってそういう語られ方が多いわけだし)と異なる世界を見せてくれる<br> で、結論として、該当書はおもしろい=ツボにはまった、となるのです。

_ arton (2004-03-21 17:07)

つまり、町工場の職人=暗黙知の典型という認識をしているからこそ、『町工場スーパーなものつくり』はその認識を砕き、新たな発見を強い、翻ってこちらの仕事のありようを見直すきっかけとなる、非常に優れた書物だといっても良いでしょう。一読をお勧めします。

_ Wankotank (2004-03-22 10:45)

3文字短縮はいくない。<br>自分だけが見るならいいけど、他人の3文字はまったくわからん。短縮だけは勘弁してください。

_ arton (2004-03-22 13:52)

はいはい。あなたには特別に、StructuredQueryLanguageExceptionというクラスを作ってあげるので、それで例外処理してください。頼みます。

_ arton (2004-03-22 13:57)

それはそれとして、なかなか雰囲気があるIDでいいなぁ。なんか元ネタがあるの? それともオリジナル? >Wankotank

_ arton (2004-03-22 22:59)

しかし、IDはしゃれているが、ちゃんと読みなよ。寂しいね。<br>int lgt = "foobar".length();<br>って文脈の話をしてるのに、「まったくわからん」はないだろ?


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|

ジェズイットを見習え