Displaying posts written in

2月 2009

ノンデザイナーズ・デザインブック

自分でデザインした文書やWebページや壁紙から漂ってくる、あの如何ともしがたい素人臭はこれが原因だったのか!

タイトル通り、非デザイナー向けのデザイン本。本屋で立ち読みして衝動買い。「Third Edition」「新装増補版」とあるのを見ると、その筋では結構有名な本だったりするんだろうか。基本的に英語圏の本なのだが、大部分はそのまま日本語でも通用するはず。本文中に載っている”悪い見本”が、これまで自分が作ってきたダサダサなデザインとあまりにも似過ぎていて、「これ!まさにこれ!」と思わず叫び出してしまうほど。

個人的に特に参考になった内容をまとめておく:

  • 関連のある要素は近付け、関連のない要素は離す。空白を恐れてはいけない
  • 全ての要素をきちんと整列させる
  • 文字の中央揃えは使ってはいけない
  • コントラストは大胆につける
  • 似て非なる要素は衝突を起こす。全く同じか、はっきり違うか、どちらかにする
  • 活字にはカテゴリーがあり、組み合わせ方にルールがある

あと、非英語圏の人間にはあまり参考にはならないのだが、「文字を全部大文字にしてはいけない」としきりに強調しているのも印象的だった。あれはやっぱり読み難いよなあ。ネイティブはそうは思わないんだろうかと前々から疑問だった。

Zend Framework 徹底入門

PHP用のMVCフレームワークを選定している。

『Zend Framework徹底入門』は、この手のフレームワーク本としてはちょっと珍しいくらいに内容が充実していて、2chのZFスレでも非常に評価が高い(あまりにも絶賛意見が多いので当初は「宣伝乙」とか思ってました…ごめんなさい)。もともとZFは公式ドキュメントが充実しているので、この本と合わせればそれでもう十分な情報量になる。

しかしいくら情報量が多くても、フレームワーク自体が使いにくければどうしようもない。そして私にとってZFは、使いやすいとは言い難い。一人のプログラマとして設計やコードを眺めるととても美しいと感じるのだが、いざ一人のユーザとして使ってみると、あらゆる種類の不親切さにうんざりしてしまう。

”Rails以前”のフレームワークを現代風に洗練した感じ、とでも言おうか。Railsは「皆さんはもっとラクをして良いんですよ」というメッセージを堂々と打ち出してきたことが衝撃的だった。ZFにはそういう意識は感じられない。優れた設計・コードはあっても、使いやすくするための工夫は少ない。

ZFの上にもう一枚、自分用フレームワークの層を構築するべきか。それとも他のフレームワークをあたるのが早いか。

Erlangの正規表現について調べる(2)

先日コメント欄で教えていただいたErlangの新しい正規表現モジュール re。使える正規表現の種類やマッチの特性・性能は PCRE に準ずるので、現代的な諸プログラミング言語と比較しても遜色ないレベルの機能を備えている。正規表現なしの文字列処理なんて考えられない!という人もこれで安心。

さらに、古い regexp モジュールと比較して、マッチ対象や正規表現自体を iodata() で構成することができるという点は注目に値する。

erl> re:run([<<"Ama">>, $m, "i ", [<<"Haru">>, "ka"]], ["^", "A.+a", "$"]).
{match,[{0,12}]}

マッチや置換の結果を取得する方法も柔軟に選択できるので、「一連のバイナリから特定のパターンを抜き出してリスト(文字列)として取得する」なんてことも簡単にできる。例えば『プログラミングErlang』193ページの scavenge_urls:gather_urls は次のように書き換えられる。

gather_urls(Bin) ->
    case re:run(Bin, "<a href.+?</a>", [global, dotall, {capture, first, list}]) of
	{match, L} -> L;
	_ -> []
    end.

id3_v1:trim も次の通り簡潔に。

trim(Bin) ->
    re:replace(Bin, "[ \\0]+$", "", [{return, binary}]).


ちなみに re モジュールはEEP(Erlang Enhancement Proposal) 11として提案され、R12B-3において実験的なモジュールとして取り込まれたようだ。Erlangは今なお活発に開発が続けられているんだなあ…。『プログラミングErlang』はR11B-5を基準に書かれているから、たまには最新情報をチェックしていかなくては。

新約聖書 訳と註 3 パウロ書簡 その一

田川建三訳著『新約聖書 訳と註 3 パウロ書簡 その一』。夕食後に少しずつ読み進め、1ヶ月ほどかけて読了。

この翻訳が読める時代・言語圏に生まれて幸運だったと思える。同著者の『書物としての新約聖書』を読んでいると心底そう思う。訳文からも膨大な訳注からも、著者の学問的誠実さがひしひしと伝わってきて、読んでいて清々しく感じる。一方、他翻訳(主に口語訳と新共同訳)の誤りを指摘する際にはかなり頻繁に露骨な嫌味が添えられているので、読んでいて何だか荒んだ気分になってくる……。

この第3巻にはパウロの真筆書簡が収められている。日本では宗教・信仰と言うと『信じるものは救われる』的な考え方が一般的だと思うのだが、パウロ本来の考え方はその真逆と言っていいもので、有り体に言えばもっとずっと「深い」。パウロの書簡の中にはそういう思想的に深いところと、その思想ゆえの自己矛盾と驕りとが隣り合わせになっている。

そういったことは、その筋の人にとっては良く知られた事実なのだろうけれども、一般人が漠然と聖書の本文を読んでいるだけではやはり分からない。翻訳の質がどうという以前に、一言一節の意図を考える一つのきっかけとして、註の存在はとてもありがたい。

Erlangの正規表現について調べる

みんな大好き正規表現が13章で初登場。Erlangのregexpモジュールについて調べてみた。

(追記:コメント欄にて、PCREベースの新しい正規表現モジュール re の存在を教えてもらいました。こちらも後で調べてみます)

実装・性能

regexpモジュールはErlnagで実装されている。code:which(regexp) でソースファイルを探してコメントを読んでみると、NFAに変換せずに独自の内部表現とパターンマッチで実装されているらしい(その方がずっと速いから、とのこと)。内部表現は regexp:parse を使って確認することができる。

erlang> regexp:parse("xxx|yyy").
{ok,{'or',{concat,{concat,120,120},120},
          {concat,{concat,121,121},121}}}

この実装を読み解いてみるのも面白いかも知れない。

ただし独自実装の宿命として、機能は貧弱だし遅い。本家ドキュメントのEfficiency Guide 3.1にも Don’t use the regexp module in time-critical code. と書いてある。

マッチの性質

正規表現によるマッチを行う関数として、match と first_match という2種類の関数が用意されている。

  • first_match は最も左でマッチした結果を返す(最左マッチ)
  • match は文字列中の全ての位置でマッチを行い、最も長くマッチした結果を返す
erlang> regexp:first_match("xx xxxx xxxxxx", "x+").
{match,1,2}
erlang> regexp:match("xx xxxx xxxxxx", "x+").
{match,9,6}

first_match の方が速いので、単にマッチするかどうか調べるだけなら first_match を使った方が良い。

またどちらの関数も、その位置でマッチする最長のものを見つけようとする(最長マッチ)。

erlang> regexp:first_match("xxxxyyyy", "x+(yy)?(yyyy)?").
{match,1,8}

よって first_match は、いわゆるPOSIX NFAと同じ最長最左マッチを行うことになる。これは perl や ruby など従来型NFAとは異なる動作である。

irb> $& if /x+(yy)?(yyyy)?/ =~ "xxxxyyyy"
=> "xxxxyy"

lib_find:files/5 の改善

『13.8 findユーティリティ』に出てくる lib_find:files/5 がイマイチだと感じたので、自分なりに修正してみた。以下の点を変更している。

  • regexp:match/2 の代わりに regexp:first_match/2 を使うようにした
  • accumulator の処理を lists:foldl/3 に委託した
  • マッチ対象を「ファイルの完全パス」から「ファイル名」に変更した

(続きを読む…)

仕事の忙しさと精神的健康

仕事が忙しい。自宅勤務ということもあって、自主的に休日返上状態で働いている。

「平日だから」「休日だから」とか、あまり考え過ぎない方が良い。その区別にこだわり過ぎると、逆に生活が仕事に支配されて、精神的健康を害してしまう。仕事なんてしょせん自分の人生の一部分に過ぎない。休日だろうが平日だろうが、すべきと思うことがあるならやれば良いし、無いならやらなくて良い。

ただし、「すべき」と思って実際に行動できるなら良いが、心の中で心配することしかできない状況なら、一切何もしない方がマシだ。『明日のことは明日自らが思い悩む。その日の苦労は、その日だけで十分である。』(マタイ福音書6.34)

『9.8 キープアライブプロセス』徹底理解(2)

先日の続き。

実は書いているうちに新たな疑問が浮かんできて、再度考え直していた。その結果、先日の内容には少し嘘が含まれていたことにも気付いた(詳細は「問題点4」の中で)。やっぱり「徹底検証」だとか格好つけるもんじゃないね!

(続きを読む…)

『9.8 キープアライブプロセス』徹底検証

『プログラミングErlang』138ページ。この1ページを理解するのに丸一日以上要したのは、単に私の頭が鈍いから、というだけではない!と思ったので、これから2回に分けて徹底的に検証していくことにする。

問題となる部分の引用:

on_exitとkeep_aliveにはちょっとした間違いがあるのに気付いただろうか?次のようなコードを書くと:

Pid = register(…),
on_exit(Pid, fun(X) -> ..),

この2つの文の間でプロセスが死んでしまう可能性がある。on_exitが評価される前にプロセスが死ぬとリンクは作られないので、on_exitプロセスは期待どおりの仕事をしてくれなくなる。そのような状況は2つのプロセスがNameに同じ値を指定して同時にkeep_aliveを評価しようとすると発生する。この状況は競合状態と呼ばれる。2つのコード(上記のコードと、on_exitの中でリンク操作を実行する部分)がお互いにリンク操作を取りあってしまう状態だ。ここで問題が起きると、プログラムは期待通りには動かないだろう。

(続きを読む…)