E4X 話 in Mozilla Party2007年04月20日 00時31分

ここでの告知がぎりぎりになりましたが、明日 4 月 21 日の Mozilla Party JP 8.0 に、講師として参加します。話す内容は E4X について。……ええ、かぶってますね、思いっきり……「えへへうふふ E4X」と……。いや、Shibuya.es の告知を見たときに、これはまずいと思ったんですけどね……、それ以外に話すネタも思い浮かばずに……。まあ復習にはぴったりということで。Firefox に特化した話もちょっと出てきますし。

そんな程度の話ですが、既に私の頭は「みんなジャガイモ」(© 広末涼子) 祭りの結果、逆にパニックを起こしそうなので、生暖かい目で見守ってくださると幸いです。それから、質問意見文句は大歓迎! むしろ 25 分間それで埋めてもいいくらいです。

E4X in Firefox 発表資料2007年04月22日 20時11分

Mozilla Party JP 8.0 に講師として参加させていただきました。以下はプレゼンテーション用のスライドです。

OnpenOffice.org 2.0 の Impress を使って作ったのですが、私のノート PC のディスプレイ接続がうまくいかず、お借りしたマシンに入っていた OpenOffice.org 2.1/2.2 ではなぜか実行途中にフリーズするので、PDF にエクスポートしたものを用いました。

また、発表は 25 分の枠だったのですが、最初に練習したときは 1 時間かかってしまい、話す内容をいろいろと削ったものの、結局枠ぎりぎりまで使い切ってしまって、質疑応答の時間をとることができませんでした。もし何か聞きたいことがあったという方がいらっしゃれば、このコメント欄にお願いします。

それから、発表中に話したこともそうでないことも含め、上記のスライドに関する補足をいくつか挙げておきます。

XML 型と XMLList 型の相互変換に関して、1 項目の XMLList が XML として扱えるだけでなく、XML が 1 項目のみを含む XMLList として扱われる場合もあります。
XML 名前空間
:: の前に指定した変数は、その文字列化した値が使われます。ですから、名前空間 URI を扱うだけなら、ns = "http://example.org/" のように、Namespace オブジェクトを使わなくともかまいません。ただし、名前空間接頭辞の情報も保持したいといったときは、Namespace オブジェクトを使う必要があります。
SpiderMonkey による拡張
XML/XMLList 型は [[Get]]/[[Put]] といった内部メソッドが上書きされています。これにより、存在しないプロパティ名が指定されたとき、プロトタイプチェーンをたどるのではなく、空 XMLList を返すといった動作が実現されます。しかし、function 名前空間を使うことで、通常のオブジェクトと同じく、プロパティの検索にプロトタイプチェーンを使うといった動作にすることができます。
スコープチェーン上に XML オブジェクト x がある状態で式 method() を評価したとき、ECMAScript ではスコープチェーンを順にたどり、method という名前のプロパティを持つオブジェクトを探します。しかし、x が method という名前の子要素を持っていなければ、x は method という名前のプロパティを持たないことになってしまいます。そのため、list.(method()) では期待通りに動かない場合があります。
AttributeName コンストラクタに指定可能な引数は、QName コンストラクタに指定可能なものと同じです。
SpiderMonkey のバグ (1)

関数内でデフォルト名前空間を指定した場合、非修飾名を解決するのにデフォルト名前空間が使われない場合があります。たとえば、以下のコードでは "Default Namespace" と表示されるはずですが、"No Namespace" と表示されてしまいます。

var ns = new Namespace("http://example.org/");
(function () {
  default xml namespace = ns;
  var x = <a>
    <b>Default Namespace</b>
    <b xmlns="">No Namespace</b>
  </a>;
  print(x.b); // No Namespace
})();

この問題は、スコープチェーンを深くすることにより解決できます。

(function () {
  ...
  with ({}) print(x.b); // Default Namespace
})();
(function () {
  ...
  (function () { print(x.b); })(); // Default Namespace
})();

また、スコープチェーンを深くする操作があれば、それが非修飾名によるプロパティアクセスのあとであっても、解決することがあります。

(function () {
  ...
  print(x.b); // Default Namespace
  with ({});
})();
SpiderMonkey のバグ (2)
for-in 文、for-each-in 文を XML オブジェクトに対して使用すると、その XML オブジェクトは XMLList に変換されます。ですから、変換された XMLList が唯一持つプロパティ、すなわち元の XML オブジェクトそのもののみが列挙されるはずです。しかし、SpiderMonkey は誤って、XML オブジェクトが持つプロパティ、すなわちその XML の子ノードを列挙してしまいます。
DOM との変換
XMLSerializer はコンストラクタ名こそ XMLSerializer ですが、実装するインターフェース名は nsIDOMSerializer です。XPCOM コンポーネントとして呼び出すときなどには注意してください。
DOM ノードから E4X XML オブジェクトに変換するコードに関して、実際には node が文書ノードなら、そのルート要素に対して XMLSerializer を適用するなどの工夫が必要です。また、XMLSerializer は DocumentFragment にも対応しているので、XMLList コンストラクタを使うことで、DocumentFragment から XMLList への変換もできるようになります。
使用例 (2)
実際に Google カレンダーのフィードをパースするソースコードHTML エクスポートを行うソースコードをご覧ください。
ヒアドキュメントとしての使用に関して、XMLList リテラルを使えば式の埋め込みが簡単にできます。また、CDATA セクションリテラルを使うと、小なり記号 (<) やアンパサンド (&) 、開き波括弧 ({) などをエスケープする必要がなくなります。
資料
cho45 さんの「えへへうふふ E4X」が参考になります。また、ActionScript に関する Web ページで E4X について触れているものもあります。

「使用例 (1)」で述べた、Greasemonkey 用スクリプトと userChrome.js 用スクリプトの例を以下に置きます。

Greasemonkey 用スクリプト (スクリーンショットソース)
閲覧中のページに対するはてなブックマークでのコメントを表示します。さらに、ブックマーク数におけるコメントつきブックマーク数の割合を、SVG を用いてグラフ描画します。
E4X による要素の作成、XML オブジェクトから DOM ノードに変換する xml2dom 関数の実装など。
worris さんの「はてなブックマークコメントビューワ」を参考にしました。
userChrome.js 用スクリプト (スクリーンショットソース)
Web 検索バーに入力した文字列を用いて、ページ内検索もできるようにします。
E4X を用いた Overlay ファイルの動的生成、CDATA セクションのリテラル表記を用いたヒアドキュメントの実現など。
Georges-Etienne Legendre さんの SearchWP を参考にしました。

さらに、あとで Piro さんから質問があったので、その概要と回答も載せておきます。(回答はそのとき答えたことに少し付け加えています。)

E4X を使ったときのパフォーマンスはどうなのか?
今回の発表に当たってはパフォーマンスに関して調べていませんが、要素のネストが深くなると文字列化が非常に遅くなるというバグがあります。また、今回示した DOM ノードとの相互変換の手法は文字列を介したもので、DOM ノードと文字列との変換、E4X と文字列との変換がそれぞれ必要になるので、パフォーマンスはあまり良くないと思われます。なお、ヒアドキュメントとしての使用に関しては「えへへうふふ E4X」でも触れられていますが、通常の文字列連結に比べパフォーマンスの点で大きく劣るという結果が出ています。
DOM ノードとの相互変換は Firefox 1.5 でも可能か?
今回示した手法なら Firefox 1.5 から使用可能です。
ヒアドキュメントとして CDATA セクションのリテラル表記を使う際の注意点は?
後方互換性の関係から、XML オプションが有効になっていないと、CDATA セクションリテラルを直に書くことはできません。HTML 中で XML オプションを有効にするためには、<script type="text/javascript; e4x=1"> のように e4x パラメータを 1 にセットするか、<script type="text/javascript; version=1.6"> のように 1.6 以上のバージョンを指定しないといけません。XUL 中または XPCOM コンポーネント中では、最初から XML オプションが有効になっているため、このような指定を明示的に行う必要はありません。また、XML/XMLList リテラル内ならば、XML オプションの状態に関わらず、CDATA セクションを記述することができます。なお、CDATA セクションリテラルの評価結果は、テキストノードを表現する XML オブジェクトとなります。

Google のソフトウェア開発2007年04月29日 19時41分

Google 技術講演会「Developing Software in the Real World」に行ってきました。講演者は Google 東京 R&D センター ソフトウェアエンジニアの南野朋之さん。その 1 週間前に行われた、Mozilla Corporation の Seth BindernagelSeth Spitzer との講演会 (Mozilla Party JP 8.0 とは別物) には参加できなかったので、リベンジ (?) という形になります。

南野さんはインターンを経て Google へ入社、Google マップでの写真表示を開発された方で、今回の公演内容は Google でのソフトウェア開発体制、および Photos on Google Maps 開発の舞台裏に関してでした。

Google でのソフトウェア開発体制

OKR (Objectives and Key Results)
四半期ごとに目標 (長期、短期) を立て、成果を評価する。これが各エンジニア、個別チーム (5 ~ 6 人)、会社などさまざまなレベルで行われる。
百聞はデモに如かず
20% ルールでの成果など、とにかくデモを作る。それに対してチーム内外からフィードバックを受けられる。
Design Doc
実際のコーディングへ移る前に、WhyHow を書いておく。
Weekly Snippets
週ごとに今週すること (したことだったかも) を書いておく。
強大なインフラ
数千台のクラスタ、ペタバイト規模のストレージ、Web データなどを (インターンでも) 自由に扱える。
何でも共有
全ソースコードは全エンジニアに共有される。Design DocWeekly Snippets など、誰が何をしているのかという情報も共有される。

Photos on Google Maps

機能概要
Google マップでお店やホテルを検索した際、その店舗に関する写真をバルーン内に表示する。
最初のアイデア
Web ページ中から住所情報などを元に関連する画像を取得する。
ノイズの除去
複数ページで使われている画像は、サービスのロゴやボタンなどである可能性があるので取り除く。
イメージ検索チームのシステムを利用してポルノ画像を取り除く。
精度の向上
住所情報だけでなく、店舗名とともに使われる特徴的な語も利用する。
デモ
自前の HTTP サーバーと Greasemonkey 用スクリプトでデモを作成。
公開
2007 年 3 月 8 日に公開。海外では Slashdot.org にも取り上げられた (該当するトピックがわかりませんでした) が、日本では反応が薄かった。(私自身気づいてませんでした。m(_ _)m)

質疑応答

Google をやめた人がソースコードを流出させる可能性について
NDA により縛られている。また、Google の社訓 Don't Be Evil には、そのようなマナーに反することをしなくても、良いソフトウェアは作れるという意味もある。さらに、ソースコードが手元にあっても、Google 外でそれを実行するのは難しい (数千大規模のクラスタを用意できないなど)。
Google 内に外部ソースコードが混入する可能性について
ソースコードのライセンス専門の担当者もいるはず。(中国語 IME の辞書問題に関しては残念。)
Google 内で出たアイデアのうち、実際世の中に出るものの割合は?
アイデアだけで終わるものもあるが、いったん走り出せば大体は世に出る。
日本語のメーリングリストもあるのか?
メーリングリストなどはすべて英語。前述の Design DocWeekly Snippets なども英語。
個人情報に関して
通常のエンジニアはユーザーのアクセスログを閲覧できない。Google Suggest の開発など、特殊な場合は契約書にサインした上で閲覧できるが、それでも生の IP アドレスなどは取得できない (ハッシュ化されている)。メールの盗み見はできない。

感想

Google の強みというのは、強大なインフラと、広範囲からのフィードバックにあると感じました。やはり一人で作業していても煮詰まってしまうところ、Google なら共有されたソースコードを参考にすることもできれば、誰が何をしているのかがすぐわかるので専門の人に聞くことも簡単です。それから英語が重要。読み書きだけでなく会話もできないときつそうな雰囲気です。

しかし、いくら Google 内部で情報が共有されているといっても、外から見ればブラックボックスなので、オープンソースソフトウェアとの関係にどう折り合いをつけていくのか疑問が残ります。(このことについて質問しておけばよかった。)