2009-12-29

キリンヤガ ([著]マイク・レズニック, [訳]内田昌之, ハヤカワ文庫SF1272)

キリンヤガ (ハヤカワ文庫SF)
マイク レズニック
早川書房 ( 1999-05 )
ISBN: 9784150112721
おすすめ度:アマゾンおすすめ度

(帯より)
SF史上最多数の栄誉を受け、21世紀の古典の座を約束された、感動のオムニバス長編

少し古い(10年と少し前)作品だけど、久しぶりに大量に読んだ勢いにまかせて、これも一気読み。以下に各短編のタイトルを示す。プロローグとエピローグをあわせて 10 作品。

  • プロローグ: もうしぶんのない朝を、ジャッカルとともに
  • 1. キリンヤガ
  • 2. 空にふれた少女
  • 3. ブワナ
  • 4. マナモウキ
  • 5. ドライ・リバーの歌
  • 6. ロートスと槍
  • 7. ささやかな知識
  • 8. 古き神々の死すとき
  • エピローグ: ノドの地

雑感

買ってから10年以上放置しておいたものの言うことではないけれど、SF が好きで、かつまだ読んでいないなら、いますぐ買いに走った方が良い。さいわい Amazon でも在庫はある。10年前の出版物としては入手しやすいようだ。

ざっくり言えば、楽園を作ろうとした老人の挫折の物語。老人が求めた楽園とは何か。なぜ失敗するのか。そもそもこれは楽園だったのか。読み手にそういうことを考えさせる作品集。

作者自身がいちばんのお気に入りだと言う(作者あとがきより)「空にふれた少女」は、ティプトリーの「たったひとつの冴えたやりかた」と並べておきたくなる作品。こう書けば、「たった…」を知っているなら物語の筋がおおよそ見当がつくだろう。訳者が言う、だまされたと思って読んでみて欲しい、と。その価値は確かにある。ただ、単独で読むよりも「ささやかな知識」とあわせて、一対の物語として読んだ方が良い。

「空に…」も「ささやかな…」も良いけれど、わたし自身のベストを挙げるなら「マナモウキ」。楽園の崩壊を予兆させる内容なのに、コミカルな印象を持つ作品。神の代弁者として絶大な力を持つ賢者が、中年の主婦のわがままに振り回される姿は喜劇そのもの。作品集全体を通して重いトーンが続く中で、唯一笑みを浮かべられる部分だ。もっとも、物語自体はやはり重い。楽園が崩壊する理由をもっともストレートに表している作品だ。

エピローグとなる「ノドの地」はイマイチ。とくにクローニングにより復活させられたゾウは余計なガジェットだとしか思えない。

知識は呪

主人公、コリバを中心とした長老たちは、自分たちの民族にとっての楽園を建設するために厳しい規制を設ける。伝統という名で呼ぶそれに反する一切を拒絶する。伝統によってのみ楽園を成立させ維持することができると信じて。伝統により、(西欧的な観点からすれば)貧しく苦しい暮らしを保つ。伝統を守るため、けがや病気を癒す科学技術にも背を向ける。伝統の名の下に、生まれたばかりの健康な子どもを間引く。

伝統を保持するために鍵となるのが、楽園の住人たちを無垢な状態に保つこと。そして、無垢すなわち無知でもある。けがの痛みをやわらげ、病気を癒す薬の存在を知らなければ、苦痛に耐えるしかない。うまい食べ物を知らなければ、粗食にも耐えられる。きれいでやらわかな衣服に身を包んだことがなければ、着飾ろうと思うこともない。

コリバたち長老は、知識を限定することが善であり、住人たちを幸福にすると決めつけた。無制限の知識は、楽園を外の世界に同一化させてしまう呪いであると考えた。そして自らも限定的な知識による制約に縛られることを受け入れた。得るために、失うことを良しとした。すべては楽園を実現させるため。

しかし、選択権を与えられなかったものが現れる。楽園で生まれ、育った子どもたちだ。彼らは大人たちが幸福と引き換えにあきらめたものを知らなかった。それが、注意深く設計された楽園を変質させてしまうものだとは思いもよらなかった。だからこそ、知識のかけらを見つけたとき、そのまぶしさに魅了された。

(空にふれた少女; p.97)
「あなたはただの人間よ」カマリは疲れきった声でいった。「もう最悪の呪いをかけてしまったわ」

コリバの持つ知識の一端に触れた少女は、女であるという理由で、知識の伝授を拒絶され、考えることをも禁じられる。彼女は自ら死を選ぶ。他に生きる道があるとは思えなくなっていたから。暗闇の中で光を見つけたものは、ふたたびそれを失うことに耐えられない。

一方、コリバの後継者として育てられた少年は、与えられた知識によってコリバの行動が、楽園の伝統が欺瞞であると反発する。

(ささやかな知識; p.359)
それよりも、いったん知識を得たら、それが自由にあたえられたものであろうとなかろうと、心をもとにもどすことはできないんだと教えるほうがずっとわかりやすい。 (……中略……) おまけに、ぼくは自分の得た知識を返したくない。もっと多くのことを学んで、すでに知ったことは忘れないようにしたい。

彼は(コリバたちのつくった)楽園ではなく、外の世界を選ぶ。

知識は呪いだ。外から見れば、知らないことは不幸に見える。けれど知らない当人にとっては、知らないのだからそもそも比較のしようがない。嘘だと思うんならチャーリーに聞いてみると良い。

楽園という名の箱庭

主人公、コリバは楽園をつくろうとした。彼と彼の民族がもっとも幸せだった時代の暮らしを再現しようとした。西欧文明が持たらした豊かな生活と引き換えに失なったものを取り戻そうとした。高等教育を受け、西欧文明を形作るものを理解した上で、そのすべてに背を向けた。

コリバが目指したものが彼にとっての楽園であったことは間違いない。彼は楽園を手に入れ、その保全に力を尽くす。楽園を楽園たらしめている伝統を、その住人に強制することで。

けれど、この小世界は本当に楽園なのだろうか? 生まれたばかりの子どもを逆子だったからというだけで殺す世界は誰にとっての楽園なのか(「キリンヤガ」)。健康で、自らの仕事を十分に心得ていて働き続ける意思のあるものが、ただ年老いたというだけで隠居して無為に暮らさなければならない世界を楽園と呼べるのか(「ドライ・リバーの歌」)。

ここで描かれる世界は読み手の共感を呼ぶことはない。この世界はコリバという男の、(西欧)文明世界に疲れた老人の恣意的な箱庭にすぎない。だから、彼は外からの侵入者を(歓迎するふりをしながら)排斥する。住人からの(変化に対する)反発を武器にして。

(マナモウキ; p.222)
生まれてからずっとこういうところを夢見てきたの。せっかく実現したんだから、絶対にここを離れるつもりはないわ。そのためならなんでもするつもりよ

この世界を楽園と信じた侵入者は、世界と融和するために次から次へと譲歩を求められる。あれをするな、これをしろ、その考えは間違っている、と。侵入者は犠牲をはらうことに疲れ、楽園だったはずの世界を去る。

しかし、楽園にも終わりが来る。いや、この小さな世界は終わらない。終わるのはコリバのつくった箱庭としてのキリンヤガだ。住人たちがコリバと、彼の押し付ける伝統に疑問を持つようになるとき、楽園は終わり外の世界の一部にもどる。

神になろうとした老人

コリバが語る寓話の中で、彼の民族が信じる神が登場する。神の語る言葉が伝統であり、楽園としてのキリンヤガを形作る制約だ。しかし、それはコリバの言葉でもある。むしろ、彼の言葉でしかない。コリバは神を演じていたのだ。他の誰の言葉にも耳を貸さないわがままな神を。

しかし、コリバの民はその言葉に疑問を持つ。彼が演じる神(とその罰)よりも、外界から入ってくる文明のかけらを求める。もはやキリンヤガに神は必要ない。

エピローグとしての「ノドの地」では、ケニアに戻ったコリバの姿が描かれる。皮肉なことに、そこでのコリバの振る舞いは、彼が民族の伝統として定めた規則からまったく外れたもの。伝統は老いては子にしたがえと求める。キリンヤガでは、それに反する老人に厳しい罰を与える。その彼自身がケニアでは息子の諫めに耳を貸さない。そこにいるのは、ただ頑固なだけの老人だ。求めることだけ多く、求められることに応えようとしない愚か者だ。神になろうとして失敗し、失敗したことの意味を理解しようとしない男だ。

関連作品

「空にふれた少女」とあわせて読みたい、ってところかな(↓)。

たったひとつの冴えたやりかた (ハヤカワ文庫)
ジェイムズ,ジュニア ティプトリー, 浅倉 久志, ジェイムズ・ティプトリー・ジュニア
早川書房 ( 1987-10 )
ISBN: 9784150107390
おすすめ度:アマゾンおすすめ度

2009-12-15

紅の勇者オナー・ハリントン シリーズ ([著]デイヴィッド・ウェーバー, [訳]矢口悟, ハヤカワ文庫SF)

ほぼ丸二日、のべ三日をかけて一気読み。まずは表紙を並べてみよう。

新艦長着任!〈上〉―紅の勇者オナー・ハリントン(1) 新艦長着任!〈下〉―紅の勇者オナー・ハリントン(1) グレイソン攻防戦〈上〉―紅の勇者オナー・ハリントン(2) グレイソン攻防戦〈下〉―紅の勇者オナー・ハリントン(2) 巡洋戦艦“ナイキ”出撃!(上)―紅の勇者オナー・ハリントン〈3〉 巡洋戦艦“ナイキ”出撃!(下)―紅の勇者オナー・ハリントン〈3〉 復讐の女艦長〈上〉―紅の勇者オナー・ハリントン〈4〉 復讐の女艦長〈下〉―紅の勇者オナー・ハリントン〈4〉 航宙軍提督ハリントン〈上〉―紅の勇者オナー・ハリントン〈5〉 航宙軍提督ハリントン〈下〉―紅の勇者オナー・ハリントン〈5〉 サイレジア偽装作戦〈上〉―紅の勇者オナー・ハリントン〈6〉 サイレジア偽装作戦〈下〉―紅の勇者オナー・ハリントン〈6〉 囚われの女提督〈上〉―紅の勇者オナー・ハリントン〈7〉 囚われの女提督〈下〉―紅の勇者オナー・ハリントン〈7〉 女提督の凱旋 上 (ハヤカワ文庫 SF ウ 16-16 紅の勇者オナー・ハリントン 8) 女提督の凱旋 下 (ハヤカワ文庫 SF ウ 16-17 紅の勇者オナー・ハリントン 8)

さすがに 16 冊ともなると壮観だ。

2009-12-12

twitter より (2009-12-11)

  • ノートパソコンについている「トラックパッド」(で良いのかな?)。マウスの代替としてはなかなかの発明だ(トラックボールからの発展なのかなあ)。けど、iPhone 以降、タッチタイプの液晶画面が(とくに携帯機器において)隆興しているのを見ると思う。(以下、つぎのつぶやきへ) posted at 10:32:22
  • どうして、ノート方でも触れる液晶が主流にならなかったんだろうか、と。 posted at 10:33:28
  • GUI の基本、ユーザに対象物を直接操作している感覚を与える、という方針にのっとれば、画面に直接触れる方が正しい進化であったはず。 posted at 10:35:48
  • すでにマウスによる入力が確立されていたデスクトップと違い、ノートタイプにはマウスとは異なる「何か」が求められていたはず。どうして、トラックパッドのような「いびつなモノ」を作っちゃったんだろう。 posted at 10:38:03
  • コストかなあ。コストのような気がするなあ。 posted at 10:38:29
  • ノート型が一般的になり始めた十数年前には、技術的に難しい点があったのかもな。 posted at 10:41:50
  • Apple がやってくれないかな。次の MacBook あたりで。 posted at 10:42:59

2009-12-11

Cocoa アプリ の構造 #1: Nib の周辺

Cocoa アプリでは、アプリが利用するさまざまなリソースを Nib ファイルに保持している。この中には、アイコン等の画像データに加えて、メニューやウィンドウといったユーザインターフェースの記述もふくまれている。アプリによっては、複数の Nib ファイルを持つものもあり、当然、どの Nib をどういうタイミングでロードするのかを制御する仕組みが存在する。この仕組みが気になり少し調べてみたので、わかった範囲で記録しておく。

アプリと Nib の関係

Cocoa アプリのスタートポイントは NSApplicationMain 関数で、その処理は主に次の 3 つ。

  1. NSApplication のオブジェクトを作ること (グローバル変数 NSApp にセットされる)
  2. アプリの主要 Nib ファイルをロードすること
  3. NSApprun メッセージを送ること

今回、ふと気になって調べたのがこの 2 番目。Nib ファイルのロードについて。具体的には、どの Nib ファイルが、いつロードされるのか、また、そのトリガーは何なのか、など。ちなみに Xcode/Interface Builder 3.0 以降は、デフォルトでバイナリ形式の Nib に代わって XML 形式の「Xib ファイル」が使われる。SCM ツール等との相性の良いテキスト形式のフォーマットを作ったとのこと。ビルドの際に Nib へと変換される。([4]を参照)

まずは、アプリに対して 1 つ存在する「主要 Nib ファイル」というものについて。これはどこで指定しているんだろうか? Xcode で Cocoa アプリ用のプロジェクトテンプレートを指定すると、MainMenu.xib が作られ、これが主要 Nib になる。まさか、ファイル名がハードコードされているはずもないから、どこかに名前の指定があるはず。

主要Nibファイルの設定

[2] の "Changing the Nib Files from the Xcode Defaults" の記述でそれが判明した。Xcode からプロジェクトのターゲットからアプリケーションを選び、「ファイル」>「情報を見る」。「情報」パネルの「プロパティ」タブを開くと、中段に「主要クラス」と「主要Nibファイル」の設定がある (右図)。

ちなみに、これら「プロパティ」の設定は、Info.plist としてアプリにくっついて行く。

MyDocument と Nib の関係

Xcode で document-based アプリ用プロジェクトを作る

Cocoa アプリのプロジェクトを作る際に "document-based application" を指定すると、Document-Based アプリ([3]を参照)を作ることができる。このとき、Xcode が自動生成する Nib ファイルは MainMenu.xibMyDocument.xib の 2 つ。前者は上述のようにアプリの「主要 Nib ファイル」だ。後者はファイルを作成、編集する際に表示するユーザインターフェースを記述するためのもの。では、MyDocument.xib はいつ(何をきっかけとして)、誰が(どのオブジェクトが) ロードするのか? その答えも [3] に書かれていた。以下は、プロジェクトテンプレートが想定する、もっともシンプルな場合の動きだ。

Document-Based アプリでは、NSDocumentController というオブジェクトが存在し、ドキュメントの作成やオープンを担当している。メインメニューからファイルの新規作成やオープンが選択されると、NSDocumentController に指示が届く。で、このオブジェクトは生成する(開く)ドキュメントのタイプに応じて、適切なクラス(NSDocumentのサブクラス; デフォルトでは MyDocument)のオブジェクトを生成する。このオブジェクトとドキュメント編集のための Nib ファイル(MyDocument.xib) との結び付きは、MyDocumentwindowNibName メソッドが返す文字列によって作られる。デフォルトではこれが "MyDocument" となっている。

さて、では NSDocumentController はドキュメントのタイプと MyDocument クラスをどこで結び付けているのだろうか? それも、Info.plist だ。その中で、ドキュメントタイプごとに拡張子やアイコン等と一緒にクラスも指定する。

関連リンク

ちなみに以下のリンクはすべて Mac Dev Center の文書なので、Xcode のドキュメントブラウザからも読める。

[1] Cocoa Fundamentals Guide: The Core Application Architecture on Mac OS X
後ろの方にある "Nib Files and Other Application Resources" が Nib 関連の記述。
[2] Resource Programming Guide: Nib Files
"Anatomy of a Nib File" では、Interface Builder でおなじみの「File's Owner」や「First Responder」の説明がある。
[3] Document-Based Applications Overview: Implementing a Document-Based Application
"The Document-Based Application Project Template" に、Xcode の Document ベースアプリのプロジェクトテンプレートの説明がある。
[4] Interface Builder User Guide: Nib File Management
Nib と Xib の違いについての説明がある。なぜ、Xib ファイルを使うようになったのか、等。

参考文献

ヒレガス本 p.157 に "The Document Architecture" に document-baseed アプリについての簡単な説明がある。ただ、Nib ファイルのことはほとんど何も書いていない。ここに書いていないから、本家のドキュメントを調べたのだ。

Cocoa Programming for Mac OS X
Aaron Hillegass
Addison-Wesley Professional ( 2008-05-15 )
ISBN: 9780321503619
おすすめ度:アマゾンおすすめ度

関連記事

2009-12-10

フリーランチの時代 ([著]小川一水, [版]ハヤカワ文庫JA930) #2

前回に続いて、残りの 2 作品、「千歳の坂も」と「アルワラの潮の音」を読んだ。

収録作品

  • フリーランチの時代
  • Live me Me.
  • Slowlife in Starship
  • 千歳の坂も
  • アルワラの潮の音

千歳の坂も

「千歳の坂も」は、「フリーランチの時代」、「Slowlife in Starship」に続く、もうひとつの豊穣の時代を描く。今度の「豊穣」は不老不死。

むかしから物語に少なからず描かれる不死者は、たいてい偶然に、それも不可避な形で、ほとんど重荷のようにその特性を背負わされる。 しかし、本作で描かれる不老不死は違う。 医療技術が発展した結果、いつの間にか実現してしまったもの。病気が根絶ないしは治療法が確立され、さらには老化遅延さらには防止が可能になった世界。人は、死なずにすむのであれば、誰もがそれを望むのだろうか。死が避け得ない何かでなくなったとき、生きること、生き続けることの意味は変わるのだろうか。そういうトーンで物語は始まる。

本作のおもしろさは、その問いかけだけで終わらなかったところだ。国民に対して不老不死を強制させる役人と、逃れようとする女性。ある意味、体制と個人の自由の対立の構図から始まった物語は、「豊穣」が歪める社会を駆け足で描き出す。いつしか、最初の問いかけは意味を失う。

十分、長編にふくらませることも可能な設定、構想を短編として提供する。千年をわずか数十ページで書き切る。SF 作家はなんとぜいたくなアイデアの使い方をすることか。そして、それを一息で読み切ってしまう SF 読みはさらにぜいたくだ。
(あろうことか、不満を漏らしたりもするからな)

アルワラの潮の音

「アルワラの潮の音」は、「時砂の王」と同じ世界の物語。それも「時砂」の方でナン・マドールの巨石文明における戦いとして言及されているエピソードだ。

(時砂の王; p.231)
南太平洋の島に浮かぶ、半水半陸のその美しい都市で、アレクサンドルと仲間たちが戦ったのは、そう昔のことではない。

「時砂」自体が、ラストはともかく、全体のトーンが重苦しいものだけに、そこで言及されるエピソードも明るいものであるはずもない。この短編を読んだだけでは、その雰囲気が後味の悪さを残すかもしれない。まだ「時砂」を読んでいなければ、これを機会に読んだ方が良い。

もともと「時砂」の物語の設定が、こういうエピソードを数多く挿入できる構成になっている。「勝利三六回、撤退三七〇回」という戦いの中には、まだまだ語られるに足る物語が埋もれているに違いない。シリーズ化しても良いと思うんだよ。それだけ魅力的な設定だ。

参考文献

関連記事

2009-12-09

twitter より (2009-12-08)

  • うお。昨日はなんとなくスルーしてたけど、Google 音声検索すげえ(in iPhone)。 posted at 09:50:22
  • なんか、未来だ、未来を感じるゾ、これ。 posted at 09:50:59
  • 使い方や設定に関しては、このページが詳しい → http://bit.ly/4B56Rf posted at 09:52:48
  • Google Goggles って、AR (augmented reality) の逆だな。→ http://bit.ly/65q4dj posted at 15:45:10
  • AR は実体世界をアッチに取り込むことで機能拡張する。Googole Goggles はアッチの端子を実体世界に伸ばす感じ。 posted at 15:46:29
  • 認識した情報をそのまま検索に投げるだけに使い切るっていうのが、とても Google らしい思い切りだねえ。テキストとして切り出しておいて、そこからユーザに明示的に検索させる(データの編集も可)とかやらないところが、さ。 posted at 15:54:15

2009-12-08

Mac のメニューで良く見る記号

メニュー項目のショートカットキーを表す記号の一覧を Xcode のドキュメントで見つけたので、抜粋してみる。[Option]、[Shift]、それに [Control] は修飾キーと呼ばれ、ショートカットキーの一部として良く見かけるもの。そのくせ、近頃の Apple のキーボードには記号による刻印がないため、どれがどれだかわからなかった。この表があればもう迷うことはない。

KeySymbolUnicode code point
Command (Apple)U+2318
Option (Opt/Alt)U+2325
Control (Ctrl)U+2303
ShiftU+21E7
Escape (Esc)U+238B
BackspaceU+232B
DeleteU+2326

ちなみに、アップルメニュー(メインメニューの左端)のリンゴマークは [Shift] + [Option] + [K] で入力できる。これがその記号「」。Unicode の U+F8FF に割りあてられている。これは私用領域(U+E000 - U+F8FF; Private Use Area)の一部で、いわゆる外字になる。よって、Mac 以外では表示できない(はず)。これが Windows では「窓マーク」になっていたらオモシロイんだけどね。
(GNU/Linux ならペンギン、BSD系ならデーモン……って、そんなフォントないか)

関連リンク

2009-12-07

文字列参照の変換 (つづき)

先日、テキストに混じった数値文字列参照(あ という形式のもの)を元の文字に変換することについて書いた。そのとき、一応動くものができたけどきちんと変換できているか不安だ、とも書いた。今回は、それを実際に確認することから始めて、文字の取り扱いについて、少し調べてみた。その結果を書き留めておく。全体の流れはこう(↓)なる。

  1. 変換が成功していることを確認する
  2. Unicode について少し調べた
  3. 各種プラットフォームでの文字の取り扱いの差

変換が成功していることを確認する

まずは変換が成功することをどう確認するかを考えた。文字コードやらその取り扱いについて調べると時間がかかりそうなので、もっと直接的に(かつ、愚直な方法で)やることにした。

  1. 元のテキストから数値文字参照を抽出する
  2. 抽出した数値文字参照の文字列を 1 行につき 1 つずつ書き出す
  3. sort して uniq する
  4. 変換プログラムにかける
  5. 結果を視認でチェックする

1 〜 4 までが直接的(かつスマート)な部分で、5 が愚直な方法。

1 と 2 は 1 つのごく短い Ruby プログラム。標準入力から読んで、標準出力に書き出すシンプルなフィルタになっている。前に書いた変換プログラムをちょこっと修正しただけ。10 行目でおかしなことをしているけどキニシナイ。

(pickp_numrefs.rb)
 1: #!/opt/local/bin/ruby1.9 -w
 2: # coding: utf-8
 3: 
 4: pattern = /&#[1-9][0-9]*;/
 5: 
 6: STDIN.each do |line|
 7:   while pattern === line
 8:     numref = Regexp.last_match[0]
 9:     STDOUT.puts numref
10:     line[numref] = "*"
11:   end
12: end

元のテキストを cat で、こいつに流し込んで、出てきたものを sort | uniq にパイプでつなぐ (上記のステップ 3 と 4)。

変換プログラムも前のものを流用。

(print_numrefs.rb)
 1: #!/opt/local/bin/ruby1.9 -w
 2: # coding: utf-8
 3: 
 4: def convert(ref)
 5:   num = ref[2...-1].to_i  # Numerical reference must be "〹"
 6:   fs = "%c".encode("UTF-8")
 7:   fs % num
 8: end
 9: 
10: STDIN.each do |numref|
11:   STDOUT.puts "#{numref.chomp} -> #{convert(numref)}"
12: end

最終出力はこんな感じ(↓)。「丑」なんて文字、入っているはずがない、と思って調べてみると「土用の丑」という言葉の一部だった。

[...snip...]
一 -> 一
万 -> 万
丈 -> 丈
三 -> 三
上 -> 上
下 -> 下
不 -> 不
与 -> 与
丑 -> 丑
[...snip...]

結局、1514 種類の数値参照が混じっていた。一文字、一文字、丹念にチェックしたわけではないが、少なくとも豆腐印になっている文字はなかった。

Unicode について少し調べた

Wikipedia (ja) を中心に Unicode やら ISO 10646 のことやら調べてみた。わかったのは、だいたいこんなところ(↓):

  • 現在の Unicode 規格は Version 5.2.0 で、2009-10-21 にリリースされた
  • 当初、16 ビットで世界の全ての文字を符号化(番号づけだね)しようとしたが、番号が不足したため、現在は 21 ビットで規定されている
  • もとの 16 ビット領域 (U+0000 〜 U+FFFF) は Unicode 2.0 以降では BMP と呼ぶ
  • BMP は ISO/IEC 10646 の UCS-2 (16ビット範囲) と同一(番号も同じ)
  • 一方、ISO/IEC 10646 の UCS-4 (31ビットの文字集合) とは別物
  • 日本語で使われる「かな」は U+3040 〜 U+30FF で定義されている
  • 普段使う漢字はほぼ U+4E00 〜 U+9FFF の範囲にある (CJK統合漢字)
  • 16 ビットの上位 9 ビットが 0 の U+0000 〜 U+007F は ASCII 互換

そしてふと思い出した。Matz の「コードの世界」に文字コードについて書いてあったことを。早速、読んでみた。うん、わかりやすい。読み物としてまとまっている方が理解しやすい。「文字コード」という用語があいまいに使われていることについての言及もあり、「文字集合」「文字コード」そして「符号化方式」の意味の違いが簡潔にまとめられている(→ p.181)。

ちなみに、Wikipedia の Unicode の項には Unicode 一覧へのリンクがある。これは Unicode 文字を 4096 文字ごとにコードポイントの順番に並べた表で、どのコードポイントがどういう文字なのかが一目でわかる。作った人に感謝。

各種プラットフォームでの文字の取り扱いの差

「コードの世界」でも言及されているが(p.196 〜 202)、プラットフォーム(プログラミング環境)によって文字の取り扱いに差がある。(わたしにとっての)主要なプラットフォームについて、文字の取り扱いに関する特徴をまとめてみる。

Ruby 1.9

「コードの世界」で言うところの、CSI (Character Set Independent) 方式。UTF-8 などの符号化方式を指定すれば Unicode 文字を扱える。先日の数値文字参照の変換が、単なる数値から文字への変換でできたのは、このおかげだ。つまり、UTF-8 を指定した文字列に対して、Unicode 文字の「文字コード」すなわち Unicode のコードポイントを与えてやれば、適切に UTF-8 に変換される。

もともと、わたしが変換しようとしたデータのオリジナルは自分で書いた文書だ。オリジナルの状態でどういう符号化方式で保持されていたにせよ(UTF-8 だったはず)、適切に数値文字参照に変換されていたならば、その数値は Unicode のコードポイント (正確には ISO 10646 のもの) であるはず。そこで間違いが入り込んでいない限り、先のプログラムで正しく変換できることになる。愚直な方法でやった確認に関して、理論的な裏付けが得られたわけだ。

Mac OS X (Objective-C/Cocoa)

Ruby とは異なり、Mac OS X の Objective-C の文字列は UTF-16 になっている。「コードの世界」で言う UCS (Universal Character Set) 方式だ。Java や Python と同じ方式ってこと。

(Mac Dev Center: String Programming Guide for Cocoa: Strings より)
A string object is implemented as an array of Unicode characters (in other words, a text string).

ここで言う「Unicode characters」は「文字集合」ではなくて「文字コード」のことになる。ちょっと調べた程度では、16 ビットを越えるコードポイントの文字をどう扱うのかまではわからなかった。NSString オブジェクトを lengthcharacterAtIndex: を経由して扱う限り、その領域も正しく扱えるのだろう。今は、あまり深入りしないでおこう。

Gauche

プログラミング Gauche」には、こう書かれている。

(5.2 マルチバイト文字の利用 より)
Gauche はマルチバイト文字をサポートしているので、プログラム中の文字列やコメント、変数名に日本語を使うことができます。
(・・・中略・・・)
ただし、ASCII 以外の文字を使う場合、文字コードに気をつける必要があります。
デフォルトでは、Gauche はビルド時に決定される内部エンコーディングでプログラムが書かれていると考えます。

あれ、これってどっち方式だろう(・ω・)?

Gauche の公式サイトには、作者自身による文字列の取り扱いに関するデザインメモが置かれている。こういうプログラマの意図がわかる情報は貴重だ。

せっかく mini に Gauche をインストールしたことでもあるし、先日の変換プログラムを Gauche で書いてみよう。今日じゃないけど。そのうち。Gauche はもともと、

(Gauche ユーザリファレンス: 1.1 Gauche の概要 より)
Gaucheは、プログラマやシステム管理者がこなす日常の雑事を効率よくSchemeで書けるようにすることを目的として設計されています。

ということだから、ああいうフィルタなんかも書きやすいはず。

関連リンク

参考文献

関連記事

2009-12-06

Gauche 0.9 をインストール

Mac mini (Snow Leopard Server) に Gauche の最新版を インストールしてみた。Ports が少し古いバージョン対応のものなので、Portfiles をちょいちょいと書き換えて、インチキ ports としてインストール。Gauche 用の Portfiles は /opt/local/var/macports/sources/rsync.macports.org/release/ports/lang/gauche にある。

Portfiles の変更点はこんな感じ(↓):

  1. Version を 0.9 に。
  2. checksums を再計算した値に。
  3. patchfiles は不要なので、行ごと削除

ちなみに、checksum の再計算は以下のように実行する (MacPorts Guide より)。md5 は md5 で、あとの 2 つは openssl に計算のタイプを指定して行う。

[mini:~] mnbi% md5 Gauche-0.9.tgz 
MD5 (Gauche-0.9.tgz) = 1ab7e09da8436950989efd55b5dc270a
[mini:~] mnbi% openssl sha1 Gauche-0.9.tgz 
SHA1(Gauche-0.9.tgz)= ebc18917c36201d6c3fda29dfdc52fce2d856a5f
[mini:~] mnbi% openssl rmd160 Gauche-0.9.tgz
RIPEMD160(Gauche-0.9.tgz)= 3e0dfc1d498849b0d647e13f49addd0a56cc56fe

configure のオプションはともかくとして、patch の適用の有無はさすがに不安なので、port とは関係なしに、configuremakemake test して確認した。そのときの configure がこれ (行を "\" で折り返してある)。

./configure --mandir=/opt/local/share/man \
            --infodir=/opt/local/share/info \
            --with-local=/opt/local \
            --enable-multibyte=utf-8 \
            --with-iconv=/opt/local \
            --with-slib=/opt/local/lib/slib \
            --enable-threads=pthreads \
            --enable-ipv6

オリジナルの Portfiles にあった設定そのままを手動で実行したことになる。 この設定で make の後、make test をした結果がこれ(↓)。全テスト合格。

Total: 10076 tests, 10076 passed,     0 failed,     0 aborted.

インチキ ports を使ったインストールの実行結果は以下のとおり。

[mini:~] mnbi% time sudo port install gauche
--->  Computing dependencies for gauche
[...snip...]
--->  Installing gauche @0.9_0
--->  Activating gauche @0.9_0
--->  Cleaning gauche
126.559u 33.476s 1:58.65 134.8% 0+0k 233+860io 0pf+0w
[mini:~] mnbi% rehash
[mini:~] mnbi% which gosh
/opt/local/bin/gosh
[mini:~] mnbi% gosh -V
Gauche scheme shell, version 0.9 [utf-8,pthreads], i386-apple-darwin10.2.0

Gauche 0.9 に付いてくる configure を見ると、Portfiles で指定されている gdbmlibiconvslib に加えて、zlib にも依存している。依存関係に追加すべきか迷ったが、Snow Leopard 標準の zlib も、ports のものもバージョンが同じようだったので、気にしないことにした。

関連リンク

  • MacPorts Guide (チェックサムの計算については、4.2 Creating a Portfile のステップ 13 を参照)

参考文献

プログラミングGauche
プロジェクト
オライリージャパン ( 2008-03-14 )
ISBN: 9784873113487
おすすめ度:アマゾンおすすめ度

関連記事

MacBook にも Ruby 1.9 をインストール

mini のときと同じく実行結果だけ。

[book:~] mnbi% time sudo port install ruby19
--->  Computing dependencies for ruby19
--->  Fetching ruby19
[...snip...]
--->  Installing ruby19 @1.9.1-p243_0
--->  Activating ruby19 @1.9.1-p243_0
--->  Cleaning ruby19
247.197u 51.410s 4:35.89 108.2% 0+0k 44+5904io 0pf+0w
[book:~] mnbi% rehash
[book:~] mnbi% which ruby1.9 
/opt/local/bin/ruby1.9
[book:~] mnbi% ruby1.9 -v
ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin10]

2009-12-05

Google Public DNS を早速、試してみた

購読している RSS フィードのひとつで、Google が DNS サービスを提供し始めたことを知った。とりあえず、試してみることにした。大まかな流れはこんな感じ(↓):

  1. AirMac ユーティリティによる Time Capsule の設定
  2. Snow Leopard Server: DNS の設定
  3. Snow Leopard (クライアント版) 側の設定
  4. 稼動確認
  5. ローカルの DNS を落としても、名前解決できるか

AirMac ユーティリティによる Time Capsule の設定

うちは Time Capsule をインターネットへのルータとして使っている。 部屋で使っている Mac たちは DNS の設定を DHCP 経由で、この Time Capsule に訊きにいく。 個別に設定することもできるが、今回は、この大元を変更してみることにした。

Time Capsule に限らず一般的なルータはとくに設定しなければ、DNS の設定を ISP の DHCP サーバから引っぱってくる。ISP から契約の際に送られてくる書類一式にも DNS サーバの IP アドレスは書かれているはずだが、それを手作業で設定したのは遠い昔の話だ。Time Capsule でこれを独自の設定に変更するには「AirMac ユーティリティ.app」を使う。

「AirMac ユーティリティ.app」を起動したら、ツールバーから「インターネット」を選び。さらにメインビューの「インターネット接続」タブを選ぶ。中段に「DNS サーバ」の IP アドレスを入力するフィールドが 2 つ用意されている。デフォルトだと、ここには ISP から取得した DNS サーバの IP アドレスが 2 つ表示されている(グレー表示になっている)。これを上書きすれば良い。

うちの LAN では Snow Leopard Server でもローカルな DNS を稼動させて、LAN 上の機器の名前解決を担当させている。2 つある DNS サーバのうち最初の方は、ローカルな Snow Leopard Server の IP アドレスを入力してある。今回の Google Public DNS の IP アドレス (8.8.8.8) は、もう一方の方に入力した。

入力後、右下の「アップデート」ボタンを押せば、Time Capsule が再起動する。

Snow Leopard Server: DNS の設定

mini で稼動させている DNS サーバはローカルな LAN 上の機器の名前(とアドレス)しか解決できない。他のリクエストは上位の(外部の) DNS サーバにリクエストを転送することで解決を図るようになっている。そのためには転送する相手のアドレスを設定する必要がある。

「サーバ管理.app」を起動し、サイドバーからサーバを選び、さらに「DNS」を選ぶ。メインビューのツールバーで「設定」を選ぶと「フォワーダ IP アドレス」のリストがある。これまで、ここには ISP 提供の DNS サーバのアドレスを 2 つ入力してあったが、それを消して、Google Public DNS の 2 つのアドレス (8.8.8.8 と 8.8.4.4) を追加した。右下の「保存」を押せば完了。

Snow Leopard 側の設定

DHCP で接続情報を取得するようになっていれば(これがデフォルト)、とくに設定する必要はない。あえてすることと言えば、「システム環境設定」を開いて DNS の設定を確認するぐらい。

mini が停止する可能性もあるから、クライアント版はローカル DNS だけにクエリーを飛ばすようにはしていない。Time Capsule の設定にしたがって、ローカル DNS と Gogole Public DNS の 2 つのアドレスが使われるようになっている (実は、3 つ目として ISP 提供の DNS のアドレスも飛んできていた; これは Time Capusle が気をきかせたのかな)。

ちなみに、Snow Leopard の場合、DNS の設定は /etc/resolv.conf にも書かれている。設定を確認するだけなら、こいつを cat するのがてっとり早いかも。ただし、このファイルは自動生成されるもののようで (/etc にあるのはシンボリックリンク、実体は /var/run/resolv.conf)、これを書き換える必要はない。というか、書き換えてはダメ。中にはこんな風なことが書かれているから。

(/etc/resonv.conf のコメント)
# Mac OS X Notice
#
# This file is not used by the host name and address resolution
# or the DNS query routing mechanisms used by most processes on
# this Mac OS X system.
#
# This file is automatically generated.

稼動確認

まあ、普通に web をうろついてみたけど、問題ない。 dig を叩いて、有名どころのアドレスを調べてみたり。

ローカルの DNS を落としても、名前解決できるか

これは稼動確認のオマケ。ローカル DNS が Google Public DNS にフォワードするように設定したのだから、通常 LAN 内での DNS リクエストは一旦、ローカル DNS に届く。ただし、mini が停止する可能性も考慮してクライアント (MacBook) では、第2候補に Google Public DNS を明示的に指定している。この設定が期待どおりに効果を発揮するなら、mini 上のローカル DNS を停止しても、MacBook は問題なく web ページを開いたりといった作業ができるはず。それを確認してみる。

手順は、mini で「サーバ管理.app」から DNS サービスを停止させ、MacBook で web を見るだけ。

やってみた。問題ない。

関連リンク

2009-12-04

twitter より (2009-12-03)

  • Google 日本語入力(β) か(→ http://bit.ly/821f3M。ケータイやiPhoneといった入力に制約の強い機器では良いと思う。 posted at 11:56:40
  • くそ、URL がおかしなことになった。正しくはこちら → http://bit.ly/6E05d0 posted at 11:57:26
  • けどねえ。予測変換っていうのはキー入力を減らすためには良いんだけど、それがそのまま入力スピードのアップにつながるかっていうと、疑問が残る。 posted at 11:58:46
  • たまに入力する人なら大いに助けになると思う。でも、毎日、それなりの分量を入力する人はかえって足手まといにならないか? > 予測変換 posted at 12:00:19
  • こう打ったら、こう変換される、っていうのを身体が覚えちゃうと思うんだ。ヒトの身体(っていうか脳だけど)の方でかかる最適化の邪魔をしちゃう気がするんだよ posted at 12:01:24
  • カナ漢のように「指にすいつく」ようにして使いたいモノって、あまり賢さを演出する必要はないと思う。むしろ、愚直であった方が良い。SKK でなければ書けない体になっているからかな。余計なことはしなくて良い。ただ変換してくれ。 posted at 12:04:17
  • 他の漢字圏の人たちって、どう思っているのかね (・ω・)? posted at 12:05:16
  • そうか〜、iMac には外部ディスプレイもつなげられるのか。30インチをつなげて同時の表示できる。ふーん、たしかに Mac Pro、かたなしだねえ。 posted at 12:51:34
  • ピカピカ液晶は嫌いなんだけどなあ。MacBook は買うと同時にノングレアのフィルムを買っておいて、すぐに貼った。 posted at 12:53:30
  • 27 とかじゃなく、30 インチで出してくれれば良かったんだよ。なら、たぶん飛びついていたよ。 posted at 12:55:01
  • ディスプレイという一番かさばる筐体に本体を一体化してしまうっていう発想は、確かに画期的だったよな。今じゃ珍しくなくなったけど。 posted at 12:57:34
  • CRT だった「おむすび」世代、その次が液晶になった「大福」、そして液晶と体型。筐体の進化で見ると 3 世代目なのか > iMac posted at 13:03:25

2バイトエンティティじゃなくて、文字参照の変換

「す」のような文字列を見たことがあるだろうか? これまで、なんとなく「2バイトエンティティ」と呼んでいたんだけど、正しくは「文字参照」、それも「数値文字参照」と言うようだ。今回、これが混じったテキストから「文字参照」だけを一致する文字に変換する必要に迫られた。ブラウザに表示させれば元の文字列に戻るから(「す」は「す」)、テキストが少量なら手作業で変換したと思う。が、ちょっとサイズが大きかったのだ(4MBほど)。仕方がないのでプログラムを書いて対応することにした。

仕様の確認

まずは、仕様を見てみようとW3C を訪れた。該当する部分をちょこっと抜粋する。

(W3C: HTML 4.01 Specification: 5.3 Character References より) Character references are a character encoding-independent mechanism for entering any character from the document character set.

「文字参照 (character references)」 は、「数値文字参照 (numeric character references)」と「文字実体参照 (character entity references)」に分かれる、ともある。この数値文字参照の数値の部分は ISO 10646 の文字番号だということ。

ISO 10646 は符号化文字集合の国際規格のひとつ。誤解を恐れず、ものすごくおおざっぱに言うと Unicode と同じもの。正確なことは Wikipedia を始めとする資料にあたること。(→ 関連リンクを参照せよ)

Ruby で変換

CGI.unescapeHTML を使うと一発のようだけど、こいつは「数値文字参照」以外も変換してしまう。やりたいことは「数値文字参照」だけを文字に変換すること。もう少し手間をかける必要がある。どうせなら CGI.unescapeHTML を使わずにやってみよう。

「〹」の "12345" の部分が文字番号なのだから、文字列中から「&#?????;」(?は数字) というパターンを取り出して頭2文字と尾1文字を削れば良い。パターンを取り出すときは、正規表現を使えばコードは簡潔になるはず。

問題は ISO 10646 の文字番号から文字(列)を生成することだが、Ruby 1.9 ではこれが拍子抜けするほど簡単にできる。書式変換関数(C の printf/sprintf に相当)を使うだけだ。

プログラム全体はフィルタにする。標準入力から読んで加工して標準出力に書き出す。それを入力が終わるまでループする。こうなる(↓):

(convert_entity.rb)
 1: pattern = /&#[1-9][0-9]*;/
 2: 
 3: def convert(entity)
 4:   num = entity[2...-1].to_i     # entity must be "〹"
 5:   fs = "%c".encode("UTF-8")
 6:   fs % num
 7: end
 8: 
 9: STDIN.each { |line|
10:   while pattern === line
11:     entity = Regexp.last_match[0]
12:     line[entity] = convert(entity)
13:   end
14:   STDOUT.puts line
15: }

5 行目で、書式変換のテンプレート (fs) に対して encode("UTF-8") を呼び出しているのは、この文字列のエンコードを UTF-8 にするため。これがないと fs は US-ASCII になってしまい、書式変換関数の呼び出して例外が出てしまう。この他にソースファイルの先頭に「# coding: utf-8」という行を追加する方法もある。

肝になるのは前述の書式変換関数による文字番号から文字(列)への変換(convertメソッド)、および 12 行目の元の行に対する置換。正規表現とマッチした文字列をそのまま部分文字列置換の引数としている。

Ruby では Apple orange Grape という文字列(これを s とする)に対して、s["orange"] = "Peach" を実行すれば s = "Apple Peach Grape" となる。

この、「パターンマッチ」→「マッチした部分を対応する文字(列)」で置き換え → マッチに戻る、というサイクルを繰返すことで元の文字列中の数値文字参照が順次、置き換わっていく。長い行に文字参照がいくつもある場合は効率が悪いんだけど、その分、記述がすっきりしたものになった。

実行結果はこんな風(↓)。例によって長い行は "\" のところで折り返してある。

[mini:~] mnbi% cat .data.txt 
<p>&#12377;&#12409;&#12390;&#12398;&#22987;&#12414;&#12426; \
&#12539;&#12539;&#12539;&#12363;&#12394;(&#12539;&#969;&#12539;) \
&#65311;</p>
[mini:~] mnbi% cat data.txt | ruby1.9 convert_entity.rb
<p>すべての始まり・・・かな(・ω・)?</p>

ちなみに、上記のコードは Ruby 1.9 専用。これは String.encode を使っているからだが、そもそも文字列の扱いが 1.8 までと 1.9 とでは異なため、肝心の 6 行目が動かない。1.8 でやるなら CGI.unescapeHTML を使うことになる。また、インタープリタに -Ku を渡さないとダメ。

さて、これで一応、期待どおりに動くプログラムができた。あと気になるのは文字番号から文字(列)への変換の部分。これですべての文字を変換できるのだろうか? それとも、ある領域の番号は変換に失敗したりするのだろうか? この問いに答えるには、ISO 10646 や Unicode、そして UTF-8 のことをもっと調査する必要がある。それは別の機会に回そう。今日のところは(だいたい)動いていることで良しとする。

PHP で書くと・・・

ちょっと、たどたどしいんだが、Ruby で書く前に PHP でもちゃちゃっと書いてみた。それがこれ(↓):

(convert_entity.php)
 1: <?php
 2: $pattern = '/&#[1-9][0-9]*;/';
 3: 
 4: while (!feof(STDIN)) {
 5:   $raw = fgets(STDIN);
 6: 
 7:   $coocked = "";
 8:   $head = 0;
 9:   $tail = strlen($raw);
10:   $pos = 0;
11: 
12:   while ($head < $tail) {
13:     $count = preg_match($pattern, $raw, $matches,
14:                         PREG_OFFSET_CAPTURE, $head);
15:     if ($count > 0) {
16:       $entity = $matches[0][0];
17:       $pos = $matches[0][1];
18:       if ($head < $pos) {
19:         $normal = substr($raw, $head, $pos - $head);
20:         $coocked = $coocked . $normal;
21:       }
22:       $coocked = $coocked . 
23:                  html_entity_decode($entity, ENT_NOQUOTES, 'UTF-8');
24:       $head = $pos + strlen($entity);
25:     } else {
26:       $coocked = $coocked . substr($raw, $head);
27:       break;
28:     }
29:   }
30: 
31:   fwrite(STDOUT, $coocked);
32: }
33: ?>

これも先の Ruby のプログラムと同様、フィルタになっている。Ruby 版の方がぐっと短くなっているのは、わたしが Ruby の方を少し余計に知っているせいかも。PHP でも Ruby 版と同様の書き方にできるかもしれない。ただ、こちらの方が少し効率は良いはず。変換が進むにつれ探す部分が短くなるから。

関連リンク

2009-12-03

Ruby 1.9.1 を ports でインストール

実行結果だけを示す。要した時間は約5分。

[mini:~] mnbi% sudo port install ruby19
--->  Computing dependencies for ruby19
--->  Fetching ruby19
[... snip ...]
--->  Building ruby19
--->  Staging ruby19 into destroot
--->  Installing ruby19 @1.9.1-p243_0
--->  Activating ruby19 @1.9.1-p243_0
--->  Cleaning ruby19
[mini:~] mnbi% rehash
[mini:~] mnbi% ruby1.9 -v
ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin10]

PHP: date.timezone に関する警告問題

ちょっと必要があって、Snow Leopard Server 上で WordPress を動かすことにした。その過程で出くわしたことを書き留めておく。全体の流れはこんな風(↓):

  1. PHP モジュールを有効にする
  2. date.timezone に関する警告
  3. phpinfo() を実行する
  4. クライアント版では・・・

PHP モジュールを有効にする

Snow Leopard Server の Web サービスは Apache が使われているが(バージョンは 2.2; in 10.6.2)、デフォルトでは PHP モジュールが無効になっている。まずは、これを有効にすることが必要。

手順は簡単で、「サーバ管理」を起動し Web の「設定」から php5_module のチェックを入れるだけ。あとはウィンドウ右下にある「保存」ボタンを押せば完了。

手作業でやったとしても、/etc/apache2 あたりの httpd.conf を書き換えるだけなんだが、GUI があるとカンタンではある。Apache の停止や再起動も意識せずに済むし。何より、Snow Leopard Server では GUI 中心の管理作業が前提になっているから、不用意に手作業を混じえない方が良い。ちなみに、Apache の管理を手作業でやる前は /etc/apache2/ReadMe.txt を読むべし。httpd.conf の運用に関する注意点が書かれている。

phpinfo() を実行する

まずは、PHP モジュールが動作していることを確認するため、phpinfo() を表示させてみる。これには、通常こういうファイルを用意する(↓)。

(phpinfo.php)
 1: <?php
 2: phpinfo();
 3: ?>

たいした手間ではないけど、Snow Leopard Server ならこれが省略できる。あらかじめ /Library/WebServer/Documentsinfo.php というファイルが用意されているからだ。内容は上とほとんど同じ。違いはコメントで注意書きがある程度。ただし、肝心な phpinfo() を呼び出す行がコメントアウトされている。注意書きによれば、これを実行することでサーバの設定情報が見えるからだと言う。

コメントアウトを外してこのファイルを表示させてみる。上記のフォルダは Snow Leopard Server 上の Apache の DocumentRoot なので、ブラウザからこんな URL を開けば良い。

http://mini/info.php

PHP Version 5.3.0 で、2009-07-19 にビルドされたことなんかがわかる。

date.timezone に関する警告

と、ここで、Apache のエラーログをチェックしてみた。すると、こんな警告が出ていた。

PHP Warning: phpinfo(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Tokyo' for 'JST/9.0/no DST' instead in /Library/WebServer/Documents/info.php on line 5

要は date.timezone を設定しろ、ってこと。ぐぐってみたところ、それには php.ini を使うとわかった。Snow Leopard Server では PHP モジュールを有効にすると、/etc/php.ini が作られる(/etc/php.ini.defaultというファイルがコピーされるだけっぽい)。

該当する部分はこんな感じになっている。見てわかるようにデフォルトの状態では date.timezone は設定されていない。

(/etc/php.ini)
 1:    (...)
 2: [Date]
 3: ; Defines the default timezone used by the date functions
 4: ; http://php.net/date.timezone
 5: ;date.timezone =
 6:    (...)

↑の5行目のコメントアウトを外し、値として Asia/Tokyo を設定すれば良い。警告メッセージは出なくなる。

クライアント版では・・・

比較のために、クライアント版の Snow Leopard でも上記のことを確認してみた。違いは以下のとおり。

  • PHP モジュールを有効にするのは手作業
  • phpinfo() のためのファイルは自分で用意
  • PHP は同じ Version 5.3.0 (ビルド時間も同一)
  • date.timezone に関する警告はやはり出る
  • /etc/php.ini はないので、/etc/php.ini.default を手作業でコピーする
  • 書き換える内容は同じ

その他

ちなみに、Snow Leopard Server には MySQL が同梱されていて、これも「サーバ管理」から有効にするだけで使える。WordPress を動かすのに必要なものは本体以外にないってこと。phpMyAdmin はインストールされていないけれど、WordPress を(ちょっと)動かすだけなら必要性は低い。

関連リンク

2009-11-29

O'Reilly の Ebook を買ってみる

少し前から気になっていた O'Reilly の電子本、Ebook を試しに 1 冊、買ってみることにした。この Ebooks の特徴は、複数のデバイスに最適化されたフォーマットのものが用意されている点。また、一度購入するとすべてのフォーマットを好きなだけダウンロードすることができる。さらに、データファイルには DRM がかかっていないため、機器から機器へのコピーも自由。だからといって、無料で配布して良いわけではない。印刷された本と同じような扱いなら良いよ、ということ。個人で自分ひとりが使う分には、細かいことは気にしなくて良いわけだ。

用意されているフォーマットは 3 種類。PDF、ePub、そして Mobi。簡単に言えば、PDF はパソコン(Mac や PC)用、ePub は iPhone 用(Stanza というアプリを使う)、Mobi は Amazon の Kindle 用だ。

印刷された本は好きだし、メディアとしての紙はとても優秀だと思う。ただ、こいつは物理的な実体を伴う。保持するためには空間コストが高くつく。平たく言えば、本を溜めこむと部屋が狭くなる。世の中には自室で遭難するほど本を溜めこむ強者もいるようだけど、ともあれその空間占有率はデジタル化された情報にくらべればはるかに高い。読んで処分する(売る、捨てる、等)のがまっとうな対処だけど、それが簡単にできるなら溜まったりしない。読んでない本は処分できないし(せっかく手に入れたのに)、読んだ本も「また読みたくなるかも」とか「この情報がいつか必要になるかも」などと思ってこれも処分しづらい。

今ある本をどうにかするための手段として有望なのが、スキャナによるデジタル化だ。バラす手間がかかることが難点だが、PDF にしてしまえば空間占有率は無視できるほど低くなる。一方で、これから入手する本への対処も必要だ。スキャンして減らした分を新しい本で埋めてしまっては元も子もない。そこで、Ebook のような電子書籍を試すことにしたわけだ。

今回、買ってみたのは Programming Interactiveity (O'Reilly のカタログへのリンク; プレビューあり) という本(↓)。2009年7月に出版された比較的新しいものだ。

さて、実際の見た目はというと・・・

2009-11-28

フリーランチの時代 ([著]小川一水, [版]ハヤカワ文庫JA930)

フリーランチの時代
小川 一水
早川書房 ( 2008-07 )
ISBN: 9784150309305
おすすめ度:アマゾンおすすめ度

小川一水の短編集。表題作から「Slowlife in Starship」までを読んだところだ。

収録作品

  • フリーランチの時代
  • Live me Me.
  • Slowlife in Starship
  • 千歳の坂も
  • アルワラの潮の音

雑感

表題作の「フリーランチの時代」は、もし何もかもがタダもしくは、コストを無視できるぐらい非常に安価で手に入れられるようになると聞いたら、あなたはそうなることを選択するか、というような内容。

無論、変化にはそれなりの代償が必要。あなたにとって、大事かどうかはわからないけど、ヒトとして本質的な何かと引き換えにしても「フリーランチ」を選びますか、そういう選択を突きつけられる。ある者は不可避に、別の者は生命体につきものの欲求と決別するため、またある者は自らの知識を拡大するため、それぞれに「フリー」となることを選ぶ。

さて、あなたならどうする? わたしは、一も二もなく飛びつくだろうな。食う心配(他にもいろいろあるよね)をしなくて良くなるなら、ヒトでなくなったって構わない。

「Live me Me.」はラストがちょっとつらい。話の筋から言って、大団円のまま終わることは無理なんだけど、やはり、ちょっとね。ヒトって何、知能ってどういうもの、意識ってどこにあるの? そう問いかける物語。

「Slowlife in Starship」では、表題作とは違った形でフリーランチが実現された世界を描く。あらゆるものがタダで、というのとは違うけれど、生きていくのに困らない程度のものは非常に安価に贖えるようになった時代。ヒトはどう変わるのか? 皆が抱く、素直な疑問に対するひとつの解答(有り得る姿)。それは「際限ない発展」と「引きこもり」。

比類なき自負心を武器に、人類の領土を着実に広げていく人々が形づくる世界。その片隅には、ニッチな生産にたずさわることで人類社会とゆるやかな交渉を保ちつつも、自分の世界から出てこようとしない人々がいる。人類に星々の征服を可能にした技術が、その一部を何万という小惑星に「引きこもる」ことも可能にしたのだ。

タイトルにある slowlife は、そんな「際限ない発展」と「引きこもり」の狭間を行き来しつつ暮らすこと。太陽風に吹かれながらゆっくりと太陽系を進む、そんな生活のこと。

遠い未来の物語のようなんだけど、実は現在にも似たような状況は存在している。だからこそ、こういう明るく前向きなラストにしたんだろう。そこはちょっと気に入らないが、それは読む側が中年のオッサンだからかもしれない。

さて、フリーランチについて、もう少し語ってみよう。

2009-11-27

twitter より (2009-11-26)

  • ほらぁ、Google がぐずぐずしているから、先に作っちゃった人がいるゾ。 http://bit.ly/6PB8eI posted at 17:50:15
  • このサイトをさっくり1000万ドルぐらいで買い取って、さっさと Google Galaxy を作ってください > Google posted at 17:50:58
  • それにしても何だねえ。ただの光の点が集まっているだけなのに、こんなにも「キレイ」とか「美しい」とか思ってしまうのは不思議だよ。 http://bit.ly/4MsvGr posted at 17:53:13
  • う〜ん、説明を読んでいると 1000万ドルじゃ安いっていう気がしてくるな。たぶん、10年前じゃ、これは作れなかった。100年前なら言うまでもない。それでいて、「今だけ」で作れるものでもない。これも立派な人類の遺産だ。 posted at 17:58:26
  • そろそろネット上の構築物の中にも「世界遺産」に登録しても良いものができてるんじゃないか? posted at 17:59:54
  • 建物なんかの「ハードウェア」とは違い、デジタルデータとソフトウェアなんて、一瞬で失われてしまうゾ。資金が尽きて、引き取り手が現れなかったら、何もなかったことになってしまう。儚いモノなんだ。 posted at 18:02:42

2009-11-25

理想のノート(アプリ編)

きっかけは Google Notebook の開発終了告知だった。 当時(2009年1月)も今も、Google が提供するサービスの中では一番気に入っていた。 この先、2年か3年たってこのことを振り返ったとき、「ああこれが Google にとっての分岐点だったのか」と思う気がしている。GNB を終わらせるということは、Google が未来ではなくて現在を選択することだと考えるからだ。世界のどこにもないものを創り続けてきた者たちが、今あるものを大事にしていこうと方針転換をした瞬間だと思うから。 単に本業であるサーチに注力するってだけかもしれないけどね。その割にはその後も変なサービスをあれこれ作ってるんだよなあ。

ともあれ、わたしにとっての「理想のノートであり、メモ帖であり、スクラップブックだった」ものが消えた(開発が打ち切られただけなんだけど)。もう、Google は作ってくれない。ならば自分で作るしかない。作れないとしても、「こんなものが欲しい」ということを書き貯めていこう。そう思って、「理想のノート(アプリ編)」というブログを始めた。たった 3 本しか記事は書かなかったが、「理想のノート」に対する思いは今も消えていない。だから、これを LOG+REPO の 3 つ目のメインテーマにする。

ラベルは「1. 理想のノート(アプリ編)」を使う。

「アプリ編」と付記してあるのは、ハードウェアのことは考えない。OS のことも考えない。というか、Mac ないしは iPhone で実現したい、してほしいモノだから、範囲としてはアプリになる。

デジタルツールに欠けているコト

紙(ノート)と鉛筆(ペン)では当たり前のことで、デジタルツール(パソコンのアプリ)では実現できないことがある。表現に対する自由度の低さだとか、持ち運びにかかる手間が大きいだとか、使える場所を限るだとか、そういうすぐに目につく特性ではない。当たり前すぎて目の前にあるのに気付かないこと。それは「減っていく」ないしは「埋まっていく」ことの快感。アナログの世界では本質的につきまとう特性だ。未来が過去に変わる快感とでも言おうか。真っ白いページが自分の書いた文字で埋まっていく。書いている最中にも常に感じているし、ふとしたとき使ったページをパラパラとめくっても感じる。デジタルなツールでこれを感じさせてくれるものに出会ったことがない。

MOLESKINE と LAMMY
送信者 LOG+REPO

どっぷりとデジタルなツール(Mac や iPhone)と環境(インターネット)に漬かって暮らしていながら、コンピュータ出現以前に慣れ親しんだアナログ系の道具(文房具)への憧れは消えない。必要性に迫られて使うこと(パソコンを持ち込めないような状況とか)もあれば、他の選択肢をあえて捨ててそっちを選ぶこともある。

前者の典型は、通勤の電車のような空間的な制約がある場合に使う。ロディアのような小さなメモとシャープペンシルがこの場合に適した組合せ。デジタルネイティブな世代であれば、片手で使えるケータイの方が良いと言うかもしれない。

後者の典型は、一日の出来事を振り返りつつ記録するときに選ぶ。平たく言えば日記。現在、このために使っているのは MOLESKINE の手帳と LAMMY の万年筆。今回のトピックである「減っていく」あるいは「埋まっていく」快感については、日々の記録を書いているとき、そしてそれを週次で見返すときに感じるようになった。

毎日、ページを自分の文字(おせじにもキレイな字とは言えない)で埋めていくことが、日々の記録をつけるモチベーションになる。どんなに眠くてもこれだけはやっておきたいと思える。ここまで書いたのか、とうれしくなる。同じことを感じさせてくれるデジタルツールはあるだろうか? いや今まで出会ったことはない。では、そういうツールを作ることは可能だろうか? それともデジタルなツールには本質的に欠けている何かがあるのだろうか?

2009-11-22

Mac mini はとても静か

静かな Mac mini

Mac mini Server (Late 2009) が届いたのは 2009-10-23 のこと。それから一ヶ月たった。サーバ版 OS なんだけど、もっぱらデスクトップ版 Mac として使っている。今のところトラブルは起きていない。

一ヶ月使い続けて、何より思うのは「すっごい静か」ということ。こいつの前のデスクトップが Power Mac G5 (Early 2005) だったから余計にそう感じるのかもしれない。あれはうるさかった。

メールやらウェブやら何やらでは MacBook (Early 2008) を使っている。これも静かなんだけど、YouTube の動画を再生したりするとファンが回り出す。普段が静かな分、余計に目立つ。

一方、mini はというと本当に静か。たまに、「あれ、なんか音がするゾ」と気付くことがあるけど、これは Time Machine が 2 台目の HDD にアクセスしている音。mini は他に音を出していないんじゃないかって思うほど。ファンなんか回っているのを聞いた記憶がない。ま、用途にもよるのかもしれんが。

コンパクトで、静かな Mac というと思い出すのは Power Mac G4 Cube のこと。わたし自身は使ったことがないんだけど、こういう写真(→ Power Mac G4 Cube と Apple Studio Display Wikipedia)を良くみかけて強烈に憧れたものだ。2009 年の感覚で見れば約 20 cm の(ほぼ)立方体っていうのはそれほど小さくはない。ましてや mini がある現在、十分に大きく見える。ひょっとしたら、世界のどこかには、mini の中身を Cube に筐体に押し込んで使っている人もいるかも。

2009-11-21

frickr から画像を貼ると・・・

Picasa ではなくて、flickr を使うとどうなるか。
こうなる。どっちが良いかね (・ω・)?

img の alt は空で貼り込まれるようだ。ここに画像のタイトルなんかを流し込んでもらいたいんだけど。

関連記事

手書きメモはスキャンして貼る

数式が混じったメモやノートを Mac や PC で作るのはメンドウだ。ワープロを使ったり、TeX に頼るっていう手もあるけど、どうしても入力のスピードで手書きに劣る。本を書くとかなら手間に見合うと思うけど。

いっそ、手書きでも良いじゃないか。今はスキャンという手段があるのだ。紙と鉛筆(ペンの方がスキャンに向いている)で、じゃかじゃか書いて、ささっとスキャン。あとは Picasa に上げてブログに貼り付け。検索の手は届かないけど、どうせ数式なんて検索できない。計算の目的や理由をブログのテキストで書くなり、画像の説明に付ければ十分だろう。

そんなわけで、ちょっと手書きの計算メモを貼りつけるテスト。Picasa だと画像の説明が埋め込まれないんだよな。改良を希望するぞ > Google

手書き計算; p29 (和の順序変更)
送信者 taocp

関連記事

2009-11-20

iPhone 対応してみる

今日はスタイルをいじる日。引用のためのスタイルだとか、ブログタイトルの下にあるナビゲーションメニューを整えたりだとか。勢い余って、iPhone で見たときにそれっぽく見えるようにしてみた。まずは、これが始めの第一歩。

デバイスごとに見かけを変えるしかけ

iPhone 対応にするには、大きく 2 つの作業が必要になる。 ひとつは、iPhone 特有の Viewport を適切に設定することだ。これには JavaScript でユーザエージェントを判定した後、iPhone (あるいは iPod touch) の場合は meta 要素を使って viewport を設定する。 もうひとつは、iPhone とその他(Mac や PC、等)でスタイルを切り替えられるようにすること。これには、メディアクエリーという CSS 3 の機能を使う。

Viewport の設定

(「iPhoneサイト制作ハンドブック」p.95)
Mobile Safari には、一般的な PC の Web ブラウザのような、サイズを変えらえるウィンドウがありません。Mobile Safari でコンテンツを配置するのに使われるのは、仮想的な表示領域である「Viewport」です。

Mobile Safari の表示と Viewport の関係は、スクリーンの背後にある Viewport の "風景" を、スクリーンのサイズに切り抜かれた "窓" を通して見ているようなイメージです。この "窓" のサイズは変えられませんが、Viewport の "風景" は、大きくなったり小さくなったり、拡大率が変わったりします。

iPhone の Safari で一般の(ie iPhone 対応になっていない)ページを開くと、ダブルクリックやピンチ操作で表示部分を拡大したり、縮小したりできる。あれはこの Viewport が変わっているのだ。コンテンツのレイアウトを iPhone 用に定義するのであれば、Viewport の拡大や縮小は不要。よって、今回、やるべきことは Viewport をサイズ、倍率ともに固定してしまうことだ。

属性設定値
widthdevice-width
user-scalableno
initial-scale1
maximum-scale1

他のデバイスでは意味のない定義だから、iPhone かどうかの判別をした上で meta 要素を挿入する (あっても邪魔にはならないと思うけどね)。これはは以下の JavaScript コードで行う。長い行は "\" で折り返してある。

(iPhone 判定)
 1: var is_iphone = navigator.userAgent.indexOf("iPhone", 0);
 2: var is_ipod = navigator.userAgent.indexOf("iPod", 0);
 3: if ((is_iphone & is_ipod) > -1) {
 4:  document.write('<meta name="viewport" \
                     content="width=device-width, \
                     user-scalable=no, initial-scale=1, \
                     maximum-scale=1" />');
}

これを script タグで囲って、テンプレートの head 要素内に置く。title 要素の前とか、すぐ後ろとか、その辺り。

引用文のためのスタイルを定義

引用文(blockquote 要素)を目立たせようと、スタイルを定義した。こんな風(↓)になる。

SICP:
Program must be written for people to read, only incidentally for machine to execute.

色は、Mail.app の「メモ」で使われている色(「#FEF8BC」)。 ノートのような罫線はぐぐって見つけたここからパクり(→ mugu - memo - CSSでノート風罫線)。画像はサイズを変更した上で使用させてもらっている。
作者に感謝。

2009-11-19

MacRuby のこれまで (0.1 〜 0.5 beta 2)

公式ブログのリリース告知をざっとまとめていたんだけど、公式なロードマップが存在していた(→ MacRuby >> Roadmap)。こっちの方がコンパクトなので、それを元に、さらに最新版の 0.5 beta 2 までの特徴を入れ込んでみる。

追記@2010-11-26

0.5 beta 2 の後、0.7 までについてはこちらを参照 → 「MacRuby 0.7 を iMac にインストール

0.1 (released 2008-03-13): GC をふくむランタイムの統合

Roadmap で特色とされているのは以下の 5 項目。

  • 最初の公開リリース
  • Objective-C のランタイムにもとづくオブジェクトモデル
  • Objective-C のメッセージ伝播の仕組みの基礎部分
  • BridgeSupport ファイルを読み込み可能
  • Objective-C の GC との統合

BridgeSupport ファイルはフレームワークやライブラリの API シンボル情報を記載した XML ファイルで、RubyCocoa や PyObjC のようなスクリプト言語と Objective-C ランタイムとのブリッジ機能で使われる。以上、Snow Leopard の man ページより。

Laurent が MacRuby-devl ML に投げた告知メールによれば、

MacRuby is a version of Ruby that runs on top of Objective-C. More precisely, MacRuby is currently a port of the Ruby 1.9 implementation for the Objective-C runtime and garbage collector.

肝心なことは Objective-C のオブジェクトがそのまま Ruby のオブジェクトになっているよ、というとだろう。MRI 1.9 を Objective-C のランタイムと GC に移植した、と言っている。

2009-11-18

MacRuby を試そう!

追記@2010-11-26

MacRuby に関しては以下の記事も参照のこと:

MacRuby の 0.5 beta 2 がリリースされたというので、試してみる気になった。

アナウンスに貼られたリンクから zip のインストールパッケージをダウンロード。zip を展開し、中の PKG ファイルをダブルクリックすればインストール開始。MacRuby の本体などは /usr/local/bin 以下に、Xcode のプロジェクトテンプレートは /Library/Application Support/Developer/3.0/Xcode 以下にそれぞれインストールされる。

インストールが完了するとこうなる(↓):

[macmini:~] mnbi% which macruby
/usr/local/bin/macruby
[macmini:~] mnbi% macruby -v
MacRuby version 0.5 (ruby 1.9.0) [universal-darwin10.0, x86_64]

また、Xcode の新規プロジェクト作成パネルはこう(↓):

MacRuby のプロジェクトテンプレート
送信者 Macをプログラムする

「RubyによるMac OS Xデスクトップアプリケーション開発入門」を見ながらサンプルを試してみたり(p.224 〜 234)。

2009-11-17

Go のサンプルコードを Ruby で書き直してみる

Go の channel のようなものとして、Ruby には Queue クラスが用意されている。これを使えば、Rob Pike の説明していたサンプル (A multiplexed server) をほぼそのままの形で Ruby に直すことができる。対応するプログラミング要素はこんな感じ(↓):

Go Ruby
channel型Queue クラス
func型ブロック
goroutineThread クラス

ちなみに、今回使った Ruby は Snow Leopard に標準のもの。バージョンはこれ(↓):

[macmini:~] mnbi% which ruby
/usr/bin/ruby
[macmini:~] mnbi% ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0]

コードはこうなる。コメントもオリジナルのものをそのまま相当する場所に記入しておいた。

(multi_server.rb)
 1: require 'thread'
 2: 
 3: class Request
 4:   def initialize(a, b, q)
 5:     @a = a
 6:     @b = b
 7:     @replyq = q                 # reply queue inside the Request
 8:   end
 9:   attr_reader :a, :b, :replyq
10: end
11: 
12: def run(req, op)
13:   req.replyq.enq(op.call(req.a, req.b))
14: end
15:
16: def server(service, op)
17:   loop {
18:     req = service.deq           # requests arrive here
19:     Thread.start(req) do |r|
20:       run(r, op)
21:     end
22:   }
23: end
24: 
25: def start_server(&op)
26:   req_queue = Queue.new
27:   Thread.start(req_queue, op) do |rq, o|
28:     server(rq, o)
29:   end
30:   return req_queue
31: end
32: 
33: # Start server; recieve a queue on which to send requests.
34: server = start_server {|a, b| (a + b)}
35: 
36: # Create requests
37: req1 = Request.new(23, 45, Queue.new)
38: req2 = Request.new(-17, 1 << 4, Queue.new)
39: 
40: # Send them in arbitrary order
41: server.enq(req1)
42: server.enq(req2)
43: 
44: # Wait for the answers in arbitrary order
45: puts "Answer2: #{req2.replyq.deq}"
46: puts "Answer1: #{req1.replyq.deq}"

オリジナルの Go コードと並べてみれば、ほぼ一対一に対応していることがわかる。

Go のサンプルにあった、channel に対する select を使った server は、Ruby の Queue では簡単に実現できない。Ruby に用意されている select (Kernel.select または IO.select) には IO オブジェクトしか使えない。Queue ではダメなのだ。Queue に対する select に相当する仕組みを Queue や Thread のメソッドを使って作ることは可能だ(と思う)けど、ちょっと面倒なことになる。

ちなみに実行結果は以下のとおり。ちゃんと動いた。

[macmini:~] mnbi% ruby multi_server.rb
Answer2: -1
Answer1: 68

関連リンク

関連記事

参考文献

プログラミング言語 Ruby
まつもと ゆきひろ, David Flanagan
オライリージャパン ( 2009-01-26 )
ISBN: 9784873113944
おすすめ度:アマゾンおすすめ度

2009-11-16

Go サンプルコードを読んでみる: A multiplexed server

Rob Pile が Go の channel の説明で使っていたサンプルを読んでみよう。 以下のコードはどれも、Rob Pike のスライドよりコピペしたもの。

まずはサーバのコード(スライドの 30 枚目)。

[A multiplexed Server]
 1: type Request struct {
 2:     a, b    int;
 3:     replyc  chan int; // reply channel inside the Request
 4: }
 5:
 6: type binOp func(a, b int) int
 7: func run(op binOp, req *request) {
 8:     req.replyc <- op(req.a, req.b)
 9: }
10:
11: func server(op binOp, service chan *request) {
12:     for {
13:         req := <-service; // requests arrive here
14:         go run(op, req);  // don't wait for op
15:     }
16: }
17:
18: func StartServer(op binOp) chan *request {
19:     reqChan := make(chan *request);
20:     go server(op, reqChan);
21:     return reqChan;
22: }

Go の文法はよくわからないが、このコードが何をするものなのかは、なんとなくわかる。

1 〜 4 行目は構造体の定義。replyc が整数の通る channel。その名前から、サーバへのリクエストに対する結果を返すものだと想像がつく。

6 〜 9 行目; サーバにおける処理の定義。2 つの整数に対して、2項演算を適用して、その結果を replyc に送る。

11 〜 16 行目; サーバ本体。引数は処理すべき 2 項演算とリクエストが通ってくる channel。for は無限ループ。13 行目でクライアントからのリクエストを取り出して、14 行目で実行。ところで、この 14 行目にある go が goroutine と呼ばれるスレッドを起動するものらしい。run はすぐ上の 7 行目で定義されている関数。それを別スレッドで処理するってことだ。

18 〜 22 行目が、サーバを起動する関数。引数としてサーバが処理する演算を受け取る。実行する内容は、リクエストを受け付ける channel を用意し(19 行目)、サーバ本体を別スレッドで起動し(20 行目)、リクエストを流す channel をクライアントに返す(21行目)。

2009-11-14

Mac mini に Maxima をインストール

ふと思い立って、Maxima をインストールしてみることにした。 まずは Mac mini (Server) でやってみた。

ちなみに、Maxima っていうのは GPL で配布されているフリーな数式処理システムだ。「はじめてのMaxima」によれば、

Maxima は 1960 年代の MIT の MACSYMA プロジェクトで開発された「MACSYMA」(MAC's SYmbolic Manipulation system) の「DOE(エネルギー省)版」を、Texas 大学のシェルター氏 (Schelter) が「Common Lisp: The language 第一版」に対応した「gcl」に移植したものです。

ということだ。手元にあるかなり古い雑誌(「インターフェイス」増刊の「archive」No.12) によれば、Maxima の前身である Macsyma の作成が開始されたのが 1966 年。1972 年に ARPA ネット(!) を通じて全米で使用可能となって、さらに一般で購入可能となったのが 1982 年だとのこと(ちなみに、同誌によれば現在数式処理ソフトとして有名な Mathematica の最初の版ができたのが 1988 年だそうな)。なかなかに歴史のあるソフトだ。

インストールを始める前はつまづくとは思っていなかった。MacPorts でインストールできるだろうと思っていたから。sudo port install maxima で後は待つだけ、そう高をくくっていた。世の中、そうそう甘くない。

2009-11-13

Realforce 86U、到着

キーボードこだわり概論

Realforce 86U: 外箱

わたし自身もそうだが、一般にキーボードに対する「こだわり」は大きく 2 つある。まず何より配列。次がキータッチ。どんなに心地良い叩き具合であっても、慣れた配列でなければ、しょっちゅうイラッとくる。だから配列が最優先。

パソコン用のキーボード配列には大きく 2 種類ある(PC であれ Mac であれ)。1 つは US 配列とか英字配列と呼ばれるもの。もう 1 つは JIS 配列あるいは日本語配列と呼ばれるもの。わたしは前者を好む。っていうか後者は使わない。「イラッとくる」から。最下段に変換、無変換のような時代遅れのキーが配置されているだけならまだしも、最上段の記号の位置が微妙に異なる。Enter キーの形状もおかしい。とにかく、JIS 配列は使わない。

キータッチにはいろいろとあるようだけど、配列の方を優先させるものにはこだわれるほどの選択肢はない。Mac ユーザだとさらに狭まる。加えて、かつてわたしは最高のキータッチのキーボードに出会ってしまっている。キータッチに関しては、あれ以外はすべて「にせもの」「まがいもの」だと感じる。「あれにくらべれば、どれも一緒、大差ないよ」と思ってしまう。

それは、昔の IBM 製 PC のために作られた日本語キーボード。パソコンがとても高い製品だったころのもの。今では手に入らないだろう。持っている人は幸運だ。わたしのいた会社では 106 キーボードと呼ばれていた。軽い叩き心地に、ほどよいストローク。何より音が良い。叩いている本人はもちろん、周囲にいる人の耳にも心地良い音だった。ただし、日本語キーボードだったから、わたし自身が使ったのはごく短期間。すぐに US 配列の 101 キーボードに乗り換えた。

今回、Realforce 86U に求めたのも上記 2 点。まずは配列。次がキータッチ。

第一印象

Realforce 86U: 左肩にロゴが入っている

この 86U は US 配列なので、第一関門はクリア。ただし、一口に US 配列とは言っても微妙な差異がある。具体的には最下段のスペースバー以外のキー、Mac OS X では修飾キーと呼ばれるキー群にその差異が現れる。Apple 純正キーボード(US)の場合、ここには[Control][Option]、そして[Command]の 3 種類のキーが並ぶ。コンパクトタイプなら[Fn]もある。わたしの場合、[Control]が最重要、続いて[Command][Option]については妥協の余地あり。

では、86U の最下段のキー配列を見てみよう。こんな風(↓)に並んでいる。

[Ctrl][W][Alt][  Space  ][Alt][AP][Ctrl]

[Ctrl](つまり[Control]) が両側かつ両端にあるのは good。ま、そうでなかったら買っていない。Emacs のキーバインドに慣れたものにとって [Ctrl] の位置は最重要。世間ではなぜか [Caps Lock] の位置に [Ctrl] を置くのが人気のようだけど、わたしは最下段のなるべく外側にないと困る。とても困る。両端ならベストポジション。ちなみに、Controlキーは指で押すもんじゃない。両方の小指のつけねというか手のひらの端というか、その辺りで押すものだ。そうすると両手に負荷を分散できる。(ノートタイプの場合は事情が変わる。)

スペースバーのすぐ外側にある[Alt]は、OS の設定で[Command]に替えよう。キーとしてはこの位置、この大きさで good。

[W]Windows キー[AP]アプリケーションキー(以下、AP キー)。 どちらも Mac には不要のもの。むかしはこんな余計なものは付いていなかった(十数年前)。ここに欲しいのは[Option]なんだよねえ。

キータッチは・・・「最高のあれ」と同じ感触でないことは確か。だからといって、ダメだってことでもない。今も 86U でこれを書いているが、こればっかりはしばらく使ってみなければ評価しにくい。ただ 1 つ、今の段階でも言えることは、音は悪いってこと。ストロークの深さも機構も違うから、比較してもしかたがないけど、今まで使っていた Apple Wireless Keyboard の方が音はマシ。

さて、箱から出して実際に使おうとすると、いくつか問題に遭遇した。

問題点 #1: 不要なキー

邪魔なアプリケーションキー

さて、Mac ユーザには意味のない AP キーだが、どうやら OSX には[Enter]のように見えるらしい。修飾キーだとは思ってくれていない。つまり、[Option]の振りをさせられないってことだ。

解決策

なし…orz
不用意に触れて [Enter] が入力されるのもうっとおしいので、Realforce の DIP スイッチで AP キーを無効にしておく(SW4 → ON)。押しても何も起こらない。ムダなキーだ。

問題点 #2: おかしな挙動

Mac OS X ではキーボード上の修飾キー([Command][Option][Control][ および [Caps Lock])をそれぞれ入れ替えることができる。この機能を使って、86U の修飾キーの機能を以下のように入れ替えた。ちなみに、Alt キーは[Option]、Windows キーは[Command]として認識されていた。

OptionCommand
CommandOption

ここで問題が起きた。この設定だと右側の[Alt][Command]キーとして機能しないのだ。なぜか[Alt](つまり[Option])のまま。これには困った。OS が悪いのか、86U が悪いのか(仕様? 故障?)。

解決策
システム環境設定:キーボード:修飾キー設定パネル:Realforce 86U用の設定

しばらく悩んだ末、回りくどい方法だけど解決できた。以下にその方法を示す。

  1. Realforce で[Ctrl][Alt]を入れ替える。(SW3 → ON)
  2. OS の設定で [Control][Command] に、 [Option][Control] に入れ替える。

不思議なもので、これだと右側の Alt キーもこちらの意図どおりに機能する。原因は不明。試行錯誤の末に見つけた、その場しのぎの方法だ。ま、使えれば良い。

先に入れ替えてあった、[W] → [Option]と併わせて、ほぼ望みどおりの配列になった。[Option]が左側にしかないのは気に入らないけれど、こいつは[Option] + Spaceしか使わないので、十分妥協可能。ちなみに、このキーで Spotlight 検索の小窓が開くように設定してある。

関連リンク

2009-11-12

Go - A Programming Language

Google で作られた新しいプログラミング言語。とりあえず Rob Pike の TechTalk を見てみた。約1時間。軽い気持ちだと最後まで見通せないぞ。英語だし。早口だし。むしろ、じっくりスライド(PDF)を見た方が良いかも。

最初は、とくに表記の仕方に戸惑った。なんと、型を変数名の後に書く。違和感ありまくりだったが、しばらく見ていると慣れるものだね。読むだけなら、これはこれで読みやすいかも、と思い始めている。書くとなったら、しばらく混乱しそう。

↑の Tech Talk 中で説明される言語の特徴、機能の中では、channel がおもしろそうだと感じた。

The Go Programming Language Specification
A channel provides a mechanism for two concurrently executing functions to synchronize execution and communicate by passing a value of a specified element type.

簡単に言ってしまえば、queue が言語に作り付けになっている、ってこと。queue は、ごくおおざっぱに言えば、右から入れたものが左から取り出せる筒のようなもの。すぐに取り出しても良いし、後で取り出しても良い。入れた人と取り出す人が別でも良い。入れた後、すぐに別のことを始めても良いし、取り出されるまで待っていても良い。取り出す人は筒がからっぽなら誰かが入れてくれるまで待つ。並列プログラミングのための仕組みだ。

この queue、Ruby だとクラスライブラリとして実現されている。用途はまさにスレッド間通信。

↑の Tech Talk で説明されていたマルチサーバの例で、この channel が使われていた。2 本の channel を使って、処理リクエストとサーバの制御(停止)を実現していた。mutex を使って共有変数を仕立てるなんていうのは primitive すぎるのだね、と目からウロコが2、3枚落ちた。

関連サイト

2009-11-11

Snow Leopard アップデート (→ 10.6.2)

送信者 Macをプログラムする

MacBook (Early 2008) の雪豹の場合アップデートファイルのサイズは 157.7MB。Mac OS X v10.6.2 アップデートについて をざっと眺めてみたけど何が変わったか実感できるような項目は見つけられなかった。

一方、Mac mini Server (Late 2009) の Server は 524.5MB。でかい。ビックリした。こちらも、Mac OS X Server v10.6.2 のアップデートについて を見た。やはり、特記したい項目は見つけられなかった。ただ、ページの一番最後にこう(↓)書いてあったので、当たり前だけどちょっと安心した。

Mac OS X Server v10.6.2 には、クライアントの Mac OS X v10.6.2 アップデート で提供されるその他のすべての改善事項も含まれます。

同時適用のセキュリティアップデートはクライアント版、サーバ版で共通。詳細はここ(↓)にある。ちなみに、日本語環境で上記の「・・・アップデートについて」からリンクをたどってもここにたどりつけない。途中のリンクが間違っている。(2009-11-11 23:00 時点)。一度、英語版を表示させてからだとたどりつける。

アップデート後の About ウィンドウ。

そうだ、今後の比較のために、カーネルのバージョンを記録しておこう。これが Server 版。

[foo:~] bar% uname -a
Darwin foo.private 10.2.0 Darwin Kernel Version 10.2.0: \
Tue Nov  3 10:37:10 PST 2009; root:xnu-1486.2.11~1/RELEASE_I386 i386

こっちが MacBook の方。

[baz:~] bar% uname -a
Darwin baz.local 10.2.0 Darwin Kernel Version 10.2.0: \
Tue Nov  3 10:37:10 PST 2009; root:xnu-1486.2.11~1/RELEASE_I386 i386

どちらも同じだってことがわかる。(行が長いので "\" のところで折り返してある。)

ScanSnap Manager アップデート

11月にアップデートが出るという噂をネットで見ていたので、公式サイトにアクセスしたところ、アナウンスが出ていた(↓):

[2009年11月 9日] ScanSnap Manager V3.0 アップデートパック1(Snow Leopard対応)
[2009年11月 9日] CardMinder V1.0 アップデートパック2(Snow Leopard対応)

Snow Leopard 対応となっているけど、何にどう対応したのかは書かれていない。テキスト認識が高速になった、とかならウレシイんだけどな。

公式サイトから dmg をダウンロードしてアップデートした後に気付いたんだけど、ScanSnap Manager、CardMinder ともにアプリを起動した状態から「ヘルプ」>「オンラインアップデート…」を実行すればアップデートの確認からダウンロード、アップデートとやってくれる。

関連記事

テンプレートを確認するためのサンプル

これは H4

この記事は、テンプレートで設定したスタイル等の見栄えを確認するためのサンプル集。ここは通常の段落(ただの p)。

  • これはリスト
  • MacBook (Early 2008)
  • Mac mini Server (Late 2009)
  1. これは番号つきリスト
  2. Snow Leopard 10.6
  3. Snow Leopard 10.6.1
  4. Snow Leopard 10.6.2
これは H5

↓はターミナルの出力を表示するスタイル。class つきの pre

[foo:~/] bar% git
usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
           [-p|--paginate|--no-pager]
           [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
           [--help] COMMAND [ARGS]

今度はソースコードを表示するためのスタイル。class つきの pre に code が入ったもの。

# This is a very long long long long long long long long long long long long line.
# This is a very long long long long long long long long long long long long long long long long line.
# This is a very very very very very very very very very very long long long long long long long long long long long long line.

次は本やウェブページからの引用に使う。blockquote

SICP
Program must be written for people to read, only incidentally for machine to execute.

そして dl

Macintosh
Apple 社が製造、販売しているパーソナルコンピュータ。
単価数量価格
1,0001010,000
10,0001001,000,000
合計-1,010,000

捨てることで見つける

【連載】Google世代の整理術「デジタル情報整理ハックス」 (21) 「どうしてもとっておきたいエントリ」はどうするか?
情報収集と一口に言っても、新聞のスクラップが主だった時代に比べて、インターネット時代の今は、収集のたやすさと情報量の豊富さにおいて、圧倒的です。こういう環境では、厳選のレベルをいくら高く設定しても、高すぎることなどないように思えます。

「気になったものはなんでも取っておくといい」というのは、むしろ紙の時代の箴言です。今ではむしろ、ちょっとでもいらないかなと思えた情報は、とにかく捨てた方がいいと言っても、過言ではないでしょう。

「はてブ」や diigo のような SBS の登場で URL を記録しておくことがとても簡単になった。その結果、ブックマークがあふれてしまう。で、せっかく取っておいた URL も埋もれてしまって見つけられない。しかたがないから、ブックマークを検索するようになる。で、ふと気付く、「あ、Google で検索すればいいじゃん。ブクマ、いらないな」と。

RSSリーダーの登場でウェブに流れる情報の監視がとても簡単になった。その結果、未読フィードがあふれてしまう。結局、読まないまま「既読にする」をクリックしてしまう。ちらっとタイトルだけを見た記憶から、あんな記事やこんな記事があったはず、とRSSリーダーに保存されたフィードを検索するようになる。で、ふと思う、「あ、これって Google で検索するのと同じ。RSSリーダー不要。ってか、最初から読まなくて良いんじゃないか?」

情報が大量に蓄積してしまうと、見つけるためには検索を用いるしかない。情報の山を始めから終わりまで(少なくとも見つかるまで)、順にたどるような方法は探索時にコストがかかりすぎる。蓄積時に整理、分類すれば探索の手間は省けるが、今度は蓄積するときにコストが発生する。加えて、たいていの人は体系立った分類法など身につけてはいない。一貫した分類を行おうとするだけで苦痛になる。整理が不要な量に収まっているときだけ効率良く整理できる。人はスケーラブルにはできていない。「大量」を相手にするには機械に頼るしかない。

一方で、検索には「見つからないかもしれない」問題がつきまとう。たとえ自分が蓄えた情報であっても目的の対象を見つけられるとは限らない。「ブックマークしたはず」という記憶が間違っていることもあるし、適切な検索語を思いつけないこともある。整理と探索にかかるコストを劇的に軽減してくれる「検索技術」は「発見する」という事象を確率化してしまうのだ。

「確率化されてしまった発見」に対して、「見つかる確率」を上げるためにさまざまな工夫が発明されてきた。SBS のように、ブックマークを共有し、タグづけを「みんな」で行うことで、集合知を味方につけようとする技術はその代表。けれど、ちょっと考えてみよう。これは Google が検索精度の向上の名のもとに日々取り組んでいることとかぶっているんじゃないか? PageRank はそもそも集合知を検索に生かそうという試みだ。ウェブ履歴は個人の嗜好を検索に反映させるものだ。

だったら、情報はどんどん捨ててしまおう。大丈夫、それがネット上のものであるなら、Google が拾ってくれる。きちんとしまっておいてくれる。必要になったら見つけてくれる(かもしれない)。見つからなければそれまでのもの。縁がなかったってことだ。心配ない、情報は、興味を引くものは他にもいっぱいある。

捨てて、捨てて、捨てまくって、それでもなお捨てられずに残るものがあるなら、それは自身にとって肝心な何か。「必要だから」じゃない、「役に立つから」でもない。それは自分にとって「忘れたくないモノ」。こだわらずにはいられない何か。捨てることで大事なものを見つける。それだけを手に持って、あとは全部、丸ごと Google に任せよう。

情報はしぼらなきゃならないという発想。これは、限られたリソースをどこに投資するかという問題(選択と集中)のバリエーションだ。そして、この問題はライフハック界隈で繰返し聞く「制御(コントロール)を取り戻す」という主張とつながくる。

「しぼる」は「捨てる」、「あきらめる」と同義。「あきらめる」こと、それが肝心。その代わり、あきらめなかったことはとことん追求する。こだわる。それが職人ってものだろう?

2009-11-10

MacBook にも Git を (あるいはリモートリポジトリの準備)

MacBook にも Git をインストール。先日の Mac mini Server のときと同じく ports まかせ。

こうして、ネットワークでつながった 2 台のコンピュータの両方に Git が準備できた。両者の間でリポジトリの clone や、変更の push を試してみよう。

プロトコルを選ぶ

Git は分散 VCS で、かつリポジトリの間に優劣の差がない。実際にそうするかどうかは別として、すべてのリポジトリはリモートリポジトリになることができる。他のコンピュータからのリポジトリの複製要求に応えることができる。適切に設定してやれば。

手元の(ローカル)なコンピュータに Git がインストールされていれば、ネットワーク上(リモート)のコンピュータからリポジトリの内容を複製するための準備は整っている。実際、GitHub などの公開リポジトリから git clone で複製できる。では、複製要求に応える方のコンピュータにはどんな準備が必要なのか。

その問いに応えるためには、まず、Git がリモートリポジトリにアクセスするプロトコルを選ばなくてはならない。プロトコルによって準備が異なるからだ。

「入門git」(p.97-100) によれば、Git が対応しているネットワーク接続のためのプロトコルは、SSH、git、そして HTTP/HTTPS の 3 つ。今回、このうちの SSH と git を使った接続をそれぞれ試してみた。以下に、それぞれの場合にリモート側のコンピュータで必要な設定について試した内容と結果を述べる。
(この記事では SSH の場合のみを扱う。git プロトコルについては別の記事で書く)

Git コマンド群への PATH 設定

さて、2 台のコンピュータ間で SSH 経由のリモートログインができるように設定されているとする (うちの MacBook と Mac mini Server ではすでにそうなっている)。この状態で以下のコマンドを叩いてみる(入門git; p.98, 101)。

[foo:~] % git clone bar.local:projects/greeting

foo.local から bar.local のリモートリポジトリを clone しようというものだ。もし、このとき git-upload-pack: Command not found. というエラーが出て、clone が失敗するようなら、リモート側での PATH の設定に失敗している。というか、うちの Mac mini Server ではこうなった。一方、MacBook をリモート側にするとこのエラーが出ない。clone に成功する。その原因を探るのに、2〜3時間かかってしまった。

リモートのシェルでの PATH の設定にはいろいろな要素がからむ。以下は、うちの Mac mini Server の場合の原因だ。同じ症状だったとしても、これがあてはまらない場合もある。自分にとっての記録と、誰かの参考のために残しておく。

MacPorts を使って Git をインストールした場合、(標準では)コマンド群が置かれるのは /opt/local/bin になる。MacPorts そのものをインストールしたときに、この場所が PATH に足されるよう設定ファイルが変更されるのだが、場合によっては(例: インストール後にログインシェルを変更した)この設定が有効にならないことがある。

MacPorts のインストーラは、その最終段階で .profile または .tcshrc を変更するようだ。うちの Mac たちのシェルは tcsh に変更してあるので、以下の記述は tcsh の場合のみにあてはまる。.tcshrc ではこんな行が追加される。

# MacPorts Installer addition on 2009-10-25_at_13:33:42: adding an appropriate PATH variable for use with MacPorts.
setenv PATH /opt/local/bin:/opt/local/sbin:$PATH
# Finished adapting your PATH environment variable for use with MacPorts.

これらの行がない場合(肝心なのは setenv の行、他はコメント)、MacPorts のコマンド群はすべて見つからない。ところで、PATH の設定は他にも方法がある。ログインシェルなら .tcshrc の後、.login も読まれるため、そちらで設定することもできる(というか、わたしはそうしていた)。つまり、.tcshrc 以外の方法で PATH を設定していた場合、対話的にターミナルから使う場合には問題なくコマンドが見つかるのに、対話的じゃないとき(つまりリモートシェルのような場合)には、コマンドが見つからず失敗する、という現象が起きる。

原因がわかれば対処できる。単純に、Mac mini Server の .tcshrcで↑に挙げた PATH の設定の行を追加するだけ。たった 1 行の追加だ。実は、ここに至るまで色々と試行錯誤を経たのだけど、この解決策がもっともシンプルなのでこれを採用。

clone する

実は SSH をプロトコルにする場合、以上でリモート側の設定は完了。後はコマンドを叩くだけ。こんな風になる。

[foo:~] % git clone bar.local:projects/greeting
Initialized empty Git repository in /Users/baz/tmp/greeting/.git/
remote: Counting objects: 16, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 16 (delta 2), reused 0 (delta 0)
Receiving objects: 100% (16/16), done.
Resolving deltas: 100% (2/2), done.

まとめ

さて、今回はここまで。Git の話題というよりは、MacPorts と SSH の話になってしまった。

この先、リモートのリポジトリに push したり、pull してきたり、実際に使う場合にはいろいろと覚えなきゃならないことがある。単にコマンドを覚えるだけでなく、どういった運用にするのかも考えなきゃならない。

想定しているシナリオは、普段デスクトップで作業をしていて、出張だとか何かで部屋やオフィスを出なればならないとき、ノートブックにデスクトップから clone して作業環境を持っていく、というもの。出先での作業の記録はノートブックのリポジトリに commit しておき、戻ってからデスクトップに push する。

何もリポジトリを分散させなくても、SD カードや USB メモリといったリムーバブルメディアにリポジトリを構築すれば、上記のようなシナリオには十分に対応できる。この方法なら Subversion のような集中リポジトリタイプの VCS でも可能。好みの問題だ。集中と分散、どっちが好きか。

上にも書いたが、SSH を使わず Git オリジナルのプロトコルを使う方法もある。そちらについては、また別の機会に書くつもり。調べたいことがまだ残っているので。

参照情報

関連記事

2009-11-08

平等分散リポジトリの見せる夢

はじめての Git

LOG+REPOのテンプレートや素材、そして記事を保全するために Git で管理することにした。まずは「入門git」の第三章、「最初のプロジェクトを作る」に書かれた手順を追ってみた。

git init がすべての始まり。CVS や Subversion とは違い、中央リポジトリは存在しない。昨日までの作業場所がそのままリポジトリの置き場所にもなる(↓)。

(入門git; p.25)
Git で自分のリポジトリがあるのは、自分の作業ツリーとまったく同じ場所にある .git ディレクトリの中だ。

ファイルを作ったら git add、そして git commit。変更しても git add、そして git commit。さっき何を変更したかを忘れたら git status。これまでにどんな変更をしたかを思い出したければ git log。詳細な差分が知りたくなったら git diff

日常のサイクルを思い出すには Git早見表の "Commands Sequence" が最適。

Git は RCS っぽい

CVS や Subversion を一から導入するのはかなりハードルが高い。ソフトウェアのインストールのことではない。今時の有名なソフトウェアのインストールはとても簡単 (Git もそうだった)。よほどマイナーなプラットフォームにこだわっていない限り、迷うことはほとんどない。大変なのは、実際にプロジェクトをバージョン管理ソフト(以下、VCS)の管理下に置く作業の方だ。こっちには途方に暮れる点が少なくない。

何よりリポジトリをどこに置くかで迷う。ローカルなマシンに置くのか、ネットワーク上の共有フォルダに置くのか。ネット上に置くなら、むしろ VCS をサーバとして動かすべきじゃないのか。いっそのこと、Google に頼むか。・・・などなど。

慣れているなら迷わない。けれど、最初にこれをやるのはかなりハードだ。失敗してしまえば(後からもっと良い方法を思いついたら)、やり直しはメンドウ。そう思うと、ますます指が動かなくなる。

その点、作業場所がそのままリポジトリだという Git の方法は迷いがない。思い立ったら、ただ git init と叩くだけでいい。「やっぱ、や〜めた」となれば、rm -rf .git で、キレイさっぱり忘れてしまえる。

ふと思った。「あ、これって、RCS と同じ感覚だ。」

RCS は、もうずっと以前に unix 界隈でメジャーだった VCS (→ Wikipedia:Revision_Control_System)。そんなの聞いたことないや、っていう人はターミナルを開いて /usr/bin あたりを見てみるといい。ci とか co というコマンドが見つかるはずだ。少なくとも Snow Leopard には入ってる (Xcode と一緒に来たのかもしれない)。

RCS は、基本的に個人の作業成果を管理するためのシステムだ。独立したリポジトリの概念はなく、作業場所がリポジトリも兼ねる (ディレクトリごとに RCS ディレクトリを作れば、そこがリポジトリになる)。だから、チームで作業するようなプロジェクトには向かない。

個人からチームへ

ソフトウェアの規模が増大するにつれて、ソフトウェア開発の主役は個人からチームに移っていった。VCS にもチームでの作業を前提とした機能が求められた。CVS の誕生だ(→ Wikipedia:Concurrent_Versions_System)。CVS の始まりは RCS への不満だったという。RCS をベースにして、そこに不足している機能を付け加える方法で開発が進められた。いつしか RCS への依存もなくなり独立した VCS として、オープンソースソフトウェアプロジェクトを中心に広く使われるようになった。

一方で、ソフトウェア開発は複雑化の一途をたどった。チームメンバーの増加、地理的分散、増大するリリース作業の負担。プロジェクトインフラとしての VCS には、大規模かつ複雑なプロジェクトをサポートする機能が求めらるようになった。つまり、CVS にも機能不足と呼ばれるときが来たのだ。

(Subversion実践入門 第2版;p.6 - 7)
Subversion のプロジェクトは、CVS に精通した開発者のチームによって開始された。(・・・中略・・・) 彼らは CVS が既に古くなりつつあることを感じて、それに代わるツールを開発すべき時が訪ずれたと判断したのだ。Subversion の開発者たちには CVS の短所が痛いほど分かっていたので、彼らは高性能で現代的なバージョン管理システムを設計することに特に重点を置いた。

集中から分散へ

リポジトリを集中させるか、または分散させるか。分散させ、かつどこかにマスターを置くハイブリッド型か。これらはスタイルの違いであり、どれが優れていて何が劣っているというものではない。プロジェクトとチームの特性に応じて適切なものを選択するのが賢いやり方だ。

だから、Git が現状(2009年末時点)で最高の VCS であり、他の VCS を使うことなど考えられない、などと言うつもりはない。しかし、個人が自分自身の活動を管理するために使うとしたら、Git のような分散タイプ、それもリポジトリ間に優劣の差(マスター/スレーブ)がない平等分散リポジトリタイプをサポートするものが良い。他の分散 VCS も「平等分散リポジトリ」をサポートするなら、あとは好みの問題だ。

個人の復権

GitHubの登場はコミッタを特権階級から追い落とす革命だった - Hello, world! - s21g

かつてはメンテナやコミッタが専権的にソフトウェア開発の決定権を握っていた構造が、Git/GitHubの登場によって、気がつかないうちに崩れ去っている。これはソフトウェア開発史上、非常に大きな出来事なんだろう

不思議なものでオープンなはずの、オープンソースソフトウェアでは↑のような状況が存在するのだという。一方で、クローズドな環境である企業の開発現場では、リポジトリの管理(昔はライブラリアンと呼ばれた)はメンドウなだけの労働であることが多い。誰も進んでやりたがる業務じゃない。そこでは管理者(マネージャじゃないよ、英語でいうならアドミニストレータ)は特権階級なんかじゃない。むしろ下働きだ。誰かがやらないといけない作業、大事なんだけど報われることの少ないロール。

オープンソースソフトウェアのプロジェクトにおいて、リポジトリに対する権限が開発者間に階級を生んでいるのだとしたら、そしてそれが開発者の間に感情の軋轢を生じさせるのならば、それはプロジェクトの特性に適していない管理方式なのだ。その場合、Git のような分散かつ平等なリポジトリを持つシステムは救いになる。

皆が自分のリポジトリを持ち、誰もマスターではなく、またスレーブでもない。ソースコードはブランチすることが前提で、世界中にさまざまな変種が存在する。誰もが自由にプッシュでき、誰もが自由にマージできる。ソフトウェアを中央のコミッタがデザインするのではく、個々のプログラマが自らの用途に合わせ、思うままにアレンジできる。何が正しくて何が間違っているのか、プログラマ自身が決めることができる。個人としてのプログラマの復権だ。

あとひとつ。Git のもたらすこのビジョンこそ、ソフトウェアの再利用というプログラマの(古くからの)夢を実現するものじゃないだろうか。再利用すべきはバイナリじゃない。ソースコードだ。皆がリポジトリを持つことで初めてそれが可能になる。

2009-11-07

Google Reader がウェブクリップに使える件

毎日使うサービス(ツール)でありながら、今日まで気付かなかった。 Google Reader でウェブクリップができる。なんというか便利だ。

準備編

Google Reader を開き、左上のメニュー(?)から「共有アイテム」を選択する。これで右側のメインエリアが共有アイテム一覧の表示に変わる。

このとき、共有アイテム一覧の上にユーザのプロフィールの内容などが表示されているが、その右に「Google リーダーでコメント」というボタンが置かれている。うっかりすると見落としがちだが、これが今回の記事の主役だ。

このボタンを説明文の通り、ブックマークバーにドラッグしておく。これで準備完了。

実践編

では、実際にクリップしてみよう。

クリップしたいウェブページを開いて、クリップしたい領域を選択する。画像がふくまれていても OK。続いて、ブックマークバーの「Google リーダーでコメント」ボタンを押す。ウィンドウが開いてコメントを入力できる。「Post Item」ボタンを押して完了。

デフォルトではコメントを Google Reader で共有するようになっているが、コメント入力ウィンドウでチェックボックスを外せば、自分だけのメモとしても使える。

試しに、Apple のサイトから MacBook のページをクリップしてみた。それを Google Reader で開いたものがこれ。レイアウトまでは再現できないけど、画像もふくめて取り込めているのがわかる。

もちろん、Google だからクリップした記事を検索できる。Google Reader 内の検索ボックスを使えば OK。クリップしたテキストはもちろんのこと、コメント部分もきちんと探してくれる。

考察編

Google Reader にウェブページのクリップを取り込めることの、どこがウレシイのだろう? それはウェブで収集する情報を一カ所に集められる、という点だ。

わたしの場合、ネット上の情報収集の主要な部分は Google Reader を使った RSSフィード経由の活動になっている。後からゆっくり読もう、もう一度読みたい、そういうアイテムには「☆」をつける。他の誰かに伝えたいと思ったら「共有」だ。Google Reader はウェブ上のサービスだから、場所も端末も選ばない。Mac mini でも MacBook でも、iPhone でさえも同じ「情報の集積所」を見ることができる。

ただ、ネットのすべての情報を RSS フィード経由で得られるわけじゃない。実際、わたしも一部はニュースサイトや何かを見て回る。そういうときに見つけた情報を保管しておきたければブックマークかウェブクリップになる。気になる箇所を明確にできることからブックマークよりもウェブクリップの方を使うようになってきた。このウェブクリップを Google Reader に集約することができれば、Google Reader がウェブから集めたすべての情報の倉庫になる。

Evernote や、かつての Google Notebook のように、ノート(メモ)アプリにウェブクリップ機能を取り込んだものは多い。しかし、RSS リーダーに組込むという発想はなかった。だから、今日まで気付かなかった。この「Google リーダーでコメント」ボタンは何度も目にしていたのに。

なんにせよ、Google Reader すごいわ。もう、なんていうか、Google、バンザイ!

関連リンク