2007年04月の記事です。
書いた人: ナカシマ@管理人(2007/04/10 15:27:46)
どうもこんにちは。ウェブマスター中島です。最近ウェブにあまりにも動きがないので、ウェブマスター死亡説、失踪説、逮捕説などなど流れていることと思います。今日はそんな噂を払拭したいと思います。というわけで現状報告をば。まず、今何をしようとしているかについて。要はウェブのリニューアルです。主に以下の2点をやっています。
次に現在その目標がどの程度達成できているかについて。デザインに関しては現状よりも幾分ましなものができたと思います。現在のデザインは見た目以外の部分で理想を追いかけすぎた感があります。新しいデザインは、冒険は控えめにして、今の自分の能力で実現できる範囲のものにしました。そのため、見た目は今よりも幾分よくなっていると思います。作っているうちに見慣れて愛着が湧いたということもあると思いますが、それを差し引いても今よりはいいはず…。あんまり自分のデザインセンスが信じられないので、ちょっと断言はできないかもしれません。けど、多分いまよりはいいはず!で、問題はレポートの方なのですが、これが大変でした。というか過去形じゃない。現在進行形で大変です。モノとしてはほとんどできていて、本来ならば今日の朝にでも公開して晴れ晴れとした気分で大学に行く予定でした。ちょっと予想外の壁にぶつかって2日ほど時間をロスしてしまいました。が、今朝通学途中にその解決策を見つけました。根本的な解決にはならないし、幾分対症療法的ですが仕方ありません。というわけでレポートはもうすぐ完成します。つまり、もうすぐ新しいウェブをアップできるということです。以上概要。以下詳細。デザインに関しては略。引継ぎ資料作るときにでもしっかり書いときます。で、CGIについて。多分去年の冬ごろ。スクリプト言語(というか変数に型の無い言語)は難しい!あれでそれなりの規模のものを作るにはやっぱりそれなりの経験が必要だ!ということに気づきました。というわけで出てきたのがD言語。最近バージョン1.000が出た新しい言語。ちょっと興味があっていじっていたので、これでCGIを作れないかなと思いました。検索してみるとD言語でCGIというwikiがあっていろいろと書いてありました。コレはいける!!思えばそれが挑戦と挫折の日々の始まりでした。D言語はスクリプト言語ではありません。だからコンパイラが必要です。ウェブのサーバーはFree BSD。自分のパソコンはWindows。さて、どうしようか。先ほどのwikiにあったこんなページが目に入りました。FreeBSDクロスコンパイルクロスコンパイラというものの存在を始めて知りました。他の環境用のバイナリを作るコンパイラ。Windows(というかCygwin)上でFreeBSD用のバイナリを作れる。そんな素敵なものの存在を初めて知りました。で、いろいろとあったのです。多分2週間くらいかけたと思います。あの手この手でコンパイラをコンパイルしようとしました。コンパイラ自体はできたんです。普通にコンパイルできたんです。ライブラリがコンパイルできなかった…。何回やってもできなかった…。あまりにも時間がかかるので諦めました。よく考えてみると、このサーバーにはTelnetでログインできるじゃないですか。別にローカルでコンパイルする必要も無い。そう思い、今度はサーバー上でコンパイラをコンパイルしようとしました。アクセス権限の関係でマニュアルどおりにはコンパイルできませんでした。いろいろやってみたのですが、どうも無理でした。こんなことならUNIXについてちゃんと勉強しておけばよかったなと思いました。LinuxとUNIXにバイナリの互換性が無いこともこのとき知りました。工夫すればちゃんと動くのかもしれませんが、その工夫の仕方が分かりませんでした。しょうがないので、FreeBSD用のコンパイラのバイナリを入手してきました。最初からこうすればよかったなと思いながら…。このときすでに3月!時の流れの早さの残酷さといったらありません。とりあえず環境はそろいました。後は開発するだけ。まずは小手調べに掲示板をD言語に移植してみようと。これは比較的スムーズにいきました。それぞれのパーツが再利用きくようにそれなりに汎用的に作ったつもりです。そのおかげでレポートのほうもスムーズに作ることができました。かかった期間は、掲示板が約2週間、レポートが約1週間。レポートはかなり効率的につくることができました。あとはレポートの管理機能を作るだけ。まずはユーザーの管理機能。半日で完成。さあ後はファイルのアップロードと記事の投稿機能だけだ。あと少しだ!と思ったら思わぬ壁がありました。改行コードの壁。ちょっとでもプログラムをかじったことのある人なら分かると思いますが、普通、改行を出力する時には\nという文字を使うと思います。UNIXやLinuxでは、この文字がそのまま改行コードとして使われています。この\nであらわされる文字をラインフィードといいます。略してLF。行を送り込む。つまりまあ新しい行を挿入するとかそういう意味でしょうか。これちょっと豆知識。まあそれはいいとして、この改行コード、Windowsでは\nではないのです。Windowsで普通に使われている改行コードは\r\n。余計な\rが付いています。この\rで表れる文字をキャレッジリターン、略してCRといいます。キャレッジとは多分タイプライターの印字部分のことかと思います。改行して新しい行を始めるとき、印字は左端から始まりますよね。その左端にヘッダ(?)を移動される作業のことです。ちなみにMacだと改行コードは\rのみ。とまあOSごとに様々です。なぜWindowsだけ改行コードに2文字も使うのかというと、昔のタイプライターの仕組みに由来しているそうで。あるタイプライターは改行する際に他の文字を打ったときよりも多く処理時間がかかったそうです。そのため、タイプしながらその内容を電信かなんかで送る時、改行のときだけ通信内容との同期がとれず、うまく通信できなかったそうです。そこで、苦肉の策として改行コードを2文字にして時間を稼いだとか。と、ここまで記憶に頼って書いたから間違ってるかも。けどこんな話しを聞いた(読んだ?)記憶があると。あとタイプライターにまつわる話しとしては、比較的有名だけどこんな話も。あるタイプライターは性能があまりよくなくて、すばやく文章を打つと処理しきれなくなってしまったとか。そのため、苦肉の策として考え出されたのが、キーボードの配列をわざと打ちにくいものにしてしまおうというものでした。その配列がQWERTY配列として現在まで生き残っているのでした。だからキーボードは元来効率の悪いものなんです。もっと打ちやすいキーボードとしてはドヴォルザークとかTRONキーボードとかきいたことあるけど詳しく知らないから略。っと。話しがかなり脱線しましたね。で、まあWindowsとUNIXとMacでは改行の文字コードが違うと。そこまで話しましたね。けど、この仕様はいかがなものかと。めんどくさいですよね。改行文字列をそれぞれのOS用にいちいち書き直すとか。しかも改行コードの変換は自動的にできる作業だから、何も考えなくてもちゃんとOS毎に適した改行コードが出力されて欲しい。そう考えるのは当然ですよね。そこで、C言語とか、その他多くのプログラミング言語は、入出力の際、改行コードの変換を自動的に行ってくれます。たとえば、Windowsの場合、\r\nという入力は\nに変換され、\nという出力は\r\nに変換されます。UNIXの場合は元から改行コードが\nなので何も変換されません。という風に、自動的に変換してくれるので、何も考えずにprintf("Hello, World!\n");とか打てて非常に便利なのですが、落とし穴が。\r\nを勝手に\nに変換してしまうとまずい入力が存在するのです。例えば、画像とか、音楽とかそういう文字列じゃない入力で勝手に変換されてしまうと、色が化けたり、酷い時には壊れて開けなくなってしまうことがあります。そのため、そのようなデータを入力する時は、バイナリモードといって、改行コードの変換を行わないモードに変更します。ここが落とし穴だったのです。(CGIの話に戻ってきました。)レポートには画像をアップする機能が必須です。画像は当然バイナリファイル。ということは入力をバイナリモードに切り替えなければなりません。まあさすがにね。入出力に対応しているならそれぐらいできて当然だよね。できないわけな………。そうです。できなかったのです。これはヤバい。とってもヤバい。何がヤバいって、壊れたデータしか手に入らないってのがヤバい。例えば、入力が\r\n\r\nだったとします。すると、手に入るのは\n\nという文字列です。この\nがもともと\r\nだったのか、\nだったのかは分かりません。例えば、手に入ったデータの中に\nが10個含まれていたとします。すると、元のデータは2^10=1024通りのうちのどれか一つということになります。元のデータが推測できるわけがない。バイナリモードに切り替える方法を探したんです。そしたらありました。Cの関数を呼び出せばいいのです。こんな感じに。setmode(filemode(stdin), O_BINARY);ところが。効果が無い。効果が無い。効果が無い。泣けるよね。BCCだと大丈夫なんだよね。普通にバイナリモードになるんだよね。けどD言語が対応しているCコンパイラのDMCだとできないんだよね。Cのプログラムでもできないんだよね。#include #include #include int main(void) { char c; setmode(fileno(stdin), O_BINARY); setmode(fileno(stdout), O_BINARY); while((c = getchar())!=EOF) putchar(c);}こんなプログラム書いて、test.exe < input.jpg > output.jpgって実行しても壊れたファイルしかでてこなかったんですよね。もう諦めました。通学途中の電車の中で。ファイルアップのとこだけ今までどおりRubyで書きます。それで解決!対症療法バンザイ!!現状そんな感じです。根本的な解決策をご存知の方がいらっしゃったらご教授いただけると幸いです。それでは長文失礼いたしました。
コメントをすべて読む / 書く
どうもこんにちは。ウェブマスター中島です。
最近ウェブにあまりにも動きがないので、ウェブマスター死亡説、失踪説、逮捕説などなど流れていることと思います。
今日はそんな噂を払拭したいと思います。
というわけで現状報告をば。
まず、今何をしようとしているかについて。
要はウェブのリニューアルです。
主に以下の2点をやっています。
次に現在その目標がどの程度達成できているかについて。
デザインに関しては現状よりも幾分ましなものができたと思います。
現在のデザインは見た目以外の部分で理想を追いかけすぎた感があります。
新しいデザインは、冒険は控えめにして、今の自分の能力で実現できる範囲のものにしました。
そのため、見た目は今よりも幾分よくなっていると思います。
作っているうちに見慣れて愛着が湧いたということもあると思いますが、それを差し引いても今よりはいいはず…。
あんまり自分のデザインセンスが信じられないので、ちょっと断言はできないかもしれません。
けど、多分いまよりはいいはず!
で、問題はレポートの方なのですが、これが大変でした。
というか過去形じゃない。
現在進行形で大変です。
モノとしてはほとんどできていて、本来ならば今日の朝にでも公開して晴れ晴れとした気分で大学に行く予定でした。
ちょっと予想外の壁にぶつかって2日ほど時間をロスしてしまいました。
が、今朝通学途中にその解決策を見つけました。
根本的な解決にはならないし、幾分対症療法的ですが仕方ありません。
というわけでレポートはもうすぐ完成します。
つまり、もうすぐ新しいウェブをアップできるということです。
以上概要。
以下詳細。
デザインに関しては略。
引継ぎ資料作るときにでもしっかり書いときます。
で、CGIについて。
多分去年の冬ごろ。
スクリプト言語(というか変数に型の無い言語)は難しい!
あれでそれなりの規模のものを作るにはやっぱりそれなりの経験が必要だ!
ということに気づきました。
というわけで出てきたのがD言語。
最近バージョン1.000が出た新しい言語。
ちょっと興味があっていじっていたので、これでCGIを作れないかなと思いました。
検索してみるとD言語でCGIというwikiがあっていろいろと書いてありました。
コレはいける!!
思えばそれが挑戦と挫折の日々の始まりでした。
D言語はスクリプト言語ではありません。
だからコンパイラが必要です。
ウェブのサーバーはFree BSD。
自分のパソコンはWindows。
さて、どうしようか。
先ほどのwikiにあったこんなページが目に入りました。
FreeBSDクロスコンパイル
クロスコンパイラというものの存在を始めて知りました。
他の環境用のバイナリを作るコンパイラ。
Windows(というかCygwin)上でFreeBSD用のバイナリを作れる。
そんな素敵なものの存在を初めて知りました。
で、いろいろとあったのです。
多分2週間くらいかけたと思います。
あの手この手でコンパイラをコンパイルしようとしました。
コンパイラ自体はできたんです。
普通にコンパイルできたんです。
ライブラリがコンパイルできなかった…。
何回やってもできなかった…。
あまりにも時間がかかるので諦めました。
よく考えてみると、このサーバーにはTelnetでログインできるじゃないですか。
別にローカルでコンパイルする必要も無い。
そう思い、今度はサーバー上でコンパイラをコンパイルしようとしました。
アクセス権限の関係でマニュアルどおりにはコンパイルできませんでした。
いろいろやってみたのですが、どうも無理でした。
こんなことならUNIXについてちゃんと勉強しておけばよかったなと思いました。
LinuxとUNIXにバイナリの互換性が無いこともこのとき知りました。
工夫すればちゃんと動くのかもしれませんが、その工夫の仕方が分かりませんでした。
しょうがないので、FreeBSD用のコンパイラのバイナリを入手してきました。
最初からこうすればよかったなと思いながら…。
このときすでに3月!
時の流れの早さの残酷さといったらありません。
とりあえず環境はそろいました。
後は開発するだけ。
まずは小手調べに掲示板をD言語に移植してみようと。
これは比較的スムーズにいきました。
それぞれのパーツが再利用きくようにそれなりに汎用的に作ったつもりです。
そのおかげでレポートのほうもスムーズに作ることができました。
かかった期間は、掲示板が約2週間、レポートが約1週間。
レポートはかなり効率的につくることができました。
あとはレポートの管理機能を作るだけ。
まずはユーザーの管理機能。
半日で完成。
さあ後はファイルのアップロードと記事の投稿機能だけだ。
あと少しだ!
と思ったら思わぬ壁がありました。
改行コードの壁。
ちょっとでもプログラムをかじったことのある人なら分かると思いますが、
普通、改行を出力する時には\nという文字を使うと思います。
UNIXやLinuxでは、この文字がそのまま改行コードとして使われています。
この\nであらわされる文字をラインフィードといいます。略してLF。行を送り込む。
つまりまあ新しい行を挿入するとかそういう意味でしょうか。これちょっと豆知識。
まあそれはいいとして、この改行コード、Windowsでは\nではないのです。
Windowsで普通に使われている改行コードは\r\n。
余計な\rが付いています。
この\rで表れる文字をキャレッジリターン、略してCRといいます。
キャレッジとは多分タイプライターの印字部分のことかと思います。
改行して新しい行を始めるとき、印字は左端から始まりますよね。
その左端にヘッダ(?)を移動される作業のことです。
ちなみにMacだと改行コードは\rのみ。
とまあOSごとに様々です。
なぜWindowsだけ改行コードに2文字も使うのかというと、
昔のタイプライターの仕組みに由来しているそうで。
あるタイプライターは改行する際に他の文字を打ったときよりも多く処理時間がかかったそうです。
そのため、タイプしながらその内容を電信かなんかで送る時、
改行のときだけ通信内容との同期がとれず、うまく通信できなかったそうです。
そこで、苦肉の策として改行コードを2文字にして時間を稼いだとか。
と、ここまで記憶に頼って書いたから間違ってるかも。
けどこんな話しを聞いた(読んだ?)記憶があると。
あとタイプライターにまつわる話しとしては、比較的有名だけどこんな話も。
あるタイプライターは性能があまりよくなくて、すばやく文章を打つと処理しきれなくなってしまったとか。
そのため、苦肉の策として考え出されたのが、キーボードの配列をわざと打ちにくいものにしてしまおうというものでした。
その配列がQWERTY配列として現在まで生き残っているのでした。
だからキーボードは元来効率の悪いものなんです。
もっと打ちやすいキーボードとしてはドヴォルザークとかTRONキーボードとかきいたことあるけど詳しく知らないから略。
っと。
話しがかなり脱線しましたね。
で、まあWindowsとUNIXとMacでは改行の文字コードが違うと。
そこまで話しましたね。
けど、この仕様はいかがなものかと。
めんどくさいですよね。
改行文字列をそれぞれのOS用にいちいち書き直すとか。
しかも改行コードの変換は自動的にできる作業だから、何も考えなくてもちゃんとOS毎に適した改行コードが出力されて欲しい。
そう考えるのは当然ですよね。
そこで、C言語とか、その他多くのプログラミング言語は、入出力の際、改行コードの変換を自動的に行ってくれます。
たとえば、Windowsの場合、\r\nという入力は\nに変換され、\nという出力は\r\nに変換されます。
UNIXの場合は元から改行コードが\nなので何も変換されません。
という風に、自動的に変換してくれるので、何も考えずに
printf("Hello, World!\n");
とか打てて非常に便利なのですが、落とし穴が。
\r\nを勝手に\nに変換してしまうとまずい入力が存在するのです。
例えば、画像とか、音楽とかそういう文字列じゃない入力で勝手に変換されてしまうと、色が化けたり、酷い時には壊れて開けなくなってしまうことがあります。
そのため、そのようなデータを入力する時は、バイナリモードといって、改行コードの変換を行わないモードに変更します。
ここが落とし穴だったのです。(CGIの話に戻ってきました。)
レポートには画像をアップする機能が必須です。
画像は当然バイナリファイル。
ということは入力をバイナリモードに切り替えなければなりません。
まあさすがにね。入出力に対応しているならそれぐらいできて当然だよね。
できないわけな………。
そうです。できなかったのです。
これはヤバい。
とってもヤバい。
何がヤバいって、壊れたデータしか手に入らないってのがヤバい。
例えば、入力が\r\n\r\nだったとします。
すると、手に入るのは\n\nという文字列です。
この\nがもともと\r\nだったのか、\nだったのかは分かりません。
例えば、手に入ったデータの中に\nが10個含まれていたとします。
すると、元のデータは2^10=1024通りのうちのどれか一つということになります。
元のデータが推測できるわけがない。
バイナリモードに切り替える方法を探したんです。
そしたらありました。
Cの関数を呼び出せばいいのです。
こんな感じに。
setmode(filemode(stdin), O_BINARY);
ところが。
効果が無い。
効果が無い。
効果が無い。
泣けるよね。
BCCだと大丈夫なんだよね。
普通にバイナリモードになるんだよね。
けどD言語が対応しているCコンパイラのDMCだとできないんだよね。
Cのプログラムでもできないんだよね。
#include
#include
#include
int main(void) {
char c;
setmode(fileno(stdin), O_BINARY);
setmode(fileno(stdout), O_BINARY);
while((c = getchar())!=EOF)
putchar(c);
}
こんなプログラム書いて、
test.exe < input.jpg > output.jpg
って実行しても壊れたファイルしかでてこなかったんですよね。
もう諦めました。通学途中の電車の中で。
ファイルアップのとこだけ今までどおりRubyで書きます。
それで解決!対症療法バンザイ!!
現状そんな感じです。
根本的な解決策をご存知の方がいらっしゃったらご教授いただけると幸いです。
それでは長文失礼いたしました。