2008年6月27日 (金)

アニメ作成ツール

ニコ動で初音さんとかVOCALOIDのPVがあるわけだけど、2Dのアニメーションってどうやって作っているのか気になって、ツールを探してみた。
でも、キーワードが悪かったのかググっても、GIFとかFLASHとかがヒットしてなかなかよさそうなのが見当たらなかった。
ニコニコ ムービー メーカーってのもあるらしいけどWindowsのムービーメーカーとおなじ様なものらしいし、コマを繋げてアニメにするのは無理っぽい。(やっていないけど)

しかし、ヨサゲなものを見つけました。

ポータルグラフィックス社のFrameToon
基本的な機能があるペイントソフトが付いていて、それで絵を描いて並べていけば、動画を生成できるというもの。パラパラ漫画の要領やね。んで、前の絵が透けて見えるようになっているので、動きも分かりやすい。
もちろんファイルの取り込みもできるので、ちゃんとした絵をGIMPとかで描いて並べていくのもできる。ああ、そうそう、音もWAVEファイルを取り込めるので、これだけである程度作れちゃうね。いろいろ調節したいならムービーメーカーを使う方が無難かもしれないけど。
生成できる動画ファイルは、AVI(圧縮もできてデコーダをいくつか選択できた)やFLASHファイル(SWF)。
試用版は、起動30回まではフルで使えて、それ以降はファイル保存とかできなくなるらしい。6,000円でレジストキーを購入して、それを入れればそのまま正式版となるとのこと。
これくらいの値段なら十分な機能を持っていると思う。

でもオイラにゃ才能がないので、まともな絵が描けない・・・。

2008年6月10日 (火)

今日の失敗

プログラムに機能追加をしていたのだが、なぜかポインタに0x00000001が入る。
そのポインタに値を入れるところは、すべてわかっているので、そんな値が入るわけがない。
というわけで、grepしてみたら、if文の条件式でNULLチェックをしているところで
X != NULL
とするところを
X =! NULL
とやっていた。

NULLは(void*)0 なので、NOT演算子(!)で0x01になり、その値を代入してしまったというわけ。

2008年5月 5日 (月)

Wizardry for Ajax 試し その2

今回は扉と隠し扉を実装してみた。(前回のエントリはこちら

Wizardry for Ajax test no.2
※:クッキーが必要です。

gif画像の隙間から後ろの壁が見えてしまっているのは何とかしたいと思うのだが、面倒だなぁ。
次回こそ画面構成とメッセージダイアログを作ろうと思う。

2008年3月10日 (月)

昨日のプログラムについて

昨日のプログラムは、昔、書いた「秘匿性の高いWebサーバを作る」というエントリでのシステムの一部でした。
持っているMP3ファイルとかMPEGファイルを離れたところでも自由に見られるようにするために、LinuxマシンをWebサーバとして動かして、そこから閲覧できるようにするシステムの一部として、MP3ファイルを追加したらコマンドを実行して、取得したファイル一覧をDB(MySQL)に作ったテーブルに書き込むようにしていた。

そして、Apache+JSP+サーブレットでアルバムごとにページを表示して、1曲聴くときはリンクからMP3ファイルを、アルバムごと聴くときはJSPでM3Uファイルを生成してWebクライアントに渡していた。
結局、M3Uファイルを渡したときWMPやQuickTimeなどが認証エラーになることに対する回避方法がどうしてもわからず、飽きてしまったので今は放置したままであるのだが・・・。
上記のエントリについてなにも反応は無いので、こういったものに需要は無いのかな?

#そのうち、無許可で音楽ファイルを提供することは違法となるって話だし、こっそりやるには秘匿性の高いWebサーバってのは需要があると思うのだが・・・。
まあ、ADSLでは線が細いので重いファイルのやりとりを行うのには限界があるか。
ちなみに、ウチでは外部へのWebサーバは動かしていないよ。ほんとだよ。

2008年3月 9日 (日)

プログラム:複数のMP3ファイルからID3タグを取得する

習作なのだが、指定したディレクトリ以下にあるファイルからID3タグ(v1.0/1.1とv2.3)を取得するJavaプログラムを作ってみました。
こちらからLHAで固めたファイルをダウンロードできます。

使い方は、DOS窓(コマンドプロンプト)からmp3filelistディレクトリの上(LHAファイルを展開したときはMP3FileListディレクトリになる)に移動して以下の様に入力して実行してください。<ディレクトリ>にはMP3のファイルがあるディレクトリを指定してください。

>java mp3filelist/MP3FileListMain <ディレクトリ>

指定したディレクトリ以下(サブディレクトリも検索します)のファイルからID3タグを取得して、csv風のデータを標準出力に表示します。ファイルに保存する場合はリダイレクトしてください。(わからない場合は"DOS リダイレクト"でググれ)
ID3タグのv1.0/1.1とv2.3が設定されている場合は、両方とも出力するようにしています。それが嫌なら改造してね。

●注意・免責:

  • このプログラムは、習作のため、動作を保証しません。何らかの被害があっても、当方は一切の責任を負いません。ミスが見つかったらこっそり直すかもしれませんし、直さないかもしれません。Javaのセオリーに従っていない変な構造になっているかもしれませんが、見直ししていないからです。すみません。
  • そんなに難しい作りではないのですが、わからない場合はいい機会だと思って勉強してください。質問されても猫並みの気まぐれさで回答するかもしれませんし、しないかもしれません。
  • 勝手に改造してもらっても構いませんが、Javaの発展のため、そのソースプログラムは必ず公開してください。

ちなみに改造してビルドする場合は(packageにしているので)mp3filelistディレクトリではなく、その上のディレクトリで以下の様に実行してください。
>javac mp3filelist/*.java

#いやね、このプログラムを途中まで作って放置していたらmp3filelistディレクトリでコンパイルしてエラー出てきて困ってしまった思い出があるので・・・。

2008年2月11日 (月)

Wizardry for Ajax 試し その1

とりあえずPerlとAjaxを連携させて、迷路を歩けるようになった。(メッセージとか扉、隠し扉などはまだ)
Wizardry for Ajax test No.1
※:クッキーが必要です。

クッキーで現在の座標と移動方向をサーバに通知するようにしているのだけど、なぜかieでちゃんと伝わらない現象が発生していた。
プログラム的には問題ない。んで、[ajax request ie]ググってみると「nitsujiの日記」の[javascript] Ajax.Request使用時のコールバック順序というエントリで、ie かつ getにすると他のWebブラウザやieのpostの時とイベントの発生順が違うということが書いてあった。
ああ、たしかにAjax.Requestの引数に指定するmethodをgetにしているし、onCompleteで読み取り時のメソッドを実行するようにしている。
それで、methodをpostにすることによってieでも動作するようになった。
たしかにpostとgetは結果的に同じ動作になるけど、意味合いが違うじゃねーか。
まあ、いいや。
次は、画面構成とメッセージダイアログを実装するつもり。(いつになるかわからないけど)

2008年2月 5日 (火)

CSSで角丸な枠線を作る その2

昨日の続き。

以下の点を改良してみた。(概要は、昨日のエントリの最後に書いたとおり)
・二重に角丸ブロックを使わないようにした。中身を2か所に同じものを設定しなくてよくなった。
・外の<div>タグだけwidthを設定すれば、他のタグにwidthを固定長を設定しなくてもよい。

#2008/2/11追記:ここにモノを置いてみた

#ちなみに昨日使った角丸ブロックはNifty Cornersというらしい。

スタイルシートファイル"angleCircle2.css"

div#contener2
{
    position: relative;
}
div#text-sample2
{
    position:relative;
    top: 0;
    left: 0;
    width: 306px;
    z-index: 1;
    background: gold;
}

#text-sample2 div.rtop, #text-sample2 div.rbottom
{
    position:relative;
}

#text-sample2 div.rtop-inner
{
    position: absolute;
    width:100%;
    display: block;
    background: black;
    z-index: 1;
    margin-top:3px;
}
#text-sample2 div.rbottom-inner
{
    position: absolute;
    width:100%;
    display: block;
    background: black;
    z-index: 1;
}
#text-sample2 div.rtop-inner span, #text-sample2 div.rbottom-inner span
{
    display: block;
    height: 1px;
    overflow: hidden;
    background: white;
    z-index: 2;
}
#text-sample2 div.rtop-outer
{
    position: absolute;
    width:100%;
    display: block;
    background: gold;
}
#text-sample2 div.rbottom-outer
{
    position: absolute;
    width:100%;
    display: block;
    background: gold;
    margin-top:3px;
}
#text-sample2 div.rtop-outer span, #text-sample2 div.rbottom-outer span
{
    display: block;
    height: 1px;
    overflow: hidden;
    background: black;
}
#text-sample2 span.r1
{
    margin: 0px 6px;
}
#text-sample2 span.r2
{
    margin: 0px 4px;
}
#text-sample2 span.r3
{
    margin: 0px 3px;
}
#text-sample2 span.r4
{
    margin: 0px 1px;
    height: 2px;
}

#text-sample2 div.rcontent
{
    position: static;
    padding: 5px;
    margin: 5px 0px 0px 0px;
    color: black;
    background-color: white;
    border-style:solid;
    border-color:black;
    border-width:0px 3px 0px 3px;
}
#text-sample2 p
{
    margin: 0px;
}

htmlファイル"angleCircle2.html"

<html>
<head>
<link rel="stylesheet" href="angleCircle2.css" type="text/css" title="Default">
</head>
<body style="background-color: Gold">
<p>test</p>

<div id="contener2">
<div id="text-sample2">
<!-- フタ -->
<div class="rtop">
    <div class="rtop-outer">
        <span class="r1"></span><span class="r2"></span><span class="r3"></span><span class="r4"></span>
    </div>
    <div class="rtop-inner">
        <span class="r1"></span><span class="r2"></span><span class="r3"></span>
    </div>
</div>

<!-- 中身 -->
<div class="rcontent"><p>テストテストテストテストテストテストテストテストテストテスト</p>
</div>
<!-- 底 -->
<div class="rbottom">
    <div class="rbottom-inner">
        <span class="r3"></span><span class="r2"></span><span class="r1"></span>
    </div>
    <div class="rbottom-outer">
        <span class="r4"></span><span class="r3"></span><span class="r2"></span><span class="r1"></span>
    </div>
</div>

</div>
</div>

</body>
</html>

まだ、なんか歪だし、CSSがおかしいのか思った通りにならないところがある。もうチョイ改良方法を考えてみるつもり。

#2008/2/6追記:IE7、opera9.25、FireFox2ではちゃんと表示されたが、IE6ではずれが生じた。何でかわからん。だれか助けて。

2008年2月 4日 (月)

CSSで角丸な枠線を作る その1

スタイルシートで角丸を実現する方法からヒントを得て、角丸な枠線を持つブロック要素を作ってみた。簡単に言うと角丸なブロック要素を二枚重ねて枠線のように見せている。
いろいろ問題があるけれど、とりあえず版ということで。

スタイルシートファイル"angleCircle.css"

div#contener
{
    position: absolute;
    top: auto;
    left: auto;
    height: auto;
}
div#text-sample
{
    position: absolute;
    top: 0;
    left: 0;
    width: 306px;
    z-index: 1;
    background: black;
}
#text-sample div.rcontent
{
    padding: 4px;
    margin: 0px;
    color: black;
}
#text-sample span.rtop, #text-sample span.rbottom
{
    display: block;
    background: gold;
}
#text-sample span.rtop span, #text-sample span.rbottom span
{
    display: block;
    height: 1px;
    overflow: hidden;
    background: black;
}
span.r1
{
    margin: 0 5px;
}
span.r2
{
    margin: 0 3px;
}
span.r3
{
    margin: 0 2px;
}
span.rtop span.r4, span.rbottom span.r4
{
    margin: 0 1px;
    height: 2px;
}

div#text-sample-inner
{
    position: absolute;
    top: 3px;
    left: 3px;
    width: 300px;
    z-index: 2;
    background: white;
}
#text-sample-inner div.rcontent
{
    padding: 1px;
    background: white;
    margin: 0px;
    color: black;
}
#text-sample-inner span.rtop, #text-sample-inner span.rbottom
{
    display: block;
    background: black;
}
#text-sample-inner span.rtop span, #text-sample-inner span.rbottom span
{
    display: block;
    height: 1px;
    overflow: hidden;
    background: white;
}
p
{
    margin: 0px;
}

htmlファイル"angleCircle.html"

<html>
<head>
<link rel="stylesheet" href="angleCircle.css" type="text/css" title="Default">
</head>
<body style="background-color: Gold">
<p>
test</p>
<div id="contener">
<div id="text-sample">
<!-- フタ -->
<span class="rtop"><span class="r1"></span><span class="r2"></span><span class="r3">
</span><span class="r4"></span></span>
<!-- フタ -->
<!-- 中身 -->
<div class="rcontent">
<p>
<a href="http://garage.mods.jp/ex/css-circle/">スタイルシートで角丸を実現する方法</a>の角丸ウィンドウを二枚重ねることによって枠を作っています。
</p>
</div>
<!-- 中身 -->
<!-- 底 -->
<span class="rbottom"><span class="r4"></span><span class="r3"></span><span class="r2">
</span><span class="r1"></span></span>
<!-- 底 -->
</div>
<div id="text-sample-inner">
<!-- フタ -->
<span class="rtop"><span class="r1"></span><span class="r2"></span><span class="r3">
</span><span class="r4"></span></span>
<!-- フタ -->
<!-- 中身 -->
<div class="rcontent">
<p>
<a href="http://garage.mods.jp/ex/css-circle/">スタイルシートで角丸を実現する方法</a>の角丸ウィンドウを二枚重ねることによって枠を作っています。
</p>
</div>
<!-- 中身 -->
<!-- 底 -->
<span class="rbottom"><span class="r4"></span><span class="r3"></span><span class="r2">
</span><span class="r1"></span></span>
<!-- 底 -->
</div>
</div>
</body>
</html>

この方法は、widthを設定していたり、中身を2つ必要としているし、あまりスタイリッシュじゃない。
二枚重ねるのではない方法も考えているのだけれど、CSSはよくわからないのでうまくいかない・・・。
その方法とは、えっと、フタや底の部分を<div>タグでくくって、中に角丸を作っている<span>タグを2つ入れてposision:absolute;にする。こうすると<div>タグの(0,0)に重なるから、内側になる角丸をmarginで(フタの場合は)少し下げる。(底のほうは上げる)
んで、中身は、border-widthで左右だけ枠線を書く。
そして、フタ、中身、底をposition:relative;にして並べる。
これでいいと思うんだけどな・・・。

2007年12月20日 (木)

TIPS:クリティカルセクション

今日、他人が作ったプログラムでクリティカルセクションを使っているのを見て、ふと疑問に思った。
そのプログラムでは、関数の実行開始時にEnterCriticalSection関数(排他設定)を実行、関数終了時にLeaveCriticalSection関数(排他解除)を実行している。
その間に呼び出す関数でも同じように排他の設定、解除を行う。
つまり、排他設定を複数回 実行し、排他解除を同じ回数 実行する。

クリティカルセクションってのは、1つのプロセス内の複数のスレッドで1つのリソースを使うときに排他を行うための仕組み。同じスレッドでは複数回、EnterCriticalSection関数(排他の設定)を実行できる。

んで、疑問に思ったのは、LeaveCriticalSection関数は、1回実行したら排他が解除されるのだろうか?それとも、EnterCriticalSection関数を実行した回数とおなじ回数 LeaveCriticalSection関数を実行しなくてはならないのだろうか?

ITPro「第3回 マルチタスクに不可欠な同期の仕組みを学ぶ」のプログラムを参考に実際に試したところ、EnterCriticalSection関数を実行した回数分、EnterCriticalSection関数を実行しないと排他は解除されず、ほかのスレッドは動作が停止した。もちろん同じ回数実行したら、ほかのスレッドは動作した。
めでたしめでたし。

2007年12月13日 (木)

サーバサイドから更新できるComet

@IT「Tomcatはどこまで”安全”にできるのか(3)」より

Ajaxってクライアントからサーバへ要求をだせるのだけど、サーバからクライアントに更新するようには出来ない。
チャットなどのシステムをAjaxで実現するには、クライアントから一定間隔でサーバに更新があるか確認しなければならない。多量に接続されると、要求数が膨大になってサーバがアップアップになって、場合によってはダウンしてしまう可能性も出てくる。
この問題を(擬似的に)解決する方法が、Tomcat6の新機能のCometというわけ。
どうやるかって言うと、クライアントからリクエストを出さしておいて、サーバはすぐにレスポンスを返さず持ったままにする。更新が発生したら、そのときにレスポンスを返す。
こうすれば、更新がないのにクライアントからの要求に応答する必要はなくなる。要求数を抑えられてサーバも安泰というわけですわ。

2007年11月12日 (月)

覚書:Perlで変数同士の文字列比較について

Perlで文字の検索というと、正規表現を用いた方法を思い浮かべるが、変数同士ではできないの?やり方があるのかさえわからないのだけど、ま、文字関数を使えばよろし。
ある変数の値にある文字がもう一つの変数の値(文字列)にあるか調べるにはindex関数を使う。(正確に言うとindex関数は、何番目に文字があるかを返す。文字列でも可)

$a='abcde';
$b='b';
if(index($a,$b)>-1) {
    print "true";
} else {
    print "false";
}

これを実行するとtrueが出力されます。
#2007/11/16修正:0より大のときtrueになるというのは間違いだった。index関数は、一番目の文字がヒットした場合0を返す。なので、-1より大にしないと。文字が見つからない時は-1になる。

SAKさんのサイトの「SAK図書館」を参考にしました。

2007年10月10日 (水)

覚書:PerlとAjaxの連携 の続きというか愚痴というか

昨日、WebサーバのCGI(Perl)とクライアントのAjaxを連携するために、どうやってSessionを使うかを示したわけだが、当初、考えていたことは実現できないことに気付いた。

というのも、Wizardry for Ajaxを作るための実験を@homepage上でやろうとしている。迷路データとかユーザデータとかを呼び出しごとに毎回、ファイルから読み込むのは遅くなる要因となるので、Sessionを使ってオブジェクトを継続できたら早くなるじゃん、と思ったのだ。
でも、CGIは、呼び出し毎にプロセスが生成されるので、呼び出し毎の処理間に継続性はなくて完全に独立している。つまり、オブジェクトを生成してもプロセス毎に寿命が尽きるので、Sessionで渡せるわけがない。やってみたから間違いない(T_T)。
※:Sessionは、どうやら文字列しか渡せないようなのだ。(オブジェクトも渡せると思い込んでしまっていた。まだちゃんと調べていないけど)
Session間で同じオブジェクトを扱うには、オブジェクトをシリアライズ(この場合は、オブジェクトのメンバ変数の値を文字列化)して、次のSessionでメンバ変数に値を設定するようにするしかないと思われ。
ということは、迷路データとか変化しないものを持つオブジェクトをシリアライズする必要性は全くなくなってしまう。適切なデータ形式のファイルなら、毎回、そのファイルを読み込めば良いわけ。

JSPならWebサーバのプロセスで、オブジェクトを継続して持てる(Applicationだっけ?)ので、話は楽なんだけどな。

とまぁ、失敗談をつらつらと書いてしまったが、本を読まないと書くネタが半減してしまって、困ってしまう。情報処理技術者試験対策中なので、いつも本読みタイムである通勤時間に、教本を眺めているのだ。あともう少しで試験なので、そこを過ぎれば、積読を消化できる!
さて、初めは何を読もうかな?リハビリの意味を込めてラノベから行きますか。というわけでDOORSに決定!
試験をがんばろ。

2007年10月 9日 (火)

覚書:PerlとAjaxの連携

CGIの言語がPerlであるWebサーバ(ここでは@homepageが対象)に対して、Sessionを用いたAjaxとの連携について、覚書を記す。

  • Sessionの機能は、Walrus::Session::Liteモジュールを使って実現する。(使い方は、リンクを参照のこと)
  • クライアントにSession IDを渡すのはCookieを使う。CookieはCGIモジュールを使って実現する。
  • クライアント(Ajax=XMLHttpRequest)に渡すヘッダに、以下のようにCookieを使ってSession IDを設定する。
print $cgi->header(-charset=>'UTF-8',-cookie=>$cgi->cookie(-name=>'CGISESSID', -value=>$session_id));
  • Sessionを作るCGIと使用するCGIを一つのファイルで兼用する場合、CookieからSession IDを受け取って、それに対するSessionが存在するか見る。ないなら作る。
    ※:下記のPerlプログラムは動作確認していません。
#!/usr/local/bin/perl

BEGIN { unshift(@INC, "/cgi-bin/libs"); }
use strict;
use CGI;
use Walrus::Session::Lite;

my %session;
my $data;
my $cgi=CGI->new;
my $session_id=$cgi->cookie('CGISESSID')||$cgi->param('CGISESSID')||undef;
my $session_obj = tie(%session, 'Walrus::Session::Lite', './.session', $session_id);
my $sid  = $session{'_session_id'};
    if(defined $sid && $sid eq $session_id){
        #Sessionがあるときの処理
        $data = $session{'DATA'};
    } else {
        #Sessionがないときの処理
        $session_obj = tie(%session, 'Walrus::Session::Lite', './.session');
        $session_id  = $session{'_session_id'};
        $data = 'TEST';
        $session{'DATA'} = $data;
    }
    print $cgi->header(-charset=>'UTF-8',
                    -cookie=>$cgi->cookie(-name=>'CGISESSID',
                                         -value=>$session_id)),
        $cgi->start_html(-lang=>'ja',
                        -encoding=>'UTF-8',
                        -title=>'test'),
        $cgi->p('DATA='.$data.'<br/>'),
        $cgi->end_html;
  • クライアント側では受け取ったCookieをdocument.cookieで参照する。Cookieを参照する分にはAjaxだからと言って特別なことはない。
  • クライアントでCookieから参照したSession IDをXMLHttpRequest()でサーバにリクエストと共に投げる場合は、prototype.jsなら、以下のように、第二引数のうちのparametersにrequestHeaders:を用いてCookieを設定する。
    new Ajax.Request(
            mapURL,
            {method: 'get',
            asynchronous:true,
            onComplete:getData,
            parameters:bearings, requestHeaders:['CGISESSID',session_id]});

こんなところかな?
あー、あと、Ajax.Request()の第二引数のうちのasynchronous:はtrueしか設定できないようだけど、どうなのよ?初め同期にしたかったからfalseにしていたけど、全然CallBack関数を呼んでくれなくて悩んだよ。asynchronous:を省略したTPでは動いていたので気付いたんだけどさ。

2007年8月 5日 (日)

@niftyのホームページでPerlを使ってみようとしている 四杯目

@homepageでPerlを使ってセッション管理を行う方法を探していたのだが、やっと方法が見つかった。

CGI::SessionとApache::Sessionを使ってみたのだが、依存関係だかなんだかのエラー(だと思う)がでて、解決方法がわからない。
というわけで、ほかにモジュールがないかと探してみたら、Walrus::Session::Liteというのがあった。
これを@homepageに入れたら使えた。よかったよかった。

2007年7月29日 (日)

@niftyのホームページでPerlを使ってみようとしている 三杯目「KCatch.pmは良い物だ」

@homepageで動くCGIでセッション管理をするため、CGI::Sessionをつかってみたのだが、WindowsのActivePerl+Apacheでは動作するが、@homepage上では動かなかった。前回は、モジュールの相性(バージョンが合わない)と結論付けたが、どうも違う模様。
その後、Apache::Sessionも使ってみたのだが、これもだめ。

@homepageでは、エラーになったという表示は出るけどなんのエラーになったは出ない。
んで、ぐぐってみるとありました。
CGIで発生したPerlのエラー情報をHTMLとして返してくれるモジュール ”KCathc.pm”が!
詳しくはKawa.netxp(川崎有亮さんのサイト)を参照してください。

んで、結局はモジュールが足りなかったとのこと。
というわけで、足りないモジュールを追加していくと、Config.pmのところでよくわからんエラーが出てしまい、現在調査中。

2007年7月26日 (木)

プログラム考察:関数

かつてアセンブリ言語では、複数の箇所で実行する一連の命令群をサブルーチンとして一か所にまとめていた。サブルーチンとしてまとめることにより、プログラムサイズを減らすことができた。(代わりにサブルーチンを呼び出すコスト=実行性能やスタックなどを犠牲にしていたけど)
これが今日の関数の始まり。
基本的には、複数の箇所で実行する処理を切りだして関数とする。

しかし、関数の意味はこれだけではない。
処理の意味(=機能)ごとに関数にまとめることによって、プログラムの構造を把握しやすくできる。生産性の向上になるわけ。
(むかしはエディタがプアだったので、ひとつの関数の行数は40行とか制限があったけど、今さらだよね。今は、そんな行数制限するべきではなく、分かりやすい範囲の行数にするべき。)
いまのコンパイラは優秀なので、1回しか実行されない関数であっても実行性能に影響はほとんどない。(いまどき、実行性能を考えて保守に不利なコーディングをする人も少ないだろう。ほかの所で実行性能を上げる苦労をしとけ)
まさにオブジェクト指向は、機能の意味でメソッドを作るという考えで成り立っている。

まあ、どのように関数を作ればいいかわからない人は、関数のテスト(=モジュールテスト)をするためのMCL(日立製作所だけの用語か?)を作成するのに、条件を書き込みやすいような関数にするべき。条件が増えたら関数を分割する。
というのも、あまり大きな関数になると
→条件が多くなるとプログラムが読みにくくなる。
→読みにくいと、保守性が悪い。バグを作り込みやすくなる。
→条件が膨大だと、MCLを作り辛いし、条件網羅性を満たすためデバッガで条件をいろいろ設定しなければならないのでテストしにくい。

関数を小さくすると
→条件が少ないので関数のコードを読みやすくなる。逆に関数が増えてどこに何があるのやら。コメントを活用したり、関数名の規則を厳密にするべし。(ヘッダに関数宣言を列挙して、そこに関数の意味の概要を書いとけ)
→読みやすくなると、保守性がよくなる。修正も小さな関数単位の影響で済むかもしれない。(そのように作れば)
→条件が少ないので、MCLを作りやすい。ただし、関数ごとにMCLを作るので枚数が多くなる。(担当を分けられるね!)条件が少ないのでデバッガで設定しやすい。テストしやすい。

まあ、関数の分割をあまり細かくするのは考え物だけど、ん万Stepの関数を書くのはバカの所業だぜ。いまどきCOBOLERでもそんなのかかない(よね?)

2007年7月22日 (日)

@niftyのホームページサービスでPerlを使う おかわり

@homepageでCGIを使えるようになるべくいろいろ苦労して、Solaris用のPerlを落としてきてライブラリをアップロード+JSON.pmをCPANから拾ってきて同じくアップロードすることによって、JSONデータを扱うことはできた。CGI.pmも使える。

でも、・・・でも!
CGI::Sessionが使えないようぉ。
これもCPANから最新版を拾ってきて、アップロードしてみたんだけどCGIプログラムがエラーになって動作しない。
とりあえず、以下のことを確認した。

  • CGI::Sessionを使うテストプログラムを、うちのマシン(Windows)に入れたApacheから動作させて見た。これは正常に動作した。
  • sessionディレクトリにSessionデータを格納するようにしていたので、権限の可能性もあるとおもい、777にしてみたが駄目。ついでに、このディレクトリにファイルを出力するCGIプログラムを作ってみたが、正しくファイルが作成される。
  • ライブラリが駄目なのかと思い、@homepageにアップロードしたライブラリ+CGI::Sessionモジュールをうちのマシンで動くか試してみた。正しく動く。

ここから導きされる結論は、環境とかCGIプログラムの問題ではなく、CGI::Sessionのモジュールが@homepageのPerlでは動かないということ。Perlのバージョンが問題なのか、SolarisではCPANのCGI::Sessionが動かないものなのかといったところか。
Cookieは動くみたいだから、独自にSessionを組むか、それともほかのSessionモジュールを使ってみるか。

2007年7月21日 (土)

プログラム考察:コメント

今、あるソフトウェアの不良の調査をしているのだが、こんなとき役に立つのがコメント。
でも、役に立つコメントと役に立たないコメントがあるわけで。

コメントは、以下の役割がある。

  • 処理の意味を示す。これはレベル(ファイル・モジュールレベル、関数レベル、コードレベル)でそれぞれ書くべき内容がある。
    ファイル・モジュールレベルは、そのファイル、モジュールにある関数などの種類を説明する。逆に言うとコメントの説明に合わない関数は、別のファイル、モジュールに入れるべき。
    関数レベルは、関数の仕様を書く。何をする関数か、引数・戻り値の意味を書く。
    コードレベルは、1行~複数行の処理の意味や注意事項を書く。(といっても、”1を足す”とかではなく、”xxインデックスをカウントアップする”といったように、対象は何なのか、それをどうするのかを書く)
  • 検索のキーワードとなる。
    デバッグするときに問題となる処理を探すのだが、初めはなにもわからないので、プログラムを読むことになる。全てソースを読むわけにはいかないので、特定のキーワードで検索を行ってあたりを付けることになる。

コメントが書けないということは、その本人が処理を分かっていないということなので、その処理を分かりやすく変えるべきである。

逆にコメントに書いてはいけないというものもある。

  • 現状の処理とそぐわないもの。嘘があるとソースを読んでいて混乱する。修正をしたことによって処理が変わるならコメントも変える。訳が分らないソースを読んでいると頭がぼやけるので、コメントを信じてしまう・・・。
  • ふざけた内容。顔文字が書いてあったり、なれなれしい風に書いてあったり(”だっちゃ”とか”だよん”とか)すると、こんなこと書いてないで品質を上げろ!とイライラする。
  • 保守していると、不要になったプログラムを後で使うかもと思って、処理をコメントにすることがあるけれど、いらね。読みにくいし、検索の邪魔になるし、いいことはない。残す代わりに、こんな修正をしたとコメントに書けばいいじゃん。

あー!もう、ほんと訳が分らんプログラムを読んでいるときにふざけたコメントに当たると、ブチ切れる!!

2007年7月12日 (木)

@niftyのホームページサービスでPerlを使う

前回、@niftyのホームページサービスのCGIのうちPerlにはライブラリがないので、CGIなどが使えないと書いた。そして、適当にWindows用のActivePerlとかLinuxのPerlのlibsの下のものを、/cig-bin/の下にコピーしたところ、strictくらいは使えるようになったのだけど、CGI.pmとかはダメだったとも書いた。
これはこれらのPerlのバージョンが5.8であったことも要因の一つだと思われる。
しかし、実行ログを見られないので、どんなエラーになったかまったくわからない。

あれからググってみると、バージョンが違うと駄目だということがわかった。
また、日曜プログラマの道具箱から@niftyのホームページサービスは、solarisで動作しており、Perl5.00502であることも分かった。

ということで、SolarisのPerl5.005を探してみると、CPANからnsPerl(Solaris版でバージョン5.005_03)にたどりつき、これをダウンロードした。展開するとちょうどlibsディレクトリがあったので、これの中のファイルを@niftyの/cgi-bin/libsディレクトリ下にコピーしたところ、CGIやJSONのモジュールが動作した。

だけど、作ったプログラムが動かねぇ!

2007年7月 9日 (月)

@niftyのホームページでPerlを使ってみようとしている

皆様ご存知の通り、@niftyのホームページサービスは、CGIとしてshシェルとPerlが使えるわけですが・・・。
そこらに転がっているPerlのCGIプログラムを使おうにも、CGIとかライブラリが入っていない状態なのですわ。(動くか試していないけど)

というわけで、ライブラリを使えるようにActivePerlのlibディレクトリの下を丸々/cgi-bin/に入れてみると、strictは使える様になりました。

・・・が、一番使いたいJSONが使えない。
絶望した!

2007年6月28日 (木)

Perlの配列をメンバ変数に入れる

久しぶりにPerlをいじっている。というか、ほおっていたプログラムを完成させようかと思って、修正しては動かしてPerlの仕様について学習しているといったところか。

んで、package内のメンバ変数(といっていいのか?)に対して、配列を追加していく方法がやっとわかった。
というのもメンバ変数は、

$self->{meber};

という風に記述する。これを配列として扱う表記方法がわからなかったのだ。

@list = $self->{meber};

と書いて、@listに要素を追加しても $self->{meber} に入れる方法がわからない・・・。

$self->{meber} = @list;

とかくと、$self->{meber}に @list の要素数が入ってしまうのか?

とまあ、もったいぶってもしょうがないので、以下に例を示してみる。
ファイル名:test.pl

use strict;
use Ctest;

my $objCtest = new Ctest;
$objCtest->setter(1,1);
$objCtest->setter(2,2);
$objCtest->setter('a','a');

$objCtest->getter;

ファイル名:Ctest.pm

package Ctest;
use strict;

sub new {
    my $class = shift;
    return bless {
        m1 => []
    }, $class;
}

sub setter {
    my ($self, $d1, $d2) = @_;
    push(@{$self->{m1}}, {x=>$d1, y=>$d2});
    my $cnt = @{$self->{m1}};
    print "Ctest1::setter cnt=$cnt\n";
}

sub getter {
    my ($self) = @_;
    foreach (@{$self->{m1}}) {
        print "Ctest1::getter $_->{x} $_->{y}\n";
    }
}

1;

これを実行すると以下の結果となる。

c:\>perl test.pl
Ctest1::setter cnt=1
Ctest1::setter cnt=2
Ctest1::setter cnt=3
Ctest1::getter 1 1
Ctest1::getter 2 2
Ctest1::getter a a

2007年6月 1日 (金)

なんかVistaのIEって動作がおかしくね?

FMV BIBLO MG70WのOSは、Windows Vista Home Premiumで、これにはnternet Explorer 7が入っている。

で、これは動作がおかしいところがいくつかある。

  • ココログを編集しようとログインボタンを押すと、別のウィンドウが開く。XPで同じ操作したときは、そのウィンドウの画面が変わったのに・・・。
  • 同じくココログの記事の新規投稿でアフィリエイトの画面を開くと、ポップアップ画面が開くのだが、そちらは「ページが表示できません」と出て、別のウィンドウの新たなタブが開いてそちらに表示される。アフィリエイトの”リンクの作成”ボタンを押しても、アフィリエイトは貼り付けられない。”HTMLをコピーして貼り付ける”画面が出てきて、HTML文をコピペしなくてはならない。面倒。
  • 時々メニューバーが表示されない時がある。設定は”メニューバー”にチェックがついたままで変更できない。→ツールバーのNortonツールバーを表示させると、メニューバーの設定も有効になる。
  • タブを多く開いていると、右クリックやダウンロード、リンククリックが効かなくなる。OutLookが開いていたときに起きたのだが、OutLookを閉じると改善したこともある。

FireFoxとかOperaを入れようか・・・。FireFoxはレジュームでメモリをドンドン占有するバグは治ったのだろうか?

#2007/6/2追記:FireFox2.0.0.4とOpera9.2.1を入れた。FireFoxはやはりレジュームするとメモリ占有量がどんどん増えていく。FireFoxを終了させないとメモリが解放されない。Operaはココログで記事の再編集でHTML文が表示されて使いにくい。
普段はOperaを使って、ココログで記事の作成はFireFoxを使う方向で。IEは、IEでしか動かないページを見るときにしか使わない。

2007年2月 6日 (火)

Perlの配列・ハッシュについて

perlでJSONを扱うとき、{} []を使う例があり、この2つは何なのか良く分からなかったのだが、ここを見て分かった。
{}はハッシュのコンストラクタ、[]は配列のコンストラクタである。
配列について、()と値を比較してみた。

$obj1 = ["foo", "bar", "baz"];
@obj2 = ("foo", "bar", "baz");
if (@$obj1 == @obj2) {
    print "Equal!\n";
} else {
    print "Not equal!\n";
}
@obj1_ = @$obj1;
$len1 = @$obj1;
$len2 = @obj2;
print "@obj1_ = $len1 : @obj2 = $len2\n";
for($i = 0; $i < 3; $i++){
    if($obj1->[$i] eq $obj2[$i]) {
        print "$obj1->[$i] : equal!\n";
    } else {
        print "$obj1->[$i] : $obj2[$i]  : Not equal!\n";
    }
};

結果はこうなる。

Equal!
foo bar baz = 3 : foo bar baz = 3
foo : equal!
bar : equal!
baz : equal!

んで、このコンストラクタは、どうやって使うのかというと、上のほうで紹介したサイトにも書いてあるけど、関数の戻り値が配列のとき、その値を配列に入れるときなどに使う。コンストラクタを使わずに配列に入れると、リファレンスが入るので、配列全てに最後の値が入った状態になる。
これを回避するためにコンストラクタを使う。
ここら辺もperlの分かり辛いところの一つだなぁ。ポインタを明確に見せないくせにリファレンスというポインタまがいのものを意識しなくてはならない。

2007年2月 3日 (土)

秘匿性の高いWebサーバを作る

秘匿性の高いWebサーバは、どうやって作れるか。そのひとつの回答として、URLを頻繁に変えればよいのではないだろうか。
そんなことが出来るのか? 出来ます!
オイラが試しで自宅Webサーバで作って、ほっぽりぱなしだけど、Webページを表示できたシステムがあります。

んで、その方法とは、ADSLを使えば出来る!

■材料

  • Perlを使えるWebサービス(@niftyはOK!)
  • ADSL
  • 自宅Webサーバ

■概要

  1. 自宅Webサーバから外部IPを取得
  2. 外部のWebサービスを利用して、ユーザが自由に参照できるところに外部IPを置く(暗号化しておけば良いでしょう)
  3. ユーザは、外部IPを取得して、自宅Webサーバに接続する

ADSLの外部IPは、固定ではなくADSLモデムを起動する度に変更される。このままでは、ユーザは変更された(外部)IPアドレスを知ることが出来ないので、それを通知する手段が必要となる。DynamicDNSを使う方法もあるけれど、誰でも接続できてしまうわけで。
というわけで、外部IPを特定なユーザに通知する方法を採用する。その方法とは、外部IPをPerlを使えるWebサービスを使って取得する。例えば、オイラが置いておいたところとか。Perlが使えない場合は、DiCEのところ(このページの一番最後を参照)とかを使う。

これをユーザに通知するには、メールを使うのもひとつの手段だけど、外部IPを切り替えるたびにメールを送るのはウザイ。なので、@niftyなどのWebサービスを使って、外部IPをホームページに置いておく。(FTPで転送する)

ユーザは、ホームページにあるその外部IPを使って自宅Webサーバに接続する。外部IPをそのまま置いておくと、誰でも接続できてしまうので暗号化しておく。ユーザには、その暗号化を解除するプログラムを送っておけばよい。こうすれば、暗号化を解読されない限り、外部の人間に接続できない。(暗号は、あからさまに数字の羅列や意味を成さない文字列にするよりは、自由律詩とか標語とかの並びにすれば、暗号と知られないのではなくて?)

まあ、こんな感じ。
このシステムを使って、仲間内でMP3を公開しようとしていたのだが、うまくいかなかった。
複数のMP3ファイルをダウンロードさせるのに、MP3ファイルのリスト(URLで表記)をm3uファイルにしたのだけれど、認証とかの関係なのか参照できないとエラーになり再生できなかった。自宅から参照したときは、RealPlayerなら再生できたのに・・・。(WMPは駄目くさい)
まあ、そんなこんなで、WebサーバのOSをFedoraCore 3から5に入れ替えるときに、環境を全て削除してしまったので、今は動かない。
プログラムは残っているので、WebサーバとかDBサーバとかを回復すればよいのだけれど、飽きてしまったのだ。誰か変わりにやる?

2007年1月14日 (日)

リナザウでfirefoxを動かす

久しぶりに「りなざうテクノウ」を見に行ってみると、リナザウでfirefox2が動くとのこと。これがあれば(リナザウを買った当初の目的通り)Ajaxの開発・テストをリナザウで出来る!
詳細は、Reg's libraryさん所のブログ「我思う故に我あり」が詳しく載っています。

どうやらQtopiaでXを動かすX/Qt上でfirefoxを動かすらしい。
ちゃんとやり方を読んでいなかった所為もあり、始めはX/Qtで動かすものとはつゆしらずターミナルから実行して、”Gtk-WARNING:cannot open display”がでて動かねぇと、悩んでいたのだが。(そうなる以前は、インストールしていないパッケージがあって、ライブラリファイルが無いとかも出ていた。)
上記のブログに書いてある手順に従えば、ちゃんと動作します。(pangoは、1.4.1をインストールで”失敗しました”とでるので、仕方なく1.10.0をインストールしています)

以下、失敗したこと。

  • start Xを実行しても、何も起こらない。 → 行っていない手順があると思われ。パッケージのバージョンが違う。入れていないパッケージがある。手順を見直すべし。
  • 日本語が表示されないで□にコードが変わりに表示された。→フォントファイルmonafont-ttfをインストールしていなかった。
  • X Windowでキーの配置がおかしい。”/”とかが”,”になる。→不明。キーマップファイルが無い?

まあ、動作するようになったのだが、猛烈に遅い。start XからX/Qtを起動してターミナルが開くまではそんなに時間はかからないのだが、firefoxが起動するといちいち時間がかかる。Google Mapを表示させようとすると、「処理に時間がかかっているか、応答しなくなっています」とダイアログが出て、処理を続行を選ぶと、そのうちZaurusのメモリ不足のダイアログがでてきて、最終的にはXごと強制終了されてしまう・・・。
うーむ、このままではメインで使えないなぁ。(Xを起動するのも面倒だし・・・)それとも何かが入れ忘れていて遅いのか?

(→2007/1/20追記:gtk+を展開していなかった。入れると少しは早くなった模様。通信速度がネックになっているのかなぁ?いや、NetFrontは同じページでも、もっと早かったから、やはりX/Qt + firefoxが重いのか。また、googleマップはやはりメモリ不足になって落ちる。)

2006年12月17日 (日)

Webのデータをプログラムから読み込むには おかわり

前回の続き。

XMLHttpRequestオブジェクトでWebページを拾ってみる。やりたいことは、認証が必要なページにアクセスしてそこからデータを取得する。まぁ、ウチの会社の勤怠管理のWebページ(認証が必要)と、お客さんの所の勤怠情報が分かれている。この2つの情報が同じか確認するのに、今は手作業で行っていて手間がかかるので、自動化できないかなと。

分かったことは、

  • sendメソッドは、引数がVariant型である。文字列を渡すからといって、String型の変数を渡してもCOMエラー(インターフェイスがない)になる。
  • Webページのformのmethod属性が"POST"の場合は、例のようにsetRequestHeaderメソッドでヘッダを設定する必要がある。
    一方、"GET"の場合は、setRequestHeaderメソッドは要らない。openメソッドのURLのお尻に?とパラメータを付加してsendメソッドは引数なしで実行する。
  • 以下の例を流用して接続に失敗したら、URLが間違っているか、sendメソッドに渡すパラメータの内容が間違っている。パラメータは、実際にWebに接続してソースの<form>タグから、何を渡しているか確認する必要がある。
  • プロキシ認証は、openメソッドの第4数ユーザID、第5引数パスワードに設定するもよし、以下の例のように空文字を渡してもよし。空文字を渡した場合は、sendメソッド実行時に認証ダイアログが表示される。

ということで、大体、実現できたので接続部分を以下に示してみる。具体的にはVBでココログ(フリー)の投稿画面に接続して、ブログ一覧のページにまで移動してみる。その内容は変数strHtmlに入る。表示とかしていないので、デバックモードで最後のほうまで動かして変数strHtmlの内容を見てみそ。(イミディエイト ウィンドウで?strHtmlを実行して、出力結果をテキストエディタにコピーしてみると”ブログ一覧”があることで分かる。)
これには、ココログフリーのユーザIDとパスワードが必要です。(ユーザIDはUSER_NAMEに、パスワードはPASSWORDに設定してください)

Const USER_NAME As String = "" 'ユーザIDを設定してください
Const PASSWORD As String = "" 'パスワードを設定してください。

Private Sub CommandButton1_Click()
    Dim objHttp As Object
    Dim strHtml As String
    Dim varSendData As Variant
    Dim iStatus As Integer
    Dim strStatus As String
   
    If objHttp Is Nothing Then
        Set objHttp = CreateObject("MSXML2.XMLHTTP")
        If (Err.Number <> 0) Then
            Set objHttp = CreateObject("MSXML.XMLHTTPRequest")
        End If
    End If
   
    ' ココログフリーに接続 → ブログ一覧ページに移行(ブログタブを選択して開くページ)
    With objHttp
        varSendData = "username=" & USER_NAME & "&password=" & PASSWORD & "&remember=1"
        .Open "POST", "https://app.f.cocolog-nifty.com/t/app", False, "", ""
        Call .setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
        .send varSendData
        iStatus = .Status
        strStatus = .statusText
       
        If iStatus >= 200 And iStatus < 300 Then
            strHtml = .responseText
        Else
            MsgBox "接続失敗" & vbCrLf & iStatus & ": " & strStatus
            Exit Sub
        End If

        .Open "GET", "https://app.f.cocolog-nifty.com/t/app/weblog", False, "", ""
        .send
        iStatus = .Status
        strStatus = .statusText
       
        If iStatus >= 200 And iStatus < 300 Then
            strHtml = .responseText
        Else
            MsgBox "接続失敗" & vbCrLf & iStatus & ": " & strStatus
            Exit Sub
        End If
    End With
End Sub

2006年12月 9日 (土)

Webのデータをプログラムから読み込むには

Webサイトの内容やWeb上のデータをプログラムから取得するには、以下の方法がある。(試していないけど)

  • TCPオブジェクトでhttpを実装する
  • Web Browserコントロールを使う
  • XMLHTTPオブジェクトを使う

おそらく一番簡単なのはWeb Browserコントロールを使う方法なのだろうが、フォームに貼り付ける必要がある。内容も表示されるし。
XMLHTTPオブジェクトも簡単である。こちらは、内容を表示しないでXMLまたは文字列として取得できる(XMLとして読み込むには、XMLの体裁が整っていないとだめ)。そして今、使われているWindowsでは標準といって良いほどインストールされている。
加えて、認証も引数から設定することも、Webブラウザと同じくダイアログが開いて入力を促すことができる。

というわけで、お客さんのところの勤怠データと、ウチの会社の勤怠データ(Webで管理)の照らし合わせするプログラムを作っている。そこでXMLHTTPオブジェクトを使おうとしているわけだ。

2006年11月30日 (木)

Perlを勉強中

ファイルに格納したJSON形式のデータを切り出して、XMLHttpRequestで受け取ることを考えている。
NiftyのホームページにCGIを置いて、そちらからデータを受け取る。(自宅サーバはまだ停止中だし、外部に公開したくない。しかもADSLだから、ADSLモデムを再起動するとIPは変わるし)

NiftyのCGIは、Perlかシェルを使えるが、シェルはまったく肌に合わないので、Perlを使用する。というわけで勉強中なのだが・・・。
Perlって、なんというのか、古き良き時代のハッカーが”俺様、天才”的考えで作り上げたって感じ。引数とか省略できることとか、変数の型(@,%,$を頭につけるところ)とか、そんなところが。

んで、CPANのJSONにある、{ }や[ ]は、ハッシュやリストらしいということはわかったのだが、手持ちの本ではハッシュは変数の頭に%を付ける、リストは変数の頭に@を付ける、データは( )で括るとあり、その違いはなんなのかわからなかった。eachやkeys、valuesでキーや値の一覧が取れないし。

なんとなくひらめいたので、”Perl オブジェクト”のキーワードでググッてみると、やはりオブジェクトみたいなものらしい。(まだ良くわかっていない)
オブジェクトにあるハッシュの値を取るには”->”を使う。例えば、CPANのJSONにある以下のデータは、

$obj = {
    id   => ["foo", "bar", { aa => 'bb'}],
    hoge => 'boge'
};

$obj->{id}[0];とやると"foo"が取れる。
$obj->{id}[2]->{aa};とやると"bb"が取れる。

でも、keysとかvaluesでは値が取れないので、どうやって何が入っているのか調べるのかは今のところ不明。オブジェクト指向ということで、見られないのか?でも、リストの数くらいわからないとあかんよな。

ちなみに、リストの値(idの中)は、以下のようにすると舐められる。(参考は、ここのHP

@e = $obj->{id};
for my $ref( @e ){
    for $ref2( @{$ref} ){
        print $ref2, "\n";
    }
}

なんか、複雑怪奇だな・・・。
あと、JSONモジュールのjsonToObj()に引数にファイルから読み込んだ(文字列の)JSONデータを入れても、ちゃんとオブジェクトになるようである。

2006年11月22日 (水)

リナザウのPerlでJSONを使うとき

PerlでJSONを扱うのには、単純にCPANからJSONを落としてきて、それを”use”で指定すればよいのだが、ウチの環境では、以下のフォルダに入る。

/home/root/.cpan/biuld/JSON-1.07/lib/

Perl実行時に-Iで指定しない限り、通常は@INCのみを参照しに行くわけで、上記のパスは普通、指定されていない。面倒なので以下のようにリンクを貼った。

#ln -s /home/root/.cpan/build/JSON-1.07/lib /usr/local/lib/site_perl

リンク先は@INCにあるパスであるが、これはperlの-Vで確認できる。(パラメタファイルで設定できると思っていたのだが、コンパイル時の指定で固定されているのか?)

→2006/12/3追記:よく見たら上のリンク元のフォルダはJSONじゃん。このままじゃ他のモジュールを入れたら変になるかも。検討しなおさなければ・・・。

2006年11月20日 (月)

ソフトウェアエンジニアリング論文集80'sを読んで

ソフトウェアエンジニアリング論文集80'sを読んでいる途中なのだが、「STATEMATE:複雑なリアクティブシステムの開発作業環境」と「合理的な設計プロセス:それを真似る方法と理由」からふと思った。

システムを構築する上でどこでミスを作りこみやすいかというと、仕様書からプログラムに落とす所だと思う。例えば、仕様書の意図したところを読み取れなかったとか、変数を間違えたとか。
ま、これは仕様書をちゃんと作っているところに限る。
大体のところは、大きなシステムであっても仕様書を作らない所は少なくない。「仕様は、プログラムに全て書いてある」というのは、当たり前なのだが、現在そのプログラムは、言語という形をとっており、容易に一部および全体像を把握するには無理がある。

これが、図(UMLなどの既存の図示方法でもよいし、それで無理なら新しい図示方法を作るでも良い)を直接コンピュータを動作させれば、容易にプログラムの全体像が見えやすいのではないだろうか?処理全てを図に示すのではなく、システム・コンポーネント・オブジェクト・メソッドというように段階別で見せるようにする。
変数も、大雑把に言うと計算結果(数字だけでなく文字列も含む)、状態とオブジェクトかなぁ?計算結果以外は、図で示せる。計算結果(計算途中も含む)は、箱という形で図に示せばよいか。
一つの図で見せるのが無理ならば、側面を見せるという形で関連図として別の図を示す。これは、他の図と相関関係をもって、一方が変われば他の側面も変化するようにする。

メソッドには、矢印なりでデータの入力の流れを示し、どんな値を入力でき、値の範囲は何で、それ以外はどのように処理するかなんかを示す。ある程度のまとまった処理は、ブラックボックスとして扱い、それらはテストの自動化により確認が行われる。

という具合で図がプログラミング言語となると。これを(CやJavaなどの)言語に落とすと、人の手を加えることになりバグを作りこむ可能性が高くなるので、極力、図のままで扱う。
ま、結局、細かい処理は人の手が入らないとやってられないところがあるので、メソッド内とかは既存の言語で定義することになるのかなぁ?

いままで、グラフィカルプログラミングツールとか、UMLを言語に落とすツールというのは多々あると思うけど、本格的にオブジェクト指向またはコンポーネント指向な図が言語ってないのかな?

と、夢想してみた。

2006年11月18日 (土)

サービス「npkcsvc」ってなんだ?

ノートPCの動作が重たいので、いらないサービスは無いかと思って眺めていたら、見覚えの無いサービス”npkcsvc”というのがあった。説明も無く不気味だったのでちょっと調べてみた。
レジストリからどこの実行ファイルを起動しているか追っていくと、System32フォルダ下のnpkcsvc.exeだった。
このファイルのプロパティの説明を見ると、”nProtect KeyCrypt Service”と書いてある。
あー、セゾンカードをweb上で見るときに入れた、暗号化ツールだわ、これ。

2006年11月 8日 (水)

リナザウにPerlを入れて更新

リナザウ(SL-C3200)にPerlを入れているのだが、ココのサイトの通りに更新しようとするとメモリが足りないといわれPerlが落とされ最後まで実行できない。
ググるとSDメモリをswapパーティションにする方法とかあるようだが、SDメモリをいったんつぶすのはなんなので、このサイトのswapファイルによる方法を試してみる。
まあ、せっかくHDDの豊富な容量を使わないのはもったいないのでSDメモリではなくHDDに作ってみる。

# dd if=/dev/zero of=/hdd3/swap bs=1024 count=131072
# mkswap /hdd3/swap
# swapon /hdd3/swap

んで、root権限でPerlを更新する。

# perl -MCPAN -e shell
cpan> install Bundle-CPAN

やはりメモリ不足で落とされるので、いったん再起動してswapon→Perlの更新を行うと今度はうまくいった。

2006年10月14日 (土)

りなざうのTextToSpeech

SL-C3200に標準で載っている「Text To Speech」は、英文を読み上げてくれるソフトである。
んで、こんなものを読み上げてもらった。

まあ、女性の声なので雰囲気は出ないのだけど。

2006年9月12日 (火)

Ajax.Requestはこう使えばよいのか

Prototype.jsのAjax.Requestに渡すコールバック関数は、オブジェクト内のメソッドを渡しても、thisでオブジェクトの内部変数は参照できない。
まあ、AjaxのFAQに当たるもので、当たり前といえば当たり前である。

これを解決するにはクロージャを使う。

こんな感じ。

<script language="javascript">
function TEST(x){
  var val=x;
  this.dispVal=function(Res){
    alert(val+Res.responseText);
  }
}
var t=new TEST('aaa');
function Read(URL){
  var a=new Ajax.Request(
     URL,
     {method: 'get', asynchronous :true, onComplete: function(Res){t.dispVal(Res); }});

Read('http://test.com/test.txt');
</script>

実行すると、アラートダイアログのメッセージに'aaa'+<http://test.com/test.txtの内容>が出力される。

ミソは、TEST()の変数valに設定することと、TEST()をnewで作ること。
TEST()の変数valは、ローカル変数のように見えるが、メンバ変数と考えればよいのか?そうすると、newしたオブジェクトを保っている間は保持される。(this.valでないことに注意)

これの問題は、クロージャが残ったままになり、溜まりにたまるとメモリリークを起こしてしまうことと、ローカル変数tの処遇に困ること。うまく開放すればよいのだが。

2006年9月 6日 (水)

こんなもの作ってみました おかわり

昨日のJavaScriptで枠内のみ表示されるテーブル(ドラッグにより移動可能)を改造しました。

こちらをクリック。

  • 中のテーブルの初期位置(top)を何故か250pxにしていた。初期位置(top、left)を-10pxにする。
  • 中のテーブルの端が移動させても表示枠から出ないようにした。
  • Opera(9.01で確認)とFireFox(1.5.0.6で確認)にも対応できた。
  • 少しPrototype.jsを使ってみた。といってもイベントの設定とStyleのpositionに'relative'を設定するメソッドを使ってみただけ。

問題は、マウスを動かして端まで来ると、テーブルの内容が選択状態になってしまう。選択したくないのに・・・。どうすれば回避できるのやら。

2006年9月 5日 (火)

こんなもの作ってみました

JavaScriptで枠内のみ表示されるテーブル(ドラッグにより移動可能)を作ってみました。
下のほうの赤い領域内にある、青い領域をドラッグすると移動できます。

  • Prototype.jsを使用していますが、全然使えていません。
  • クリッピングするためにDIVを使用しています。初めは、DIV内にあると移動できなかったのですが、内側のDIVにCSSのpositonを設定したら移動可能になりました。なんで?
  • IE6 for Windowsのみ動作可能。というのも、operaやFireFoxではonmousedownの左マウスボタン押下の番号がちゃんと取得できなかったため。event.buttonじゃ駄目なのか?
    時間が無くて、onmousemoveの引数について調査不足です。

なんに使うかというと、データ量が多くて、データ表示領域をマウスにより移動させる必要があるデータ解析ツールとか。
たとえば、馬鹿デッカイテーブルの内容表示。一部を先に読み込んで、スクロールされて未読領域になったら、その領域を読み込む。うまく表示・移動とリンクして書き換えれば、途切れないデータ表示領域が実現できる、はず。

2006年8月26日 (土)

ドジッた!

「もう疲れたよ・・・、ペロくん。」
ルーベンスの絵の前の床に横たわるタンちゃんとペロくん。
そっと、天使達が2人を空へと案内する。

という心境である。
ソケット通信関数のうち受信関数rcevfrom()のエラーを取得するのにWSAGetLastError()を使用したのだが、何故か時々、131(ファイルの先頭よりも前にファイル ポインタを移動しようとしました。 )や183(既に存在するファイルを作成することはできません。 )を返す。
一日悩んでいたのだが、fopen()を使用するとエラーが発生するらしい。
WSAGetLastError()は、ソケット通信のみのエラーを返すと思っていたため、fopen()を使用するとソケット通信関数に影響してエラーなる!→回避方法がないなぁと結論付けるところであった。

さにあらず。fopen()を実行した結果を受けて、WSAGetLastError()がエラー値を返していたのだ・・・。もち、fopen()は成功している。エラー番号の違いは、開くファイルの有無で変化する。

なんなのだ、この糞仕様は!!
いや、ちゃんと仕様を理解していなかったオイラが悪いのか・・・。

2006年6月17日 (土)

onclickが使えるタグ その2

onclickが使用できるタグの続き。

divタグ、tableタグの内側から外側にクリックイベントが波及していったが、もっと外側にも行くのではないかと、ふと思った。
試しにtableタグの外側にdivタグを置いてみたり、bodyタグにonclickを定義してみると、やはりtd → tr → table → div → bodyに波及した。

うーむ、使い方を誤るとトンでもない事になりそうだな・・・。

2006年6月16日 (金)

onclickが使えるタグ

ふと、onclickはtableタグでも使えるのか疑問に思ったのでググってみた。
MSDNがヒットした。(怪しいことが書いてあるけど・・・)
以下のタグでonclickイベントを使用できるとの事。
ん、tableタグはOK。これで、グリッドオブジェクトが作成できる。

A, ADDRESS, APPLET, AREA, B, BIG, BLOCKQUOTE, BODY, BUTTON, CAPTION, CENTER, CITE, CODE, DD, DFN, DIR, DIV, DL, DT, EM, EMBED, FIELDSET FONT, FORM, H1, H2, H3, H4, H5, H6, HR, I, IMG, INPUT, KBD, LABEL, LEGEND, LI, LISTING, MAP, MARQUEE, MENU, OBJECT, OL, OPTION, P, PLAINTEXT, PRE, S, SAMP, SELECT, SMALL, SPAN, STRIKE, STRONG, SUB, SUP, TABLE, TBODY, TD, TEXTAREA, TFOOT, TH, THEAD, TR, TT, U, UL, VAR, XMP, document

んで、試してみた。table,tr,td/thタグにonclickを設定して、alertを出してみる。
すると、td/thタグ→trタグ→tableタグの順にイベントが発生した。
これは、結構便利かも。tdタグのonclickを消すと、trタグやtableタグで受け取ってもらえる!

onclickありthタグonclickなしthタグ
onclickありtdタグ tdタグonclickなし
<table onclick="alert('table click')" border="1">
<tbody>
<tr onclick="alert('tr click')"><th onclick="alert('th click')">thタグ</th></tr>
<tr onclick="alert('tr click')"><td onclick="alert('td click')">tdタグ</td></tr>
</tbody>
</table>

ということは、入れ子のdivタグも同じく外側のdivタグで拾ってもらえるのか?
試してみる。

onclickありdivタグ
onclickなしdivタグ

<div onclick="alert('外側div click')">
<div onclick="alert('内側div click')">onclickありdivタグ</div>
<div>onclickなしdivタグ</div>
</div>

どうでしょう?ちゃんと拾ってくれますね。
これなら、Windowオブジェクトが作れそうだ。
目指せ、Wizardry for Ajax!!

おまけ。
hrタグにonclickイベントを発行して何に使えるのか?
うまくマウスカーソルを合わすのが難しいけど、線をクリックするとちゃんと発行される・・・。