2008年4月17日木曜日

プロジェクトにおける不安について

プロジェクトに参画した人は、普通さまざまな不安を抱きます。

「このコードをリリースして大丈夫だろうか」(開発者)
「無事リリースできるのだろうか」「明日はどんな障害が発生するだろうか」(マネージャー)
「障害が発生して業務を止めたりしないだろうか」(顧客)

人は不安からは逃げられません。プライベートであろうが仕事であろうが、あらゆることが不安の対象となります。

むしろ不安を抱かない方が却って問題です。何も不安に思わなければ、問題意識も生まれません。漠然とした不安をきっかけとして、具体的で有効なアクションを取れることもあるのです。

不安には冷静に対処する必要があります。なぜ自分が不安に思うのか。まずはその対象を明確にしなければなりません。また、不安は対象が明確になればほとんど消えてしまうものなのです。
いろいろ考えてみると不安の原因が単に自分の無知だった、ということも少なくありません。その場合も不安はさっぱりと消えてしまいます。
例えば、あるプログラムが本当に動くかどうか不安に思って調べたところ、開発環境でずっと問題なく動いていることを知ったために一切の不安がなくなった、などということは開発者ならば珍しくないでしょう。

もちろん、対処しようがない不安もあります。そういう場合は覚悟を決める他はありません。ですが、プロジェクトに参画することで生じる不安は、ほとんど全てが具体化すれば消えてしまうものです。ですから、具体化の努力を怠ってはなりません。

まずは漠然とした不安を感じたとして、その不安の原因をできるだけ具体化するのです。例えばある機能がちゃんと定義されているかどうか。具体的にはどのような定義が、どこに設定してあればよいのか。期待通りに定義されていることを確認すれば、不安は消えます。
あるいは無知から生じる不安については、自分が何を知らないから不安なのかをはっきりさせ、その具体的な事実なり知識なりを仕入れさえすれば、同じく不安は解消します。

それを怠り、いたずらに不安の対象を広げるのは好ましくありません。特に下手に不安を抽象化するとその対象は際限なく広がることになります。
例えば、先ほどの「設定漏れ」が不安の原因ではなく、「人によるチェックミス」が原因だと考えてしまったとしましょう。ところが人為的なミスはどこでも常に発生しうるものです。ですから、そのように不安の原因を定義してしまうと、不安はいつまで立っても解消しないことになります。人によるチェックミスは「あってはならないもの」ではなく「当然ありうべき」言わば制約なのです。不安の原因がチェックミスであると考えてしまうと「チェックミスが発生する(し得る)」限り不安は解消しません。すると「今後チェックミスは許さない」という無茶なスローガンが生じたり、「他にチェックミスはないのか」という愚問が生まれたりします。
もちろん今後同じようなミスが発生しないように、「設定漏れ」というリスクに対して「設定項目が正しいか」チェックする運用を作る、という対処は正しいと言えます。そうではなく、顧客やマネージャーの漠然とした不安を「全部チェックする」「あらゆる設定の妥当性を確認する」ことによって解消しようとすると、行きつく先はプロジェクトの破綻です。

顧客やマネージャの不安を上手にハンドリングできるSE、つまり「信頼感」を与えるSEこそが、優れたSEではないか、と私は思います。

DB2ストアドプロシージャ メモ

Stored Procedure のページが簡潔で良いです。
この通りにやれば出来ますが、一部ハマった点があったのでメモしておきます。

まず、接続は「デフォルトコネクション」を使います。
Connection con = DriverManager.getConnection("jdbc:default:connection");

最初、'jdbc:db2://hostname:port/dbname'でやったところ見事にハマりました。

まず「resultset closed invalid operation」とか何とか出て、気持ち悪いなと思ったもののconnectionをクローズせずにやったところ「java.sql.CallableStatement.executeQuery() was called but no result set was returned.」だのなんだの。

デフォルトコネクションを使ったところ、connectionをcloseしても問題なく使えました。

次に
db2 "call sqlj.refresh_classes ( void )"

です。これを実行すると、SQL0444N rc=4 が出ました。
SQL0444N  ルーチン "*_classes" (特定名 "SQL080417102058370")
が、アクセスできないライブラリーまたはパス "...refresh_classes"、関数
"sqlj.refresh_classes" のコードで実行されています。 理由コード: "4"
SQLSTATE=42724

これも大分ハマったのですが、
以下のように'void'を取ると問題なく実行できました。
db2 "call sqlj.refresh_classes()"

以上です。

2008年4月15日火曜日

コマンドラインからCVSを使う

コマンドラインからCVSを使ってみます。
Eclipse - CVS連携はよく出来ていますが、やはり内部の動きが見えないと不安ですね。(そんなことはないですか?)

情報提供しているページは山ほどありますが、自分のために整理してみました。

■ログイン■

$CVSROOTを確認します。サーバがセットアップされているのが前提となります。
# echo $CVSROOT
:pserver:user@hostname:/cvsroot
【CVSにログイン】
# cvs login
Logging in to :pserver:user@hostname:2401/cvsroot
CVS password: ********[Enter]

■プロジェクト追加■
# ls sample_project
a.c b.java
# cvs import -m "初期登録" sample_project vendor start
N sample_project/a.c
N sample_project/b.java

■バイナリファイルの指定■
# cvs co CVSROOT
# cd CVSROOT
# vi cvswrappers
【ファイルを編集し、以下の行を追加します】
*.gif -k 'b'
*.GIF -k 'b'
*.bmp -k 'b'
*.BMP -k 'b'
*.xls -k 'b'
*.XLS -k 'b'
*.Xls -k 'b'
*.pdf -k 'b'
*.PDF -k 'b'
*.class -k 'b'
# cvs update
cvs update: Updating .
M cvswrappers
# cvs commit
cvs commit: Examining .
【viが開くので"バイナリファイル指定を追加'というコメントを入力し':wq'でviを終了します。】
CVS: ----------------------------------------------------------------------
CVS: Enter Log. Lines beginning with `CVS:' are removed automatically
CVS:
CVS: Committing in .
CVS:
CVS: Modified Files:
CVS: cvswrappers
CVS: ----------------------------------------------------------------------
cvswrappersを編集
~
~
"/tmp/cvsNrkSUb" 9 行、314 文字
Checking in cvswrappers;
/cvsroot/CVSROOT/cvswrappers,v <-- cvswrappers
new revision: 1.3; previous revision: 1.2
done
cvs commit: Rebuilding administrative file database

■CVS関連作業の終了■

cvsからチェックアウトしたファイルをリリースします('-d'オプションでディレクトリも削除されます)。一旦作業を止めるイメージです。
# cd .. # <- 削除対象ディレクトリを指定するため上位に移動
# cvs release -d CVSROOT
You have [0] altered files in this repository.
Are you sure you want to release (and delete) directory `CVSROOT': yes
#

■タグをつける■

タグをつける前に、以下のを確認しましょう。
 バージョンを構成する全てのファイルがコミットされていること
 リリースしないファイルやディレクトリがないこと
  # ls *.log *tmp* *test* *.org *.orig *.bak *.back *.[0-9]* *hoge* *piyo* *foo* *bar* # などなど
 classなどをCVSで管理している場合は、タグをつける前にコンパイルをしましょう
# ls
sample_project
# cvs tag rel20080326 sample_project
cvs tag: Tagging sample_project
(略)

■rdiffの使い方■

タグ=バージョン名をつけると、タグを使ってもバージョン同士/バージョンと現状のdiff/rdiffを見ることができます。(もちろん-r [リビジョン]でもOKです)
# cvs commit -m'rdiffテスト' a.c
# cd ..
# cvs rdiff -s -r rel20080326 sample_project
cvs rdiff: Diffing sample_project
File sample_project/a.c changed from revision 1.2 to 1.3

■cvs statやcvs logコマンドでタグの状況を確認■
# cvs stat -v a.c
# cvs log a.c

■タグを削除する■
# cvs stat -v | grep -p Existing
【削除したいタグを確認する】
# cd ..
# cvs tag -d rel20080326 sample_project

■エクスポートする■

バージョンを指定してエクスポートします。
エクスポートによって"CVS"管理ディレクトリを含めないでソースを抽出することができます。
タイムスタンプも、レポジトリ上の最終更新日に揃えられます。
# mkdir export
# cd export
# cvs export -r rel20080326 sample_project

■コメントを編集する■
# cvs admin -m1.3:'変更後コメント' a.c

■パーミッションを変更する■

やむを得ず(go+xやパg+wなど)パーミッションを変更する場合は、レポジトリのファイルパーミッションを直接変更することになります。
レポジトリのパーミッション+umaskで最終的なパーミッションが決まります。
動かなくならないよう、常識的な範囲で変更して下さい。

■ログインしてモジュールをチェックアウトする■
# cvs login
Logging in to :pserver:cvs@hostname:2401/cvsroot
CVS password: ********
# #【重要】必要に応じてumaskを変更します。
# # 755, 644系のパーミッションを期待するなら、umaskは022とします。
# umask 022
# cvs co sample_project # <- co は checkoutの略

■ファイル追加■

ファイル'addtest.ksh'を追加します。
# cvs add addtest.ksh
# cvs commit -m"新規登録" addtest.ksh

■バイナリファイルの追加■
# cvs add -kb binry.o

■ディレクトリ追加■

ファイルが存在しないディレクトリは存在しないのと同じです。
# mkdir adddir
# echo "test" > adddir/adddir.ksh
# cvs add adddir
# cvs add adddir/*.ksh
# cvs commit -m "dir以下のファイル追加"

他の人が追加したディレクトリを自分の作業ディレクトリに表示させるときは
cvs update -d -P を実行します。

■ファイル編集■

viでも何でも使って適宜編集した後、update, commitします。
'cvs commit ファイル名' とすると指定したファイルのみをcommitします。
# cvs update
# cvs commit -m"コメント" fileName.txt

■ファイル削除■

実際にはファイルは削除されません。レポジトリから見えなくなるだけで、いつでも復活させることができます
# rm filename
# cvs remove filename
# cvs commit -m "Removed unneeded files"

cvs remove -f とすれば、rmコマンドは不要です。
# cvs remove -f filename

# 削除後でもログは参照可能です。
# cvs log filename

■ファイルの削除を中止する■

手順概要(1)remove 実行前
# rm filename
# cvs update

手順概要(2)remove 実行後(commit未済)
$ rm filename
$ cvs remove filename
$ cvs add filename
$ cvs commit

手順概要(3)remove/commit後
$ cvs add filename
$ cvs commit

■ディレクトリ削除■

実際には削除されません。リポジトリには空のディレクトリが残ります。
# rm adddir/*.ksh
# cvs remove adddir/*.ksh
# cvs remove adddir
# cvs commit -m "adddirを削除"
# cvs up -d -P

■ファイルの名前を変更する■■
# mv addtest.ksh renametest.ksh
# cvs remove addtest.ksh
# cvs add renametest.ksh
# cvs commit -m "addtestをrenametestに変更"

■ディレクトリの名前を変更する■
特別な手順はありません。新規のディレクトリを作成し、ディレクトリ中のファイルを作成したディレクトリに移動させます。

■古いファイルとのDIFF■
# cvs diff -r[rev] [ファイル名]

■コメント/履歴確認■
# cvs log [ファイル名]

■バージョン確認■
# cvs stat [-v] [ファイル名]

'-v'を追加するとタグ(リリースバージョン)情報を出力します。

■最新バージョンに書き戻す■
$ rm ファイル
$ cvs update ファイル
U ファイル

【あるいは】

$ cvs update -C ファイル

■古いバージョンに書き戻す■
# cvs log ファイル
# cvs diff -r[rev] ファイル # 戻したいファイルとのDIFFを確認する
# cvs update -p -r [rev] ファイル > ファイル
# cvs update
M ファイル
# cvs commit ファイル

■追加を途中でやめる■
# cvs remove -f ファイル

commitは不要です。

■作業ディレクトリがいつチェックアウトしたものか分からなくなった■
作業ディレクトリで'cvs update'するか、一旦作業ディレクトリを削除してcheck outします。
(当たり前か)

■終了する(release)■

cvs releaseコマンドを使います。
'-d'オプションを使うとディレクトリまで削除してくれます。
# cvs release -d sample_project


【参考】
CVS--Concurrent Versions System (in Japanese) - CVS のコマンド便覧 必要十分なリファレンス
CVS使用法メモ(Hishidama's CVS usage Memo) 実践的なコマンドメモ
リリースブランチ(cvs) ちょっと毛色は違いますがブランチの意義について