雑な k|m の生態について

その1 - はじめます

2002-04-29

ニッチの極み

Apple - eMac

ご覧の通り,教育用マッキントッシュ です。頭に e がつくからと言って決して電子マッキントッシュではありません。

ていうか,またぞろ随分と狭い市場を狙った製品だと思いませんか。今やパーソナルコンピュータと言えば (ちょっと悔しい気もするけど) Windows。マッキントッシャーの方々はちょっと肩身の狭い思い。それに加えて「教育現場」と空間を限定。そこにちょっと倉庫に眠っているような iMac を置くならまだしも,さらに市場を狭めるべく「教育用モデル」ですよアンタ。そういえば富士通さんはその昔「白い FM-TOWNS 教育用特別モデル」なるものを出していましたが,その後瞬く間に FM-TOWNS ごと Windows に潰されてしまいましたね。

実は上の記事をまだじっくり読んでないんですが,これでどんな教育を行うのかに興味があります。まさか,Objective-C !?

[ 電子マッキントッシュではありません ]
どうも人生最大の間違いを犯した気がするんだけど,気のせいです。きっと。

2002-04-28

お前ら! 漏れの遺伝子を見てください。

セレラ社 ── 2年ほど前,ヒトの DNA の塩基配列の読み取りを終了したことで一躍有名になっちゃった会社です。そしてその2ヵ月後,(元)社長グレーグ・ベンター氏は「遺伝子情報は保護されるよう法制化するべきだ」とも発言。

そんな(元)社長がついにカミングアウト。米セレラで読み取った塩基配列は,なんと(元)社長自身のものだったとか。曰く,「遺伝子のプライバシーが暴かれるというリスクは自分が負うべきだ」と。

研究者としては至極当然な事に聞こえます。が,その当然な事さえ実行しない似非研究者が跋扈,新聞の1面を飾ることも少なくない今日び,この(元)社長の発言のなんたる輝きよ。がんばれ(元)社長! 負けるな(元)社長! 今は何をやってる人ですか(元)社長!?

[ 今は何を... ]
名誉会長くらいにはなってるのかなあ?

EUC にしろとあれほど口を酸っぱく

遺伝子とはまったく関係ない話になりますが・・。

どうも私には極力色んな環境でも動くようなコードを書いてしまうクセがあるようです。これはある部分ではすごく大事なことですが,仕事等で環境が限定されている場合はまれに混乱を招いてしまう悪いクセ。早く治さないとね。

さて,今やっている仕事で書いたのはこんなコード。

ファイル SysUtils.pm
package SysUtils;

# 文字コードを得る
sub getCharset {

	# SysUtils.pm の文字コードを返す
	if ('あ' =~ /\x82\xa0/) {
		'Shift_JIS';
	}else{
		'EUC-JP';
	}
}

sub confirmCharset {
	my $japanese_a = shift;  # 'あ' を入力

	# 文字コードの整合性確認
	# この関数を呼び出したファイルと SysUtils.pm とで
	# 使用している文字コードが違えば
	# エラーとする
	if ('あ' ne $japanese_a) {
		writeLog((caller)[1], '文字コードが違う');
		return 0;
	}

	# 文字コードOK
	return 1;
}
ファイル something_*.cgi
use SysUtils;

my $gCharset = SysUtils::getCharset();
SysUtils::confirmCharset('あ');  # 私のミス

print "Content-type: text/html;chaset=$gCharset\n\n";

print qq!<html><head>!;
print qq!<meta http-equiv="Content-type"!;
print qq! content="text/html;charset=$gCharset">!;
# (以下略)

something_*.cgi は全部で 6 ファイル。全てのファイルに,いちいちファイル自身の文字コードを確認するコードを埋め込むのが億劫だったので,すべて SysUtils::getCharset() に任せてしまいました。

ならば当然,something_*.cgi と SysUtils.pm は使用する文字コードが同じでなければなりません。SysUtils::confirmCharset() はそれを確認する関数。お互いに使用している文字コードが違えば,ログを出力して 0 を返します。ちなみにログを出力する際,第1引数に渡しているのは (caller)[1],つまりこの関数を呼び出したファイル名です。

以上の仕組みにより,シフト JIS コードでサーバにアップロードされれば charset として "Shift_JIS" を,EUC-JP でアップロードされれば "EUC-JP" を自動で出力できるのです。

ここで「# 私のミス」注目。こんなにも文字コードに関して几帳面な処理を行うのならば,confirmCharset() に失敗した時点で処理を続行するべきではありません。しかし「どうせヘンな部分があればログで確認できるし」と,ほんのわずかなコード "or die;" を書かないまま相手先に提出してしまったのです。これは完全に私のミスでした。

[ クセ ]
しかも私の腕は中途半端であるため,実際に別の環境で動かそうとしても動かないというオマケつき。

混乱開始

相手先からメールが来たらしいです。

『代表』の部分が文字化けしています

私のファースト・インスピレーション:

・・あんた,シロウトですか・・

確か,相手方は Perl も C もよく知っていると聞いた気が・・・。少なくとも Perl や C 言語,Java に長く携わっている人間ならば,シフト JIS の「¥」問題はよくご存知のはず。つまり今回の文字化けも,シフト JIS のまま動かしていることが原因であることにどうして気づきませんか。

いやしかし私の常識は世間の非常識。私がちゃんと出力文字を「代表\取締役」と書いておけばよかったのかも知れません。・・いやいやしかししかしプログラマは面倒くさがりでなければなりません。別の解決策 ── すなわち全てのファイルの文字コードを EUC-JP に変換してやることで解決できるならば,その方法で解決してもらうに越したことはないのです。

全てのファイルの」・・これ重要。something_*.cgi も SysUtils.pm も,という意味です。

早速,その旨を伝えるメールを出したようです。そしてまた相手先から返信。

やはり全体的に文字化けを起こしています。

むーん,こちらの環境では再現しない・・。本当にきちんと全てのファイルを EUC-JP に変換したのかな? そのことに注意するよう指示,そしてまた返信の模様。

文字化けを起こします。出力は EUC-JP ですが,meta タグで charset=Shift_JIS となっていることが原因と思われます。

そして私の脊髄反射:

おいっ!

これは明らかに SysUtils.pm がシフト JIS のままであることの証拠。そこらへんについて重点的にツッコミを入れて,事態はようやく落ち着いたようです。

結局アレですか。私が "or die;" を書かなかったばっかりに余計な混乱を招いてしまったようです。何も出力されなければ,何も文字化けを起こしません。簡単なコトだったのに・・。

[ らしいです ]
一部の文章に推量の助詞が組み込まれているのは,私は相手先と直接メールをやりとりしていないから。どこの世界でも「現場」なんてこんなもの。

今さらながら,最良の手段

当初,私は confirmCharset() 関数を書いていませんでした。後になって「そういえば,全てのファイルで文字コードが統一されていなければイカンなあ」と気づいたのです。だから↑あ〜んなコードを書いちゃったわけで,しかも中途半端なコトをしでかしてしまいました。

最良のコードは getCharset()confirmCharset() をまとめた↓こんな感じっすよね。

package SysUtils;

sub getCharset {
	my $japanese_a = shift;  # 必ず'あ'を入力

	# SysUtils.pm と同じ文字コードか?
	if ($japanese_a ne 'あ') {
		writeLog((caller)[1], '文字コード違う');
		return undef;  # 未定義値を返す
	}

	# 文字コードを返す
	if ('あ' =~ /\x82\xa0/) {
		'Shift_JIS';
	}else{
		'EUC-JP';
	}
}
use strict;
use SysUtils;

my $gCharset = SysUtils::getCharset('あ') or die;

# 以下略

関数に失敗すれば $gCharset は未定義になります。もし "or die;" がなくても,use strict; の働きにより $gCharset を使おうとした時点でウォーニング。うーんスッキリバッチリ。これでいこう。・・・実は全てのコードの提出期限は5月2日なのです。今からでも間に合います。うひひ。

2002-04-27

goo ドメイン問題

局 goo.co.jp ドメイン騒動は NTT-X さんの主張が認められました。goo.co.jp 保有者さん最後の叫びが虚しく響きます。

今回の "元" goo.co.jp ドメイン保有者さんの失敗は何だったのでしょう? 確かに元ドメイン保有者さんは "goo 株式会社" 等のように,goo に関連する社名を持っているわけではありません。しかしそんなことでドメインを奪われてはたまらないし,NTT-X さんだって社名に "goo" をつけて活動しているわけでも無さそうです。お互いに条件は一緒,いやむしろ,元ドメイン保有者さんの方が先にドメインを登録していました──無論,goo というナビゲーションサービスが登場する以前に。

きっとこれは元ドメイン保有者さんがドメインについて余程トンデモな扱いをしていたに違いありません。そうでないのにこんな判決を出されるのは困りますもんね。

最近の goo.CO.jp はよくわかんないサイトへのリンクと goo.NE.jp への(リダイレクタを通すような)リンクを貼ってあります。聞いた話では,ある種のブラウザで閲覧後,閉じようとすると JavaScript が起動してなんだか分からないサイトへ延々と飛ばされ続ける事もあるとか。

むぅ,確かに自ら進んで見たくはないサイトかも。しかしかなり前の goo.CO.jp は・・・ちょっと知らないんですが,そうではなかったようです。goo.CO.jp が今のようになってしまったのは goo.NE.jp が台頭してから。「元々 goo.CO.jp はなんでもないサイトだったのに,goo.NE.jp が有名になってから goo.CO.jp は変貌してしまった。それは goo.NE.jp の名声を悪用しようとしたに違いない」というのが今回の結論だそうです。

[ 主張 ]
法律の話をする場合は「対抗」って言った方がいいの? よく分かんないや・・
[ 社名に "goo" をつけて... ]
なんだか商標権を主張してる模様だけど,詳しくないんで無視っ。

ドメインの取り扱い説明書!?

元ドメイン保有者さんの失敗はズバリ次の通りっ。

途中でサイトを変貌させてしまった

最初から今のようなドメインの使い方をしていれば,NTT-X さんも文句は言えなかったはずです。仮に文句を言ってきたなら,元ドメイン保有者さんはこう答えたでしょう:「漏れは元々 goo.CO.jp をこういう形で使ってきた。NTT-X こそ,既に goo.CO.jp が存在することを知りながらも,どうしてもナビゲーションサービスの名称を "goo" にしたくて,後で金にモノを言わせて goo.CO.jp ドメインを乗っ取ればいいや〜とか考えてたんじゃないのか?」・・あ,そういえば今回の件についてだって,goo.NE.jp のようなドメインを取得したのは NTT-X さんの責任のはず。このあたりの議論,どうなってるんでしょう?

アダルトサイトへのリンク

「なぜか?」を論じるには私はあまりにも無知ですが,アダルトサイトへのリンクがあればそれだけでサイトの評価を下げられてしまうようです。

ただの転送サイト

途中でサイトのコンセプトを変貌させるにしても,どうしてただの転送リンクを貼るだけにしちゃうかなあ。これで使用権を剥奪されても,私なら何も言い返せない気が。転送するんじゃなくて,まさにそのドメインで堂々とアダルトサイトを運営すればよかったのに。

ただの転送サイトじゃなくて,拙作「ブラクラチェッカー」の固定キャッシュ検索サイトにしていればどうだったでしょう? お金が欲しいならちょっと広告を貼り付けておくとかね。みなさんのお役に立ってるサイトなだけに,使用権はずっと保持できていたでしょう。NTT-X さんだって文句を言うのはためらったはず。

・・つーまーりー,ドメインとは,そのサイトの運用の仕方を間違うとそれだけで使用権を剥奪されてしまうものという判断で OK? your-domain.CO.jp のようなドメインをお持ちの方,ぜひとも上の忠告をよくご理解下さい。そうでなければ後からデカい企業が your-domain.NE.jp を取得して,そのついでにあなたの your-domain.CO.jp を潰してしまうのです。

[ アダルトサイトへのリンク ]
河上イチローさん ( 元ライター,現在は宗教団体 "アレフ" 所属 ) によると,警視庁のサイトから数回ほどリンクを辿るとアダルトサイトに行き着いてしまうとか。マジっすか!?
[ しちゃうかなあ ]
「かなあ」は憤慨の終助詞。( LOGiN 誌のパクり )
[ ブラクラチェッカー ]
無論,ブラクラチェッカーはほんの 3 年前に始めたばかりなんスけどねー。

漂流するドメイン

判決が出てしまった以上,元ドメイン保有者さんは goo.CO.jp の使用権を主張することは難しいでしょう。控訴・上告する手もありますが,でもそんなに裁判費用を掛けられないんじゃないかなあ。

しかし誤解してはいけないのが,今回の判決は「goo.CO.jp は NTT-X に引き渡せ」ではないということ。あくまでも元ドメイン保有者さんがその使用権を失ってしまったに過ぎません。

とりあえず NTT-X さんのナビゲーションサイト "goo" は,少なくとも私にとっては goo.NE.jp 以外あり得ません。この時点で NTT-X さんが goo.CO.jp を取得するメリットはどれくらい? これから goo.CO.jp はどうなっちゃうんスか? 誰のモノでも無くなるのかな? だとしたら・・チャンス?

・・・もちろん,NTT-X さんはすぐさま goo.CO.jp ドメインを取得する/したんでしょうけど・・・

[ チャンス ]
何の?

2002-04-26

!広告!!連絡方法無!

んか叫びまくってますが,とうとう来ましたよ,「!連絡方法無!」メール。これは受信を金輪際拒絶するための返信アドレスを持たないメールを指すらしいです。04-23 の雑記で紹介したスラッシュドットのストーリー内では「!広告!」以外にも例えば「!無意味!」「!宗教!」「!勧誘!」「!連鎖講!」,しまいには「!エロ!」だとか,いろんな文字をエクスクラメーションマークに挟んではどうか,という案が出てましたが,まさか本当にそんなメールを受け取るとは。

どうでもいいんだけど,スパマーさんの中でものすごく日本語の不自由な方がいらっしゃるようです。冒頭で「突然のメール失礼いたしました」はどうなのかと問いたい問い詰めたい小一時間。

今日のスパムの数:7 通

[ 受信を金輪際拒絶 ]
・・・できるように見せかけて,実はそれが次のスパムの種になるというトリッキーな仕組み。・・・どこがトリッキーじゃい。
[ エクスクラメーションマーク ]
びっくりマーーークッ!!!!!!

[Perl]use strict; のせいで・・・

04-22 「パッケージを越えた sort 関数 その2」 には多少の罠が潜んでいることが分かりました。次のコードはうまく動きません。

use strict;

(中略)

sub cmp_method{
	my $pkg_a = (caller)[0] . '::a';
	my $pkg_b = (caller)[0] . '::b';

	${$pkg_a} <=> ${$pkg_b};
}

use strict; はつまり use strict 'refs'; も含むわけですが,実は文字列をスカラのリファレンスにしようとするとこの制限に引っかかってしまうようなのです。すなわち,まれにこんなコードを書いてしまいますし,use strict 'refs'; でさえなければこれは期待通り動作しますが:

${"foo"} = 'bar';

strict refs 下ではこれは認められないそうなのです。ならば,strict refs を解除すればオールオケー?

# 失敗例
use strict;

(中略)

no strict refs;  # 追加
sub cmp_method{
	my $pkg_a = (caller)[0] . '::a';
	my $pkg_b = (caller)[0] . '::b';

	${$pkg_a} <=> ${$pkg_b};
}
use strict refs;  # 追加

・・・やはり動きません。なぜならば use strict; だから。つまり,no strict refs; という書き方さえも邪道だったのです。refs はきちんとクオートしてやらなければなりません。正解はこう。

use strict;

(中略)

no strict 'refs';  # 追加
sub cmp_method{
	my $pkg_a = (caller)[0] . '::a';
	my $pkg_b = (caller)[0] . '::b';

	${$pkg_a} <=> ${$pkg_b};
}
use strict 'refs';  # 追加

人生はほろ苦いですな・・。

2002-04-25

CLASSPATH?

日から本腰入れて Java を触って遊んでる 23 の春の夜。私と同年代の人ならば普通は色恋沙汰云々で大変な時期なんでしょうね。私? いやあさっぱり。でもぜんぜん悲しくなんかありません。

それはともかく,Java,大変な事に気づきました。msconfig を見ても AUTOEXEC.BAT を見ても CLASSPATH の記述が見当たりません。むしろ自分で明示的に設定した記憶もありません。そのくせに javac でちゃんとコンパイルもできるし,生成した class を java で動かせるんですよね。Java は CLASSPATH が必要だって聞いてたんだけど,・・そんなもんなのかなあ?

初心者度:92

2002-04-24

[オブジェクト指向]「委譲」ってアレやね

Java は基本的に多重継承を認めていないことは有名です。小泉首相の幼年期の失敗談よりも有名。そのため,複数のクラスを一つのクラス内でまとめて扱いたい場合はよく「委譲」という手段を用います。むしろ C++ のような多重継承は必要以上に複雑だとする意見さえも。

今日,私はとうとう本当に Java を始めたくなりました。っていうか始めました。Perl のガベージコレクタの快感に酔ってしまったのです。そしてファースト・インスピレーション。

難しっ!

いえ,C++ での Windows プログラミングに比べればフォームも簡単に表示できるしその上にボタンも配置できるし,なんと扱いやすい言語でしょうか。しかし,その「ボタンを配置する」という作業で私は「委譲」に潜む問題点を垣間見た気がします。

JFrame frame = new JFrame();
JButton button = new JButton("Hello!");
frame.getContentPane().add( button, BorderLayout.CENTER );
frame.getRootPane().setDefaultButton( button );

ボタンを生成し,フォームのど真ん中に貼り付けてます。この場合,フォーム全面がボタンになっちゃいます。それぞれのメソッドの意味はまだよく分かってませんが,なんとなく「contentPane」てなオブジェクトを得て,それにボタンオブジェクトを追加している気が。そして「rootPane」てなオブジェクトで,そのボタンがフォーム上でのデフォルトのボタンであることを主張しています。

ここで引っかかるのが「contentPane と rootPane の関係って?」てな疑問。私は contentPane というオブジェクトに対してボタンを加えたつもりです。なのに一体どういう謂れで rootPane がデフォルトのボタンを決定する権利を持つのでしょう?

[ 基本的に ]
無論,委譲も使いようでは多重継承に見えます。
[ 小泉首相の〜 ]
普通の人が知ってるわけないでしょう。。。

「委譲」が隠したもの

「java JFrame」で検索してみるとどうやら rootPane オブジェクトは layeredPane と呼ばれるオブジェクトを持っていて,さらに layeredPane が Component 型の contentPane を持っている構図が。

すなわち,この行

frame.getContentPane().add( ...

は,次のようにも書けるわけです。

frame.getRootPane().getContentPane().add( ...

しかし contentPane はよく使われるオブジェクトなため,JFrame クラスじきじきに getContentPane() メソッドを定義・実装し,contentPane へのアクセスを簡単にしてくれているというのが真相。

委譲とは,オブジェクトのメソッドへのショートカットメソッドを作る事なり。なるほどなるほど,下手に委譲を行ったり,馴れ馴れしくショートカットメソッドに頼りきってしまうと,この階層をすっかり隠してしまうことになるんですね。Java を学ぶにあたって,これは用心しておくべきだと思いました。

あっ,でもまた疑問がっ。JRootPane の仕様書の図によると,layeredPane は contentPane を保持しているように見えます。でもどうして layeredPane から contentPane を取り出せないんだろう? JLayeredPane クラスの仕様書を見ても,getContentPane() のようなメソッドは見当たりません。

むむむ,このあたり,まだ私は大きな勘違いをしているかも知れないのですな。

高円宮ご夫妻,W杯で「公式訪韓」

「公式」でも「非公式」でも,やることは変わらないという罠。

2002-04-23

!広告!「スパマーと広告業界の微妙な関係!?」

来ならば日経のサイトの URL でも示せばいいんだろうけど,きっとその URL は恒久的じゃないんで,またもやリソースを示すのはヤメ。そのかわりスラッシュドット ジャパンの方をご覧下さいな。楽しい議論でいっぱい。

何があったかというと,広告メールに「!広告!」の文字を表示するのは「広告」という言葉自体が反社会的なものに印象づけるとして,広告関連の 7 団体が表示義務の見直しを求めたのです。どうしようもないスパマーたちのおかげで,わりと意外なところも迷惑を被ってるわけですね。

この件で私はちょっと反省しないといけないんだけど,スラッシュドットのタレコミを見て脊椎反射的に「くわっ! スパマーのくせにナメたコトをいけしゃあしゃあと!!」と思ってしまいました。冷静に日経の記事を読むと,見直しを求めているのはスパマーではなく,良識的に広告活動を行っている団体。彼らが危惧する「『広告』への悪印象」は既に私の脳内に侵入していたようです。とほほ。

いや,でもこの私の先入観は「!広告!」なメールを見続けたからじゃないっす。「!広告!」メールなんぞまず受け取りません。ほとんど海外スパムや「!広告!」の付いていないスパムばかり。そもそも,性根の腐りきったウジ虫未満最低最悪スパマーが正直に「!広告!」なんかつけるワケないんスよね。

ともあれ「スパマー」という人種,世界的に貴重なネットワーク資源を無駄遣いするなど,非常に許しがたい不逞の輩であることに異議はないでしょう。よりグローバルな視点でスパム活動を抑制する仕組みが必要なんだけど・・・どうすりゃいいんでしょう?

今日のスパムの数:5通

[ 被害を被ってる ]
正確には「被りそうになってる」ですか。

掲載許諾願いメール

メールつながりで,もう一つメールのネタを。

宣伝っぽくなっちゃいますが,「日経ネットナビ」に拙作「PortableBrowserCrasherChecker」が掲載されます。このソフトは,常日頃「アクセスが面倒だ」と言われているブラクラチェッカーに,わずか 3 クリックでアクセスするもの・・といってもブラウザを拡張してブラクラチェッカーへのアクセスの便宜を図るソフトはすでに存在するわけで,もはや PBCC は紙面埋めの役割しか果たさないんスよね。

ブラクラチェッカー本体自体は,何度か多数の雑誌に紹介して頂いております。その度に寄越されるのが「掲載許諾願いメール」。あれほど口を酸っぱく「掲載はご勝手に」とアピールしても,やはりその都度メールは送られてくるのです。これはやっぱりアレですか,オトナの礼儀作法とかいうやし。

そしてお決まりの許可メールを返信すると,次にやってくるのが「ありがとうございます」メール。ここでやりとりは終了します。そして私はそれが掲載された本を買いに本屋へ・・・すいません。買ったことありません。いやむしろ見たこともありません。いえ,探しても見つからないのではなく探してさえいません。正直,あんまし興味が沸かなかったりするんスよ・・・。

中には手ぇ抜いて「貴サイトの云々・・」などと代名詞のみを用いたやりとりもありますが,通常はやはりそれなりに丁寧な文面。このようなやりとりを,私以外のサイトの管理者さん達にも数十〜数百くらい行うんですよね。「仕事やってるな〜」て感じで頭が下がります。私なんか,会社に行って紅茶を飲みながら趣味でプログラムを書いて一日を過ごしてるのに。

[ 紙面埋め ]
あ,なんか業界用語では別のコトバがありそう。もしかしたら「穴埋め」とか言いますか?

2002-04-22

[Perl] パッケージを越えた sort 関数 その2

〜,なんとなく良さげな解法を一つ見つけました。まず問題は次の通り。

package MyArr1;
sub new { return bless [], shift; }
sub sort {
	my ($self, $rname) = @_;
	@$self = sort $rname @$self;
}
1;

package MyArr2;
sub new { return bless [], shift; }
sub sort {
	my ($self, $rname) = @_;
	@$self = sort $rname @$self;
}
1;

package main;
$obj1 = new MyArr1;
$obj2 = new MyArr2;

for (0..9) {
	$obj1->[$_] = int(rand(100));
	$obj2->[$_] = int(rand(100));
}

$obj1->sort('main::cmp_method');
$obj2->sort('main::cmp_method');

print join ', ', @$obj1;
print "\n";
print join ', ', @$obj2;

# MyArr1 と MyArr2 で
# 共通の比較関数を使いたいっ
sub cmp_method {
	# ??
}

ここで cmp_method の中身を埋める問題。これは 2002-04-20「パッケージを越えた sort 関数」のアレです。まず失敗例。

# 失敗例
sub cmp_method {
	$MyArr1::a <=> $MyArr1::b;
}

こんな感じでパッケージ名を決めうちしてはいけません。なぜならばこの例では MyArr1 の sort はうまく動くけど,MyArr2 の sort が期待通りに動かないからです。

そこで登場するのが caller 関数。次のように caller 関数でパッケージ名を取得,完全修飾を行えば,パッケージにとらわれない比較関数を書くことができるのです。

# 成功例
sub cmp_method {
	my $pkg_a = (caller)[0] . '::a';
	my $pkg_b = (caller)[0] . '::b';

	${$pkg_a} <=> ${$pkg_b};
}

・・・うーん,コードの見た目はアレだけど,悪い方法じゃないと思いました。これでいいんです。多分。

それが動かない理由

PostgreSQL 使った仕事です。私は離れたトコロでコードを書いているだけなので,相手方のマシンは見たことも触ったこともありません。しかしログを見る限りきちんとコネクトも正常にできてるし,ちゃんと SQL を実行できるデータベースもあるのです。なのに従業員データベースで SQL を実行すると SELECT も INSERT も UPDATE もできない,と。実際にエラーコード PGRES_FATAL_ERROR が返ってきています。

致命的エラーかよっ!?

会社のテストサーバではちゃんと動いているのに! これは世界中のプログラマが1〜2ヶ月に1回はぶちあたる問題。今回の場合はおおかた相手方のデータベースに該当テーブルがないかフィールドがないか使用する権限がないか神様に呪われているか・・・そんな感じなんでしょう。connection オブジェクトの errorMessage を参照すればきっと有用な情報があるに違いありません。そう信じたい・・・。

今回は私がうっかりしてデバッグ用ログ出力関数の中身を空にしないまま「完成版ですよー」と言ってコードを提出したため,こんな障害でも原因がすぐに突き止められそうです。私のマヌケさ加減の凄まじさの異常さも,たまには役に立つですな。

ともあれ,相手方のサーバでテストもしないまま「完成版ですよー」と言ってコードを提出しなければならない境遇,どうにかなりませんか。あと欲を言えば,お客様と直接話をしたい・・・細かな仕様についての打ち合わせをしたい・・・。

[ 致命的エラー ]
いとも簡単に致命的エラーを出してしまう相手方データベース畏れ。時にプログラマ生命を絶つこともある現象なのです。
[ そう信じたい ]
神に祈ってます。

2002-04-21

ハサミ乱舞

れ,何だと思うっす?

----8<----8<----8<----

メールのシグネチャなんかでお使いの方が多いんだけど,初めて見た時はエスニックで謎の模様。しかーし,いやもうなんていうか,すっごく分かりましたですよ。

これ,ハサミ。

- - - 8< - - - 切り取り線 - - - - - -

ね?

理解度:75

[ ね? ]
「ね」じゃねえよコイシ

記念すべき最終項目

VC++ 5.0 起動時の「ワンポイント」ダイアログです。やたー。

http://www.coara.or.jp/%7etkuri/DOWN/final.png (URL は変更するかも)

到達度:10000

ほげ

A page of HOGE - ほげを考えるページ

「ほげ」に関する 4 つの議論と 16 の FAQ。普段何気なくついつい用いてしまう「ほげ」の本質に迫ります。「ほげ学」とは何か? 「ほげ」はどこに生息するのか? 「ほげ」誕生の謎,そして今ここにある「ほげ度」。全てを究めた時,私たちのほげほげと共にほげってしまうのです。ほげ

・・・世の中は本当にいろんなコトを考える人がいるんです。しかも半分真面目に。参考:RFC3092「Etymology of "Foo"(“Foo” の語源)」

↑のリソース内の「ほげ」の数:138個

[ RFC ]
「Request for Comments」の略。私たちがよりよいネットワーク活動 ( なんかヘンな言葉・・) を送るため,主にハッカーたちが「こんなこと考えたけど,どうよ? コメント求む」と提案している技術文書。4 月 1 日はまれにジョークRFCも発表されます。

2002-04-20

マネーのなんとか,とか,なんとかの虎,とか

お断り:私はいろんな意味で素人なんで,どちら様もぜひ↓の文章は鼻で笑っていただきますようお願い申し上げます。

本テレビ「マネーの虎」昨日初めて観ました。面白いんだけど,ツッコミどころも満載では,というのが感想。

まず「虎」と「出資希望者」との面談。あれって長くてもほんの 2 〜 3 時間くらい? そんなんで「虎」をイイ感じに説得して 1000 万単位でアハハハってのはどうなんだろう,と。逆に『短時間で「虎」を納得させるほどのプランやビジョンならば 1000 万円の価値がある』という言い方もできますが,所詮「虎」も人の子。例えばその場の温度,湿度の微妙な変化が「虎」の思考を支配している可能性だってゼロじゃないし。それで運良く事業を始められたとしても,そんな幸運がいつまで続くやら。1ch.tv を見てると・・・。

画面に映っているのは小奇麗な顔立ち,ちょっとオサレっぽくて,なんだか国際弁護士を目指していた云々な青年。これでスポーツ万能ならば何かにつけて妬まれるタイプ決定です。「頭丸める覚悟できてます」って,私なら何とも思わないし,つまり結局それって「主観的な覚悟」に過ぎないし,そもそもあの場で何らかの覚悟をしてるのは当然だから自慢げに言うべきじゃないし。

それからうどん屋を開きたいおじさんも登場。障害をもった子がいるならそれこそ事業を興すべきじゃないでしょう。私に言わせれば現代は資本主義も末期状態。事業を興すのは道楽以外の何者でもないと思います。失敗すればそれこそ基本的人権さえ剥奪されてしまうんだから,ここは堅実にどこかの会社の従業員でいる方が余程お子さんのためでは・・・。

あと,一番思ったこと:どうして 1000 万くらい自分で貯めませんか?

[ いろんな意味で ]
私は番組を制作したことも,事業を興した事も,「虎」として出資したことも,出資してもらおうと頭を下げたこともありません。あと,このような文章を書く人間としてもズブの素人。あと,吉田A作さんカコイイ。
[ 運 ]
「運」について,「努力や実力との因果関係がなく発生するイベントのバロメータ」と定義します。「運も実力のうち」とか言うヤシUZEEEE。
[ 1ch.tv ]
かわいそう (ρ_;)

・・ツワモノどもの宴

面白いページを見つけました。「ただいま実験中!!」。ていうか有名だし,私も前から知ってたんスけどねー。まれにリンクを見つけて飛んで読んで笑ってたんだけど,気づいてみればブックマークをしていなかったという落ち。

中にはちょっと眉をひそめてしまう実験とかもあるんだけど,基本的に爆笑。迂闊にも声出して笑ってしまいました。くそうくそう。

爆笑度:20

[Perl] パッケージを越えた sort 関数

最近,仕事で組んだのがこんなコード。(思いっきり端折ってます)

package MyArr;

sub new {
	return bless [], shift;
}

sub sort {
	my $self = shift; # オブジェクト
	my $sub_rtn_name = shift; # サブルーチン名

	@$self = sort $sub_rtn_name @$self;
}

1;

結局ただの配列のリファレンスですね。使い方は,例えばこう。

use MyArr;
srand;
$obj = new MyArr;

for (0..19) {
	$obj->[$_] = int(rand(100));
}

$obj が参照している配列 20 個にランダムな整数を入れることができました。これをソートするのが,何気なく MyArr パッケージで定義している sort メソッド。第一引数に比較用サブルーチンの名前を入れてやればソートできます。ええ,サブルーチンへの「リファレンス」ではなく,まさしくサブルーチンの「名前」を。

# ためらわずにサブルーチン「名」を!(間違いの例)
$obj->sort('cmp_method');

# 比較サブルーチン(間違いの例)
sub cmp_method {
	$a <=> $b;
}

実行してみると「Undefined subroutine in sort」とエラーが。すなわち sort メソッドを実行してみたんだけど,MyArr の中で 'cmp_method' という名前のサブルーチンを見つけられなかったのです。このようにパッケージを越えてサブルーチン名を渡す場合,「完全修飾」をしなければならない模様。

$obj->sort(__PACKAGE__.'::cmp_method');

これでエラーが出ずに動きます。ではソートされた結果を表示しようかな。

print join "\n", @$obj;

結果(実行時によって異なります):

51
81
70
19
21
14
42
87
74
57
82
14
61
58
5
50
7
64
42
22

えっ!? ソートされてないし!?

私はここで小一時間 問い詰められ ・・悩んだんですが,cmp_method の中で処理すべき $a$b にもちょっとした罠が。上のコードではこの 2 変数を完全修飾すると $main::a および $main::b になっているのです。私が本当にやりたかったことをするには,$a$b の 2 変数が MyArr のものであることを示さなくてはならないようなのです。

# 正解例
sub cmp_method {
	$MyArr::a <=> $MyArr::b;
}

これでやっと期待通りの結果が。・・・にしても,汚いやり方やね。もっと綺麗に且つ汎用的にオブジェクトを表現する方法はないのか? もしや 'Exporter' は私を幸せにしてくれるのでは? と悩んでる間にコードの提出期限が・・・。

とりあえず,商用としても活躍する程に強力なインタプリタを開発,無償で提供を続ける Larry さんの健気さは異常。

コードの不満足度:100

2002-04-19 夕方

冤罪事件! 一番怖いのは・・・

電車内の携帯電話使用を注意したら逆切れ,痴漢よわばりで逮捕拘留云々・・・。んで国賠訴訟ですか。ちゃんとしたリソースを示せればいいんだけど,有名なニュースサイトはリンク不許可だったり記事があちこち移動したりして大変です。

もっと大変なのはここから発生するある種のモラルハザード。なまじこんな事件を知ってしまっただけに,いくら電車内で携帯電話を大声で使ってる人を見てもその人を注意ししにくくなったりして。こういう社会的なメンタルバリアがワッシワッシ積もっていくと,最後には一国を滅ぼしてしまうこともあるんじゃないかと。考えすぎ?

2002-04-19

はじまりはいつも夜。しかも夜中。

々から考えてたんだけど,私みたいなプログラマは本当にネットのお世話になり放題です。厄介な問題がでてくると,すぐに心当たりのある単語で検索するですな。するとすぐに答えが出てくるですな。これで何度命を救われたことか。

ってことで,私もネットに対して何か貢献したくなったのですよ。考えたあげく,やはり一番単純で効果があるのは日記かと。しかも技術的な云々を交えた文章。検索でこのようなページに飛んできた人が,このあたりの文章を読むことでその人が抱えていた問題を解決してくれれば私としても大満足っす。最近では deflate 圧縮のコードを書いて自由に使ってちょうだいな〜とか言ってますが,そんなんじゃ物足りないっす。(そのコード,やけくそに重いし)

ここらへんのリソースは全て Xemem 空間に置いてます。なんかリンクして欲しいような単語があれば,遠慮なくメール(tkuri@fat.coara.or.jp)をば。

ちょっと追記:Xemem から離れてみました。もっと Xemem にふさわしいリソースを用意して参加すべし。

・・・あらかじめ不定期更新なのを覚悟してやってくつもりなんだけど,これさえ更新が止まっちゃうならばもう私の集中力のなさの凄さの異常さを自覚する方向で。

[ 検索 ]
前は goo 最強だったんだけどそのうち フレッシュアイが最高に思えてきて,今や Google の天下。諸行無常。
[ 命を救われた ]
ここで命ってのは,プログラマ生命のことです。
[ Xemem ]
何て読むですか? ぜめむ?

Windows のスレッド

最近,○トリスのような落ちゲー ( っていうかテ○リスそのもの ) を作って何人かの人に遊んでもらいました。そんな時,掲示板にてなぜかいつもお世話になってる章先生から不具合報告。曰く,

「WindowsNT じゃ動かん。」

これ,多分ワケも分からずに ::CreateThread() 使ってるからです。しかも malloc() などという C ランタイムライブラリ関数使ってるし。「::CreateThread() を使うなら,中のスレッドでは C ランタイムライブラリ関数は使ってはいけない」とちゃーんとヘルプに書かれています。あと,ちゃんと /MT オプションつけてコンパイルしたっけ? libcmt.lib リンクした? このあたりもあやしい〜・・・。

そんなミスを犯していても,多くの場合は一見まともに動くらしいです。それで原因が特定されにくいバグに悩まされる人多数。無論そんなのは「偶然動いてるだけ」。本来なら「動かなくてもともと」ってわけですな。

結論としては「malloc() を使うなら ::CreateThread() 使うな」ってことなんだけど,それはそれでまた問題が出てきたり。

偶然動くという罠

例えばおとなしく ::_beginthreadex() でスレッドを生成したとして,initflag 引数に CREATE_SUSPENDED を渡すとサスペンド状態でスレッドが生成されるんですよね。これをリジュームするにはどうすればよいですか? 多分 ::ResumeThread() なんでしょうし,それ以外考えられないし。でもじゃあどうしてリファレンスに明記してませんか? あと,どうして ::_beginthreadex() の戻り値を unsigned long にしてますか? ってな疑問が。

::CreateThread()」に対して「::_beginthreadex()」というまったく別々の生活習慣を送っている人間が考えたような名前を付けるならば,「::ResumeThread()」にも「::_awakethread()」などという関数が ( 名前だけでいいから ) 欲しいと思ったのは私だけじゃないと思いました。あと,ちゃんとリファレンスにも分かり易いトコロに書いて欲しいなー。確かに ::_beginthreadex() の戻り値 unsigned long は「スレッドを指すハンドル」とリファレンスに書いてくれてます。でもどうして HANDLE 型じゃないんだろう? ちょっと解せません。::ResumeThread() の引数の型は HANDLE 型なのに,気持ち悪いっす。

現在の私はまだ本当に ::ResumeThread() を使ってよいかどうかの確信を得ておりません。試してもいません。仮に ::ResumeThread() で期待通り動いたとしても,マニュアルで記述を見つけられていない以上それは憎むべき「偶然動いてるだけ」な可能性が大きいのですから。

[ リファレンス ]
_beginthread,_beginthreadex ……リンク切れですけども.
[ HANDLE 型 ]
VB でこの型を使用する場合,Long 型で対応するように言われてるんですよね。これはもしや「HANDLE 型は unsigned long だ」とする MS 様直々のお達し? そんなんでいいの?

::CreateThread() を使う場合の問題

C ランタイムライブラリ関数である malloc() じゃなくて Win32 API の ::HeapAlloc() を使えば,堂々と ::CreateThread() でスレッドを生成してよいわけです。しかしその場合「ソケット」はどうすればよいのでしょう?

ソケットとスレッドは斬っても斬り離せない関係。サーバを作るならまず socket() でサーバソケット生成,listen() でソケットを開いて select() でクライアントを待って,クライアントから接続要求が来れば accept(),recv(),send() ってなもんですか。この select でクライアントを待つ部分や recv(),send() を行う部分をスレッドに任せてしまうのは常套手段です。

( このあたりは間違えてる可能性大なんだけど -> ) socket()select()accept() も C ランタイムライブラリ関数だとすれば,やはり迂闊に ::CreateThread() を使うわけにはいかないっすよね。このようなソケット関数にも代替 Win32 API が用意されているのかなあ? ていうかあるっぽいんスよねー。socket() としては ::WSASocket() とか,なんか小癪な名前で別関数が用意されております。

これをどう捕らえるかが当面の悩みです。やはり socket()select()::CreateThread() は犬猿の仲なのかなとも考えられるし,でも winsock2.h を見てみると socket() 関数などの定義に「WSAAPI」なんて奇妙で意味深な識別子が。これって C ランタイムライブラリじゃなくて,::CreateThread() と共存させてよいとする主張? なんとも判断がつかないっす。。。(もっとも winsock2.h で同時に socket()::WSASocket() も定義されているあたりで事情や事態を推測してもよさそうだけど)

[ 斬っても斬り離せない ]
ツッコミを入れたい人募集。
[ select() ]
ん,あなたは select() を使わない派? でもまあ重要じゃないし。

悩むのはやめたですよ

何にしても _beginthreadex() さえあれば私は幸せなプログラミングライフを送れるのかも ( ::ResumeThread() の問題さえ解決すれば)。なんでも,C ランタイムライブラリ関数ってのは同様の働きをする Win32 API よりも高速に動作するよう設計されてるらしいじゃないスか。そのかわりに Windows 独自の機能も制限されるのかも知れないけど - 例えば fopen()::CreateFile() の差とか - もう悩むのはヤメ。疲れたし。

2008-09-06 追記:今の私は非常にクリア

現在確認できる _beginthreadex() のリファレンス には,CREATE_SUSPENDED で作成されたスレッドは ResumeThread で起動すべしと明記されています.非常に明快.こうでなくっちゃ.

ちょっぴり大人になってきた度:30

ところで,スタイルシート

スタイルシート,わけわかってません。このリソースではちょっと解説したい単語なんかを抜き出して dl 要素で解説文を入れて,( スタイルシートが有効ならば ) 本文の右側に配置してる・・・はずなんだけど,本文と dl の位置関係,なんかボタンを掛け違えちゃったような感じになってます。本来ならば本文に float:left; を埋め込んで,後続する dl が自動的に右側に配置されるのを期待するべき? しかし解説文の方が長い場合,余剰部分は右側に配置されず,本文の下側に配置される模様。dl のスタイルシートに float: right; を埋め込んでるんだけど,これは最適解じゃないっすね。そこで本文のスタイルにも float:left; を埋め込めば IE や Mozilla では見栄え的に解決ですが,Netscape4.* では悲惨な事に。きっとそれも最適解じゃないんだろうなー。

訂正:結局今みなさんがご覧の,このスタイルに落ち着けました。全部の p を div で囲んで float:left; です。これならば解説文の方が長くなるってことはないでしょう。・・・ただし Netscape4.* で div 要素の解釈がアレなんで,div で囲んだ一番下の p を別のクラスにして,次の h4 要素との距離をとるのです。

・・で結局,NC4.x は切り捨てたんですよね。。。

[ 最適解 ]
無論,Netscape4.* のスタイルシートの解釈の仕方は異常。だからといって無視したくない私は潔癖症。
Written by kuri|minima(tkuri@fat.coara.or.jp) - all rights reserved.(warai
このリソースの位置情報は http://www.coara.or.jp/%7etkuri/D/001.htm で安定しています。coara マンセー。