Apacheの設定ファイルをLuaで書く?
ApacheにLuaを組み込み?、なんて話がこの辺( http://mail-archives.apache.org/mod_mbox/httpd-dev/200803.mbox/%3c20080326130647.7f9ae161@grimnir%3e )から始まるスレッドで起こっています。
おそらく組み込まない可能性が高い気はしますが。
Apacheの設定ファイルは歴史的な事情により、わかりづらくなっています。構文があるようで無くて、モジュールが勝手にディレクティブに対して独自な構文らしきものを作ってしまうからです。ドキュメントが充実しているので救われているだけです。
構文がXMLになれば救われるかと言えば、何も変わらないでしょう。本物のプログラミング言語を使えると一部救われる可能性はありますが、複雑な部分はそのままです。
設定ファイルが簡単なのは、パラメータ値の設定だけしかない設定ファイルです。条件分岐(パターンマッチの形式を取ることも多い)があれば、とたんに難しくなります。
やっていることの複雑さの割りに(*)設定ファイルが簡単なのはどのソフトでしょう。個人的にはpostfix辺りを推したいと思います。
(*)やっていることが簡単であれば設定ファイルが簡単なのは当り前なので。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/apache-lua/tbping
イーサネットに関する本
先日、学生バイトからイーサネットに関する本の紹介を依頼されたので、次のふたつの本を薦めました。どちらもイーサネットだけに関して書かれた本ではありません。
「インターコネクションズ」ラディアパールマン 内容は非常に良いのですが、翻訳が悪く読みづらいです。
「コンピュータネットワーク第4版」タネンバウム MINIXのタネンバウムです。
レイヤが下の技術に惹かれるのは、若さの証でしょうか。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/ethernet/tbping
似たようなものを探す能力
プログラミングにおいて、「似たようなものを探す能力」が重要だと思います。 たいていのコードは、過去の似たようなコードを参考にして書かれるからです。 探す先は、自分の記憶だったり、既存コードだったり、書籍やWeb上の情報だったりします。
こう書いてしまうと、プログラミングという作業を過度に貶めてしまう気もしますが、事実はこんなものではないでしょうか。 もちろん、真に創造的なプログラミングをしている人の存在を否定するものではありません。
- 似たようなことをしているコードを探し出す能力
- 探し出したコードを変形して、変化とその因果関係を把握する能力
こういう能力が必要になります。
ここでの「似ている」は、コードの表記が似ているという話ではありません。やろうとしていることが似ている、という意味です。 プログラミングでは、何かを実現したくてコードを書きます。やりたいことが分かっていても、どう書いてよいか分からない時の話です。
とても小さなレベルなら、今ならWebで探すだけです。例えば、現在時刻を取得するコードの書き方が知りたければ、検索エンジンで少し探せばすぐに見つかります。 Webに情報が無い社内独自言語などであれば、社内の既存コードから探すことになるでしょう。これはささやかな例ですが、この時に使うキーワードにもセンスが問われます。
もっと大きなレベルでは、多くの場合、やりたいことが単純にWebでは検索できません。こういう場合、やりたいことを小さなレベルに分解して、それぞれを探す力が必要になります。 例えばWeb系アプリなら、ユーザのフォーム入力を参照するにはどうコードを書くか、データベースから情報を引っぱるにはコードをどう書くか、などがあります。 これらの一般的な書き方はWebで調べると見つかるかもしれませんが、このぐらいのレイヤの話になると、(フレームワークなどの)環境や既存コードの流儀なども関係してくるので、既存コードから似たコードを探すことが必須です。
慣れない外国語で作文をする時のことを考えると、プログラミングの経験が無くても、この作業の難しさの想像がつくかもしれません。
例えば、方程式の解き方を説明する文を外国語で書きたいとします。 単語レベルのキーワードで探し始めるのがひとつの手です。「方程式」や「解」といった外国語の単語で探し始めます。 先に挙げたWeb系アプリの例で言えば、フォーム入力を参照するコードを探すために、parameterなどのキーワードで探すイメージです(ここでparameterというキーワードが出るにはちょっとしたメタ知識が必要ですが)。 一方、外国語で書かれた数学の教科書を参照する手段もあります。これは方程式の解き方の説明は数学の教科書にあるというメタ知識があるからです。 コードで言えば、ソフトウェアの構造上、フォーム入力を参照する箇所はこの辺にあるに違いないと当たりをつけるイメージです。
この辺にあるに違いない、と当たりをつける部分がコードリーディングのスキルです。静的に当たりをつける以外に、デバッガで追うなど動的に当たりをつける方法があります。 ここがなかなか他人に伝承不能な部分で、伝承不能ということは、スキルとしての実体も怪しいのかもしれません。
個人的には、エディタとgrepとデバッガが手に馴染んでいないと困ると思います。 ただし、まれにツールを全然使いこなしていない凄いプログラマもいるので、必要条件では無いようです。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/code-reading/tbping
Apache3.0とHTTP2.0
全般的に暴走気味のプレゼンです。 プレゼンの最初に断っているように、Apache3.0(および途中でHTTP2.0)に対する妄想の世界で、決定事項ではありません。
Roy Fieldingは、Apacheの人と言うよりRESTの人と紹介した方が通りが良いかもしれません。
25ページでHTTP2.0?として提示しているシンタックスは受け入れられない気がします。 一緒に提示しているWakaは、今回言い出した話ではなく、以前から言っているようですが、これも微妙です。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/apache3/tbping
僅か30分で3つのバグ - Rubyの落し穴 -
Rubyでソートキーがふたつあるソート処理を書こうとした時の話です。
実際のデータ構造は違うのですが、簡単のために次のようなデータを用意します。
arr = []
arr.push({:x=>1,:y=>1}).push({:x=>2,:y=>2}).push({:x=>1,:y=>9}).push({:x=>5,:y=>0}).push({:x=>1,:y=>3})
x要素がプライマリなソートキーで、y要素がセカンダリなソートキーだとして、次のようにソート処理を書きました。
arr.sort{|a,b| cmp = a[:x]<=>b[:x]; cmp != 0 ? cmp : a[:y]<=>b[:y]}
=> [{:x=>1, :y=>1}, {:x=>1, :y=>3}, {:x=>1, :y=>9}, {:x=>2, :y=>2}, {:x=>5, :y=>0}]
一瞬で作業終了、と思ったのですが、次のようにnil要素があると、これはエラーになります。
arr.push({:x=>nil,:y=>0}).push({:x=>1,:y=>nil})
arr.sort{|a,b| cmp = a[:x]<=>b[:x]; cmp != 0 ? cmp : a[:y]<=>b[:y]}
ArgumentError: comparison of Hash with Hash failed
nilのソート順は最後にすることに決めて、だいぶ長くなってしまいますが、次のように書き直しました。ブロックがdoに変わったのは気分の問題です。
arr.sort do |a,b|
return 1 if !a[:x]
return -1 if !b[:x]
cmp = a[:x]<=>b[:x]
if cmp != 0
cmp
else
return 1 if !a[:y]
return -1 if !b[:y]
a[:y]<=>b[:y]
end
end
Rubyに慣れた人ならすぐにバグに気づくと思いますが、これは期待通りに動作しません。irb上で実行すると、LocalJumpError: unexpected return のエラーがでて、すぐに return が悪いことに気づきますが、メソッド内に書くと、普通にメソッドが抜けるだけでエラーにはなりません。
ブロックの途中で値を返すには次のようにnextを使う必要があります。知っていたのにミスりました。
arr.sort do |a,b|
next 1 if !a[:x]
next -1 if !b[:x]
cmp = a[:x]<=>b[:x]
if cmp != 0
cmp
else
next 1 if !a[:y]
next -1 if !b[:y]
a[:y]<=>b[:y]
end
end
ちなみに上のコードで cmp != 0 を cmp とだけ書くのもありがちな落し穴ですが(Rubyは数値0を真偽値として評価すると真になります)、流石にこれはミスりませんでした。
ここまででふたつのバグです。
残りひとつは別の実験コードを書いていて作ったバグです。injectメソッドの動作確認のために、次のようなコードを書きました(このコード自体はたいした意味はありません。説明のためのコードです。このコードと同じことをするならmapを使う方が自然です)。
arr.inject([]){|arr,e| arr << e[:x].to_s}
実コードであれば、こんないい加減な変数名を使わないのですが、実験コードなので安易に配列はarr、要素はeと無意識に書いていました。
問題があると言われて見ればすぐに分かるかもしれませんが、上のコードは意図通りの動作をしません。正確に言えば、結果は意図通りですが、意図しない副作用が起こっています。ブロック内のスコープのつもりで使っているブロック変数arrが、外側のarrを破壊するのです。
もっとも、このバグはRuby1.9では仕様変更により起きなくなっているようです(未確認)。
僅か30分ほどの間に3つもバグを生みました。これもRubyの生産性の高さ故でしょうか。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/ruby-and-bugs/tbping
JavaScriptで恐いバグ
3年以上前に過去形で語っている話ですが、かつて自分の作ったバグを記録していたことがあります(http://dev.ariel-networks.com/blog/inoue.php?blogid=2&archive=2004-9-17)。
この時の結論は、バグの大半がAPIの仕様の理解不足から生じていた、でした。ここの「API」という用語は、非常に広義な意味で使っています。21世紀になって自分の作るバグの多くがマルチスレッド絡みになってきたという変化はありますが、APIの仕様の理解不足がバグの要因として大きい事実は変わっていません。
上記の記事では、次のようにも書いています。
当時、言語仕様の理解不足で生じるバグを作ることは無くなっていました。
ほとんどC言語オンリーで、かつ充分に経験を積んでいたので、言語仕様の理解不足で作るバグはありませんでした。
時代の要請か、多くのプログラミング言語を使う機会が増えました。ひとつひとつの言語に対する理解が浅いせいか、今の方が言語仕様の理解不足で作るバグが増えたようです。先日のRubyで作ったバグ(http://dev.ariel-networks.com/Members/inoue/ruby-and-bugs)も、この例です。
言語が高級になっていることも要因のひとつかもしれません。いくつかはコンパイル型言語でないことも影響しているかもしれません。長らく、コンパイラにバグを見つけさせる技術を磨いてきたので、コンパイラが無いと大きな武器を失った気分になるのです。
今日はJavaScriptでのバグの話です。実は自分の作ったバグではありませんが、恐いバグだと感じました。
バグには、恐いバグと恐くないバグがあります。バグを作っても、今後、同じようなバグを作らない対策を打てるバグはあまり恐くありません。ある種のコーディングで同じバグを防げることが分かるなら、バグの経験は良い経験です。一方、同じようなバグを作らない対策が、今後気をつける、しか無いバグは恐いです。注意していても忘れるからです。うっかりコードを書いてもバグを防ぎたいのです。ミスはコンパイル時に検出できればベストです。最悪でも実行時にそれと分かりたいのです。このために、いわゆる防衛的なコーディングとして知られる技術があります。
JavaScriptの恐いバグの話に戻ります。
prototype.jsのバージョン1.5.xを使っていたコードでした。そのコードはElement(prototype.jsが定義したクラス)のオブジェクトに独自に select というプロパティを加えていました。用途はフラグ変数でした。
prototype.jsのバージョンをv1.6.0.2に上げた時、問題が発生しました。prototype.js側で、Elementクラスにselectというメソッドが追加されていたためです。フラグ変数を期待していた参照箇所がすべて真になりました。
些細な話と思うのは簡単ですが、ぼくはこの話を聞いて恐いと思いました。外部ライブラリの更新で壊れるコードは、JavaScriptに限りませんが、このケースの場合、決してエラーは起きませんし、防衛するためにどう書けばよいのか分からないからです。
selectはフラグとして名称がおかしいので、selectedにすべきだった、という指摘はもっともですが、プログラマはそんなに予知的ではありません。第一、この指摘は本質的ではありません。selectedというプロパティがprototype.js側で追加されれば同じことだからです。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/terror-bugs/tbping
js2-mode
浜辺さんからjs2-modeを教えてもらいました。
JavaScript用メジャーモードです。Rhinoから移植したJavaScriptパーサを実装しているようです。従来の各種プログラミング言語用のメジャーモードは、たいていパターンマッチングで構文を推測していました。完全にプログラム全体を構文解析するjs2-modeには驚きました。
上記blogから引用
This is part of a larger project, in progress, to permit writing Emacs extensions in JavaScript instead of Emacs-Lisp.
またひとつ、人にJavaScriptを薦める理由ができそうです。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/js2-mode/tbping
ソフトウェアテストの適性
某所から、ソフトウェア開発の未経験者に対して、ソフトウェアテストの適性を見る課題が無いかと聞かれたので次の課題を考えました。
- OpenOfficeをインストール(http://ja.openoffice.org/)
- ワードもしくはエクセル(慣れている方)で作ったファイルをOpenOfficeで開く
- OpenOfficeで作ったファイルをワードもしくはエクセルで開く
上記の作業で、不具合(バグ)を見つけて記録してください。 記録は次のように行ってください。
手順(*): 1. ワードで新規文書を作成 2. 文書内の日本語テキストを下線付きに変更 3. 文書を保存 4. OpenOfficeで該当文書を開く 期待値: 該当テキストの下線が正しく表示できる 結果: 該当テキストの下線が無くなる 備考: 英語テキストでは問題がありません
- ソフトウェアテスト未経験者でも、説明無しに使い方が分かるだろう
- ソフトウェアテスト未経験者でも、不具合を見つけられる可能性が高いだろう
という、やや失礼な理由でOpenOfficeを選びました。
バグを多く見つけられる人も貴重ですが、作業が苦にならないことはもっと重要なことだと思います。
最近のOpenOffice安定版の品質を把握していませんが、1時間で2つ以上のバグ報告を書ければ、結構な才能かもしれません。 興味があれば、アリエル採用ページをご覧ください。 http://www.ariel-networks.com/company/recruit.html
(*)例を示すためのバグ報告で、OpenOfficeにこのようなバグはありません。念のため。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/qe-recruit/tbping
ブロックを呼び出す回数が少ないから効率的です。
記事のためにデータ構造を単純化しましたが、実際のコードはソートキーが整数ではなく、Time型でした。可読性とのバランスで、配列を使うsort_byで書き換えました。コードが短くなりました。
ありがとうございました。