訃報に寄せて

その本に本当の意味で出会ったのは、確か22才のころ。
大学を中退してはじめる事になった社会人に、全く馴染めてなかった5月の事でした。
前から存在は聞いていて一度読んでみようとは思っていたのだが、学生な時分ってこともあり、金銭的になかなか踏ん切りがつかなかったのが、読んでいなかった理由です。
そこで、お金が少し出来て真っ先に買ったのがその本。
行き帰りの電車で最新刊に追いつくまで毎日のように読んだことを記憶しています。

読み進めていくと、次第に自覚もなくその世界に引き込まれていきました。
ソノ前に読んでいたシリーズは、今で言うラノベに分類される作品でありながら、魂の呼応による性別を超えた愛を表現した非常に力強い作品だったため、まさか引き込まれているとは自覚出来なかったのかもしれません。
最新刊に追いつき一年くらいした頃、ある事がきっかけで自己嫌悪に陥る羽目となりました。
ちょうどその時、ある登場人物の身勝手さや乱暴な思考に、自分の身勝手さや乱暴な思考を重ねて共感し、また嫌悪感を覚え、その登場人物の成長がなくしては自己嫌悪感もなくならないと思い込み、その成長を切に願うほど、のめりこんだ時期もありました。

そう、その作品とはグイン・サーガ
かれこれ10年間、本編はもとより外伝や資料集、漫画、果ては作者自らの手による同人誌に至るまで、関連書籍を読んできました。

最新刊ではようやく、その登場人物…イシュトバーンが心の平静を得られそうな展開になっていて、ようやく私も妙な登場人物への束縛から解放されるかなぁと、ほっとしていたところでした。
栗本薫という作家自身、創作者と消費者の悲しき感情のすれ違いに大きな感情とエネルギーを費やしてきて、最近になって創作の世界への逃避的解消という形でようやく平静を取り戻したかに見えたわけで…。
そこに今回の訃報。
未だ信じたくない気分でいっぱいです。

「いや、天国にグイン・サーガを広めるために、ちょっと旅立っただけさ」とかいう、ステロタイプにかっこつけた見方はきっと栗本薫は最も欲しがってない考え方でしょう。
しかし、私は思わずにはいられないのです。
きっと、彼女は天国でも創作の手を止めないでいてくれるだろう。

ご冥福をお祈りします。

サーバ更新

年齢が0x20才になった誕生日プレゼントってことで、サーバを刷新することにしました。
構成は
Main: Shuttle SN68GS2
CPU : AMD Athlon X2 5050e (2.6GHz)
MEM : KINGBOX KBD4GD2-800(2GB x2)
HDD : SAMSUNG HD501LJ (500GB) x2 (手元にあったTera Stationをバラして投入)
DVD : Sony NEC Optiarc DVD RW AD-7200S (System TALKS SATA-TR150TWを使って接続)
KBD : AOTECH AOK115UPB
MON : NTT DATA CF-L10
OSはNexentaにしようかUbuntuにしようか悩んだけど、結局Ubuntu Serverのamd64版を入れることに。
今から考えると、DVDドライブはIDEのものを買えばよかったかもなぁと思ったりもする構成です。


CF-L10は10インチのVGAなカラー液晶モニタで、業務用のものらしいです。
インストールに必要なだけなので、これで十分。
前から管理用の小さなモニタがほしかったので、安くそういうものが見つかったのは、大きな収穫でした。

(CF-L10前面と Shuttle SN68GS2本体がある風景)



(CF-L10背面)



(CF-L10左)



(CF-L10右)

[プログラミング] JUDEにおけるアクティビティ図と開始ノード

ちょっとDFDを描きたくなったのですが、Visioが手元に無いのでJUDEで描いてみようと思い立ちました。
しかし、JUDE CommunityなのでDFDは描けないようなので、こういう時はUMLのアクティビティで代用とあったため、アクティビティでなんとかしようと考えました。
作業をしてみたところ、なんとなく開始ノードを複数作ろうとしたら、二つ以上作れないと警告されてしまいました。
はて。開始ノードは一つだけしか描けないものなのでしょうか。


JUDEはUML2.0対応。
UMLの仕様は公開されているため、OMGのサイトでUML2.0 Specをダウンロードしてみます。
ダイアログに関する詳細な仕様が載っているのはSuperstructureなので、formal 2005-07-04のPDF(ZIPed)を調査。
該当箇所は 381P の 12.3.31 InitialNode にありました。
読んでみると、

Description
An activity may have more than one initial node.

とあります。一つ以上あるかもしれないと言っているようです。
更に読み進めます。

Semantics
(中略)
If an activity has more than one initial node, then invoking the activity starts multiple flows, one at each initial node.

「アクティビティに複数の開始ノードがあるならば、複数フローの開始をそれぞれ表します」くらいの意味でしょうか。
やはり、動きとして同じアクティビティに対し、複数の始点があるならば、開始点は複数あってよいようです。

そもそもDFDの代用なので、その開始点があるという考え方自体が間違ってるので、問題は私のほうにあるのは間違いありません。
しかし、それにしてもJUDEはナゼ、開始を一つだけにしてあるのでしょう。
理由がよく分からないわけですが…。


ところで、UML2.2が2月に出ていたのですね。
こちらもせっかくなので、後で詳しく調べてみるとします。

GASと疑似命令

Gnu Tarが1.22になって、Jオプションというかxz圧縮に対応した。
tarでJオプションを試そうとすると、どうも内部ではxzコマンドを呼び出しているらしい。
そこで、cygwin上でxz 4.999.8betaをコンパイルしようとしたところ、コンパイルエラーが起きた。

原因

makeしてみると、以下のようなメッセージが発生する

/bin/sh ../../../libtool   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I.
./../..  -I../../../src/liblzma/api -I../../../src/liblzma/common   -g -O2 -MT l
ibcheck_la-crc32_x86.lo -MD -MP -MF .deps/libcheck_la-crc32_x86.Tpo -c -o libche
ck_la-crc32_x86.lo `test -f 'crc32_x86.S' || echo './'`crc32_x86.S
 gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../../.. -I../../../src/liblzma/api -I../.
./../src/liblzma/common -g -O2 -MT libcheck_la-crc32_x86.lo -MD -MP -MF .deps/li
bcheck_la-crc32_x86.Tpo -c crc32_x86.S  -DDLL_EXPORT -DPIC -o .libs/libcheck_la-
crc32_x86.o
crc32_x86.S: Assembler messages:
crc32_x86.S:73: Warning: .type pseudo-op used outside of .def/.endef ignored.
crc32_x86.S:73: Error: junk at end of line, first unrecognized character is `_'
crc32_x86.S:276: Warning: .size pseudo-op used outside of .def/.endef ignored.
crc32_x86.S:276: Error: junk at end of line, first unrecognized character is `_'
make[4]: *** [libcheck_la-crc32_x86.lo] Error 1
make[4]: Leaving directory `/usr/local/src/xz/xz-4.999.8beta/src/liblzma/check'
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory `/usr/local/src/xz/xz-4.999.8beta/src/liblzma'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/usr/local/src/xz/xz-4.999.8beta/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/usr/local/src/xz/xz-4.999.8beta'
make: *** [all] Error 2

gccコンパイルしているので、アセンブラ部分はGASで処理される。

問題が発生しているのは73行目

.type	LZMA_CRC32, @function

と276行目、

.size	LZMA_CRC32, .-LZMA_CRC32

の部分。
pseudo-opとは、疑似命令の事だからして、どうやらtype疑似命令とsize疑似命令が問題のようだ。

defineされた中身はどうなっているのだろう

実際にプリプロセッサを展開した後はどうなるのか、一つ前のを参考にしつつ、確認。

 .globl _lzma_crc32
 .type _lzma_crc32, @function
 .align 16
_lzma_crc32:

(空行は省略しました)
正常に出ているくさいが、ダメだという。
そもそも、Bunutils - as .type疑似命令の解説を見ると、

.type name , type description (ELF version)

となっている。
.size疑似命令の解説でも、

.size name , expression (ELF version)

となっており、このELF用の利用法を選択しているのが問題なのだろう。
つまり「(ELF version)」と書いているところから、Cygwin用ではない。
Cygwinが出力するバイナリはCOFFだからして、「#if defined(__CYGWIN__)」などとして正しい定義をすればいいのだろう。

一難去ってまた一難

以上を見てみて、Windowsと同じ形式にすればよさそうということで、コードに変更を加えてみた。
src/liblzma/check/crc32_x86.S の 72行目と270行目にCygwinWindowsと同じように処理をするように追記。
そしてmakeすると

/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/as: BFD (GNU Binutils) 2.18.50.20080625 assertion fail /netrel/src/binutils-20080624-2/bfd/coff-i386.c:579
crc32_x86.S: Assembler messages:
crc32_x86.S:117: Error: cannot represent relocation type BFD_RELOC_386_GOTPC
make: *** [libcheck_la-crc32_x86.lo] Error 1

またコンパイルエラーで落ちてしまった。

解決できず

BFDで再配置が云々といわれているけど、メモリ上の再配置の話だろうか。
あいにくこの周りの知識はほとんどない。
そもそも、上のWindowsと同じ処理にして合っているのかどうかも分からない。
ん〜。とりあえずCOFFのフォーマットから勉強してみるとしましょうか。

cmdで遊んでみた

とある事情により、今月半ばから、今の現場の下の階にある会社に常駐することとなった。
新しい場所では、どのような顔が並んでいるのだろう。
不安半分、興味半分だ。


閑話休題
先日、WindowsXP上でcmdのスクリプトを動かしてたのだが、動きがおかしくてだいぶ困った。
これはその時のメモ書きというか、備忘録。
ちなみに再検証している環境はVista

if

複雑なcmdスクリプトを組みたくなる理由はいくつかあるが、当然ソレは制御構造を表現したい場合が多い。
cmd上でのif文は

if condition somethingToDo

と書くのが基本。複数の文を書きたい場合は、カッコを使う。
具体的にはこうなる

C:\Users\quabbin>if 1 == 1 (
More? echo x
More? echo y
More? )
x
y

C:\Users\quabbin>

ここで、「More? 」は「(」に対するプロンプト。
実際に入力しているのはechoの部分だけ。
当然elseも書ける。

C:\Users\quabbin>if 1 == 2 (
More? echo x
More? ) else (
More? echo y
More? )
y

C:\Users\quabbin>

elseはif側の閉じカッコと同じ行に書かなければいけない。
理由は分からなくもないけど、ちょっと面倒。
else ifは elseの中にifを書く必要がある。

C:\Users\quabbin>if 1 == 2 (
More?   echo x
More? ) else ( if 1 == 2 (
More?     echo y
More?   ) else (
More?     echo z
More?   )
More? )
z

C:\Users\quabbin>

書き方を工夫しないと、見にくい。

for

繰り返しにはforが使える。

C:\Users\quabbin>for %x in (a b c) do echo %x

C:\Users\quabbin>echo a
a

C:\Users\quabbin>echo b
b

C:\Users\quabbin>echo c
c

C:\Users\quabbin>

do の後ろの文が実行される。
実行されるときには、cmdファイルのように実行されたコマンドがエコーされる。
@を付けるとエコーはなくなるので、出力がまとまる。

C:\Users\quabbin>for %x in (a b c) do @echo %x
a
b
c

C:\Users\quabbin>

複数行実行する場合は、doの後ろを()で纏める。

C:\Users\quabbin>for %x in (a b c) do @(
More? echo %x-1
More? echo %x-2
More? )
a-1
a-2
b-1
b-2
c-1
c-2

C:\Users\quabbin>

「(」の前の「@」は、エコーを止めるため。
ちなみに内側のechoに@を入れると、「()」がエコーされる。

C:\Users\quabbin>for %x in (a) do (
More? @echo x
More? )

C:\Users\quabbin>()
x

C:\Users\quabbin>

二つ目のプロンプトは、自動表示されたものだ。

一番納得がいかない部分

さて、DOSのbatファイルからだが、もっと高度な制御はgotoを使うしかない。
本題はここからで、このgotoや「()」の周りの動きが納得いかない。


まずラベル。
for文からの脱出構文が見つからなかったので、gotoで制御したくなり、()内でラベルを使おうとした。
しかし、これがうまくいかない。
どうも()内にラベルを書けないようだ。

C:\Users\quabbin>(
More? echo x
More? :label
More? )
) の使い方が誤っています。

C:\Users\quabbin>

複雑なfor文を作成しようとすると、これが邪魔になる。
ifとelseを組み合わせて何とかするしかないのだろうが、フラグ制御も必要になりそうなのだが、これがまた問題。
()内で変数を変化させようとすると、うまく動かない。

C:\Users\quabbin>for %x in (a b c) do @(
More? set y=%x
More? echo %y%
More? )
%y%
%y%
%y%

C:\Users\quabbin>

この現象は「()」自体の問題らしく、

C:\Users\quabbin>(
More? set z=a
More? echo %z%
More? )
%z%

C:\Users\quabbin>echo %z%
a

C:\Users\quabbin>

値は代入されているが、echoで解釈する場所は、()の外側の値を参照するらしい。
これは%ERRORLEVEL%のような、特殊な変数でも同じ現象が見られる。

C:\Users\quabbin>(
More? cd \\\
More? echo level is %ERRORLEVEL%
More? if ERRORLEVEL 2 echo x
More? if ERRORLEVEL 1 echo y
More? if ERRORLEVEL 0 echo z
More? )
'\\\'
CMD では UNC パスは現在のディレクトリとしてサポートされません。
level is 0
y
z

C:\Users\quabbin>

xyzの出力を見て分かるとおり、ERRORLEVELの値は1になっているにも係わらず、%ERRORLEVEL%は「()」の外側での値、0がそのまま保持される。
ついでにbashの$?と違って、echoはERRORLEVELの値を書き換えない。

まとめ

このように、Windowsのcmdをそのまま使おうとすると、バッドノウハウが面白いように溜まっていく。
複雑なことをさせようとするとすぐこんがらがるので、複雑なことは他の言語でなんとかするべきという設計思想なのだろう。
この状況は、Windows Power Shellなどで解消されるのだろうか?
解消されていて、Windowsの標準構成で使えるようになったら(Windows7の次のバージョンあたりだろうか)、そちらを試してみるのいいのだろうか。

2009/03/08 06:55 追記

Sukoyaさんの助言を受け、変数の展開方法について調べてみたところ、比較的簡単に変数の動きを意図通りにする方法が見つかりました。
というか、そんなところにorz

C:\Users\quabbin>cmd /v:on
Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.

C:\Users\quabbin>(
More? set x=1
More? echo %x%
More? echo !x!
More? )
%x%
1

C:\Users\quabbin>

キモはcmd /v:onと、表記を「!x!」のように「!」で囲む部分です。

三項演算子で代入

yharaさんのblogを見て、少し気になるところがあった。

true ? 1 : x = 2

のようなソースがパースエラーにならないかどうか。
(略)

  • 書けない:

[prog] 三項演算s…もとい、条件演算子の右辺に代入が書けるかどうか

早速試してみる。

C:\Users\quabbin>copy con A.java
class A{ int i = (true ? 1 : int x = 2);}
^Z
        1 個のファイルをコピーしました。
C:\Users\quabbin>\Develop\Language\jdk1.6.0_07\bin\javac.exe A.java
A.java:1: '.class' がありません。
class A{ int i = (true ? 1 : int x = 2);}
                                 ^
A.java:1: ';' がありません。
class A{ int i = (true ? 1 : int x = 2);}
                                      ^
エラー 2 個

バージョンについては深い突込みをしないでください。
そのまま訳しただけでは…やはりダメですね。
だば、宣言を別にしてみたらどうでしょう。

C:\Users\quabbin>del A.java

C:\Users\quabbin>copy con A.java
class A{ int x; int i = (true ? 1 : x = 2);}
^Z
        1 個のファイルをコピーしました。

C:\Users\quabbin>\Develop\Language\jdk1.6.0_07\bin\javac.exe A.java
A.java:1: 予期しない型
期待値  : 変数
検出値  : 値
class A{ int x; int i = (true ? 1 : x = 2);}
                              ^
エラー 1 個

これでもダメだけど、少し解釈できているっぽい。

さて、ここで少し考えてみるとします。
三項演算子の後ろの二つは、何らかの値を返すことが期待されてますよね。
正確な理由は分からないが、Javaでは「if( i = 0 ){}」みたいなバグっぽいものを書けなくするためか、そういう場合は代入の記述が直接出来ないこととなっているようです。
しかし、Javaで記述する場合、条件判断を与える場所に代入を書かないとコードが冗長になる時もあります。
例えば、ファイルを文字列として行読み込みするときなんかがそれにあたりますが、当然簡潔に書く方法もあるわけです。

BufferedReader reader = null;
String line = null;
while(null != (line = reader.readLine())){
	// do something
}

変数lineに代入している部分が()で括られているところがキモ。
応用してみましょう。

C:\Users\quabbin>del A.java

C:\Users\quabbin>copy con A.java
class A{ int x; int i = (true ? 1 : (x = 2));}
^Z
        1 個のファイルをコピーしました。

C:\Users\quabbin>\Develop\Language\jdk1.6.0_07\bin\javac.exe A.java

C:\Users\quabbin>dir *.class
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 3574-3602 です

 C:\Users\quabbin のディレクトリ

2009/01/08  23:26               219 A.class
               1 個のファイル                 219 バイト
               0 個のディレクトリ  145,907,171,328 バイトの空き領域

というわけで、成功しました。

しかし、Javaもダークサイドが多いですね。

2009年新年挨拶

遅ればせながら、あけましておめでとうございます。


昨年は私の周りもいろいろと変革が起きる一年でした。
長らく続けてきたプロジェクトから他のプロジェクトへと異動したことにより、作業が企画兼マネージメント兼システム関係の何でも屋から、上流工程兼マネージメントをする形へと予想外に変化し、仕事の方向性の違いというものに思い悩む年末となりました。
また、忙しさに任せて、日記の更新もあまりしない形となってしまいました。
しかしながら、さまざまな勉強会に出ることにより最新の情報に触れ、また多くの恥をかきながらも自分を見つめなおせたことは、何よりの収穫であったと言える一年でもありました。(ご迷惑をおかけしました各位には、ここで改めてお詫びをさせていただきます)


本年は去年の反省を踏まえ、まず自分の時間管理をうまくし、技術のネタを多く発信して行こうと思います。
そこで、本年の目標をここに掲げます。

  • テンプレートエンジン「MITT」の作成と公開
  • local_variable_set()パッチの作成と投稿
  • 勉強会への参加と社内勉強会の主催
  • the Art of Computer Programmingの読了
  • 上流工程におけるバグ検査手法の調査と確立

年が終わってどれくらい完了しているかわかりませんが、順次仕上げていけたらと考えます。


では、本年もよろしくお願いいたします。