dabbrev-expand-multiple による動的略語展開

この週末に tokyo-emacs なんていう勉強会があったんですね。完全にノーチェックでした。もし次回があったら参加したいのですが、あるのかな… (追記:あるみたいです。次回は絶対参加しよう。)

せっかくなので、 Emacs についてなんか書いてみることにします。僕は単語の補完に dabbrev-expand-multiple を愛用しています。動的略語展開の候補を tooltip もしくはインラインで複数表示してくれるものです。単語を途中まで入力して、 M-/ を押すと補完してくれるのですが、ここでさらに / を押すと他の候補一覧がツールチップで表示されます。で、それらの候補は SKK 風に a,s,d,f,g で選択することができます。

こういうのは実際に使ってみないと便利さがなかなか伝わらないのですが、おすすめ。

;; dabbrev-expand-multiple
(require 'dabbrev-expand-multiple)
(global-set-key "\M-/" 'dabbrev-expand-multiple)

;; 補完候補を一度に5つにする
(setq dabbrev-expand-multiple-select-keys '("a" "s" "d" "f" "g"))
;; 複数候補表示に移るキーに / を足す
(add-to-list 'dabbrev-expand-multiple-multi-selection-keys "/")
;; 複数候補表示時に次の候補表示に使用するキーに n を足す
(add-to-list 'dabbrev-expand-multiple-next-keys "n")
;; 複数候補表示時に前の候補表示に使用するキーに p を足す
(add-to-list 'dabbrev-expand-multiple-previous-keys "p")
;; ツールチップを表示する秒数
(setq dabbrev-expand-multiple-tooltip-timeout 2000)
;; 10秒で消えるように設定する
(setq dabbrev-expand-multiple-tooltip-timeout 10)
;; 最初に展開した文字列に highlight をかける.
(setq dabbrev-expand-multiple-highlight-face 'highlight)
;; インライン表示のときに使用するフェイス.
(setq dabbrev-expand-multiple-inline-show-face 'underline)
;; インライン表示の見た目の変更 (アンダーラインをなしにする)
(setq dabbrev-expand-multiple-inline-show-face nil)

関連リンク:
» anything.el が手放せなくなった
» emacs-snapshot-gtk

WaterMark System Information

最近はだいぶ暑くなってきて、PCの温度が気になるようになりました。そんな人には、 WaterMark System Information がお勧めです。CPU負荷の他に、メモリ使用量、CPU温度、ファン回転数、HDD温度などをまとめて監視できます。

Android 勉強会 第4回に参加してきました

6月16日に秋葉原ダイビルで開催された「Android勉強会 第4回」に参加してきました。定員を大きく超える応募があったそうで、抽選に当選して何とか参加することができました。副都心線の影響(?)で少し遅れて会場に到着したため、既に席はほとんど埋まっていて100人くらいはいたんじゃないかと思います。

Google I/O, Developer Day ともに参加したのですが、 Android のセッションにはほとんど出なかったので、安藤恐竜さんのプレゼンはかなり参考になりました。それから、やはり動いている実機でプレゼンというのはインパクトがありますね。懇親会にも参加させてもらったのですが、いろいろなメーカーやゲーム業界の人などもいて楽しかったです。Android については、単に携帯電話のプラットフォームと捉えていると判断を誤りそうな感じがします。

ブリリアントサービス 近藤さん

  • Armadilloの実機でAndroidを動かして、自作アプリケーションでプレゼン!
  • Androidデバイスが巷に溢れるはず
  • 一年後がどうなっているかは想像が付かない(いい意味で)
  • メモリ64MBでは厳しいのではないか?
  • サウンドは? - 鳴ります。PCM 48kHz,ALSA
  • 3Dアクセラレーション対応ボードを買えばもっと性能が出るかも

日立ソフトさん

  • モバイルこそセキュリティが重要 → SELinux
  • 実際にlibpngの脆弱性があった
  • カーネルの対応、ユーザランドの移植、セキュリティポリシーの準備が必要
  • 組み込み用でも数万ルールの設定が必要
  • カーネルのチューニングをして、500kbyte以内に抑えている
  • SELinux Policy Editorオープンソースで公開している
  • Android on Zaurus SL-C3200
  • privateとbusinessのセキュリティ権限設定の確認

安藤恐竜さん

  • Binder:
    shared memory方式によるパフォーマンス改善
    プロセス単位のスレッドプール
  • Power Management:
    バッテリーが最大のボトルネック
    Linux PMの上に拡張
    FULL_WAKE_LOCK(cpu,lcd),PARTIAL_WAKE_LOCK(cpu)
  • Bionic:
    カスタマイズされたlibc、組み込み用に最適化
    BSDライセンス(GPLの混入を嫌がった?)
    pthread, setprop/getprop
    POSIX完全準拠ではない
    glibc互換ではない
  • HAL:
    上位層をハードウェアから分離
    pmap
  • Dalvik:
    200-500MhzのCPU
    RAM 64MB ROM 64MB
    バッテリー
  • Dexファイルの構造:
    データをタイプごとに整理
    データにidを付けてポインタのみ上部に格納
    ファイルサイズをjarの半分以下に
  • Zygote:
    ダーティーでシェアードメモリ
    クラスをプリロードし初期化
  • Dalvikはレジスタマシン、通常のJava VMはスタックマシン
  • Androidアプリを開発する上での心得:
    賢くループ
    先にlimitを計算しておく
    CPUとメモリはボトルネックではない、バッテリーがボトルネック
    バッテリーにムーアの法則は成り立たない

IIIMECF + ATOK X3 を Emacs の日本語入力に使う

僕は、emacs-snapshot-gtk をメインのエディタとして使っています。そのままでも日本語入力はできるのですが、入力時のフォントがどうしても気に入らないので、 Emacs では IIIMECF を使って、IIIMサーバと直接通信するようにしています。

インストール方法

IIIMECF-0.75.tar.gz (2007/1/10)
$ tar zxvf IIIMECF-0.75.tar.gz
$ cd iiimecf
$ emacs -q --no-site-file -batch -l iiimcf-comp.el
# mkdir /usr/share/emacs/site-lisp/IIIMECF
# cp lisp/* /usr/share/emacs/site-lisp/IIIMECF

.emacs の設定

UNIXソケットのデフォルトは、 /tmp/.iiim-username/:1.0 のようですが、自分の場合は :0.0 だったので次のように設定しています。これで Shift+space で IIIMECF 経由で ATOK が利用可能です。

;; iiimecf
(setq iiimcf-server-control-hostlist (list
          (concat "/tmp/.iiim-" (user-login-name) "/:0.0")))
(setq iiimcf-server-control-default-language "ja")
(setq iiimcf-server-control-default-input-method "atokx3")
(setq default-input-method 'iiim-server-control)
(require 'iiimcf-sc)
(global-set-key [?\S-\ ] 'toggle-input-method)

GNOMEランチャの設定

emacs 起動時の環境変数に XMODIFIERS="@im=none" を渡すようにします。GNOMEのランチャから起動する場合は、次のように設定すればOKです。

env XMODIFIERS="@im=none" emacs-snapshot-gtk

OAuth Consumer Request の処理フローと実装

OpenSocial の RESTful API では、OAuth を利用して権限の確認を行います。ただし、コンシューマが完全にユーザに成り代わって処理をするため、コンシューマとプロバイダ二者間の信任フロー(2-legged OAuth)になります。この方法については、まだドラフト段階ですが次の文書に記されています。

» OAuth Consumer Request 1.0 Draft 1

処理フローを以下に説明します。コンシューマは次のパラメータをプロバイダに送信することになります。

oauth_consumer_keyコンシューマキー
oauth_signature_methodHMAC-SHA1
oauth_signatureシグニチャ
oauth_timestampUNIXタイムスタンプ
oauth_nonceランダムな文字列
oauth_version1.0 (オプション)

ここで、 oauth_signature は以下のようにして生成されます。まず、ベース文字列を生成するために次の値を用意します。

  1. GET
  2. http://provider.example.net/profile
  3. oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=kllo9940pd9333jh&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1191242096&oauth_version=1.0

これらをURIエスケープした後に & で連結して、ベース文字列を生成します。

GET&http%3A%2F%2Fprovider.example.net%2Fprofile&oauth_consumer_key%3D
dpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method
%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_version%3D1.0

そして、このベース文字列を HMAC-SHA1 によってダイジェスト値を生成し、BASE64 でエンコードすることによってシグニチャが生成されます。この際、利用する共有キーは cosumer_secret と 空のToken Secret を & で連結したものになります。例えば、 consumer_secret が kd94hf93k423kf44 なら kd94hf93k423kf44& になります(Token Secretは空のため)。こうして、ダイジェスト値は以下のようになります。

SGtGiOrgTGF5Dd4RUMguopweOSU=

こうして生成されたパラメータをリクエスト時の Authorization ヘッダに付加します。プロバイダ側でも同様にダイジェスト値を生成し、シグニチャが合っていればプロバイダが持つリソースへのアクセスを許可します。また、タイムスタンプが5分以上前の場合にはエラーとすることで、リクエストURLが漏れた場合でもセキュリティを確保しています。

Authorization: OAuth realm="http://provider.example.net/",
               oauth_consumer_key="dpf43f3p2l4k3l03",
               oauth_signature_method="HMAC-SHA1",
               oauth_signature="SGtGiOrgTGF5Dd4RUMguopweOSU%3D",
               oauth_timestamp="1191242096",
               oauth_nonce="kllo9940pd9333jh",
               oauth_version="1.0"

さて、以上の処理を Django で実装してみました。コンシューマ側は、普通のPythonスクリプトですので、コンソールから実行することができます。

プロバイダ側

import oauth
from django.shortcuts import *

class MockOAuthDataStore(oauth.OAuthDataStore):
    def __init__(self):
        self.consumer = oauth.OAuthConsumer('key', 'secret')
        self.nonce = 'nonce'

    def lookup_consumer(self, key):
        if key == self.consumer.key:
            return self.consumer
        return None

    def lookup_nonce(self, oauth_consumer, oauth_token, nonce):
        return None

def auth_test(req):
    os = oauth.OAuthServer(MockOAuthDataStore())
    os.add_signature_method(oauth.OAuthSignatureMethod_HMAC_SHA1())

    # build from request
    base_url = req.is_secure() and 'https://' or 'http://' + req.get_host()
    try:
        os.oauth_request = oauth.OAuthRequest.from_request(
            req.method,
            base_url + req.path,
            headers={'Authorization': req.META.get('HTTP_AUTHORIZATION')},
        )

        consumer, token, params = os.verify_request(os.oauth_request)
    except oauth.OAuthError, err:
        return HttpResponse(err.message, status=401)

    return HttpResponse('OK!')

コンシューマ側

import oauth
import urllib2

CONSUMER_KEY = 'key'
CONSUMER_SECRET = 'secret'

def oauth_request(method, url, parameters=None):
    consumer = oauth.OAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET)
    signature_method_hmac_sha1 = oauth.OAuthSignatureMethod_HMAC_SHA1()

    # access protected resources
    oauth_request = oauth.OAuthRequest.from_consumer_and_token(
	                consumer,
			token=None,
			http_method=method,

			http_url=url,
			parameters=parameters)
    oauth_request.sign_request(signature_method_hmac_sha1, consumer, '')

    headers = oauth_request.to_header()
    
    r = urllib2.Request(url, headers=headers)

    try:
        print urllib2.urlopen(r).read()
    except urllib2.HTTPError, e:
        print e

if __name__ == '__main__':
  oauth_request('GET', 'http://localhost:8080/auth_test/')

Leah Culverさんが書いたOAuthライブラリを利用しているのですが、空の Token だとエラーになるので、一箇所だけソースに手を加えています。

--- oauth.py.org   2008-06-14 11:52:33.000000000 +0900
+++ oauth.py       2008-06-14 12:01:44.000000000 +0900
@@ -311,7 +311,10 @@
         version = self._get_version(oauth_request)
         consumer = self._get_consumer(oauth_request)
         # get the access token
-        token = self._get_token(oauth_request, 'access')
+        try:
+            token = self._get_token(oauth_request, 'access')
+        except:
+            token = ''
         self._check_signature(oauth_request, consumer, token)
         parameters = oauth_request.get_nonoauth_parameters()
         return consumer, token, parameters

アルカトラズ島

サンフランシスコ湾に浮かぶアルカトラズ島(Google Maps)は別名「ザ・ロック」と呼ばれ,連邦刑務所があったことで有名。アル・カポネも服役していた。脱獄不可能といわれていたが,1962年に通気口を使った脱獄が敢行され,この刑務所は翌年にロバート・ケネディの命令で閉鎖された。この脱獄劇は,クリント・イーストウッド主演の「アルカトラズからの脱出」という映画になっている。インディアンによって占領されていた時期もあって,壁にはその名残のメッセージも見ることができる。

prison  Al Capone  ceiling  ceiling  Administration building  Indian's message  Alcatraz  Escape from Alcatraz

アルカトラズ島へは船で行く必要があるのですが,けっこう人気らしいので前もって公式サイトで予約して行った方がいいです。本当は9:30出航の船を予約していたのですが,9:00のに乗せてもらえました。アルカトラズ島ツアーなるものもあるようですが,もともと無料で日本語の音声ガイド機を借りられるので,手数料を取られるだけ損かと。
この音声ガイドは,服役囚や看守が登場したり,ストーリー仕立てになっていてかなり楽しいです。よくある再現ドラマののりで,声優さんがアル・カポネとかになりきって説明してくれます。

Google I/O 翌日

Google I/O の翌日は,あんどうさん佐々木さんと一緒にある場所へと向かいました。レンタカーを借りて,初めてアメリカで運転しました。カリフォルニア州では,国際免許証が無くても日本の免許証で運転できるそうです。右側通行は30分くらいあれば慣れる,と誰かが言っていたけど,全然慣れませんでした。無事に帰って来れて良かった…

Wi-Fi at Mountain view GPS Navigation  Freeway Exit 

どこに行ったかについては,ブログに書いてはいけないことになっているので,ご想像にお任せします。

関連リンク:
TIME: Life in the Googleplex Photo Essay

Google I/O 第2日目

Google I/O の第2日目は,特に集合したりはせず,一人で会場に行って朝食を取りました。下の写真のようなビュッフェ形式の朝食でなかなか美味しかったです。

Google I/O Lobby  Breakfast

ここで,たまたま隣に座った人と話をしたのですが,彼はサンフランシスコのエンジニアで,これから OpenSocial 関連のプロジェクトを立ち上げたいと言っていました。また,JavaScript に関して,僕は jQuery がお気に入りだという話をしたのですが,彼は jQuery を知らないようで,「何だそれ。何がいいんだ?僕はDojoを使っているよ。」と言っていました。jQuery のすばらしい点を説明しておいたんだけど,うまく伝わったかなぁ…
他に何人かと話した感じでは,日本ではあまり話題に上らない OpenSocial の動向について,こちらでは多くの人が注目しているようです。それと LinkedIn の評価が高いようで,彼らはスマートだと口々に言っていました。

Marissa Mayer
Keynote from Marissa Mayer at Google I/O 2008
Photo by jwowens

この日のキーノートは,副社長の Marissa Mayer さんでした。とても美しい女性で鵜飼さんによると,新しいプロダクトは必ずこの人の承認を受けなければならないとか。彼女については,a2cさんがブログにまとめているので参考にしてください。全く持って同感です!「マリッサは大変なものを盗んでいきました」 後から聞いたら,自分と同い年だそうで,軽くショックを受けました。

少しだけ僕が分かった範囲で補足しておくと,Google Products の UI について語っていました。"Split A/B Testing"の手法を使って,ユーザごとに微妙に異なるデザインのページを表示して変化を調べているそうです。サンプルとして挙げていた検索結果ページのデザインの場合だと,微妙にロゴの周りのスペースが違うだけなのですが,このレベルでテストを行っているようです。また,検索トップページを作ったのはセルゲイ・ブリンで,彼に聞いたら "We didn't have a Webmaster, and I don't do HTML." (参考)と答えたそうです。会場は爆笑。

Even Faster Web Sites by Steve Souders

Steve Souders

キーノートの後は,『ハイパフォーマンスWebサイト』の著者で,YSlow を作った Steve Souders のセッションを聞きました。なるほど,この人,Yahoo! から Google に転職してたんですね。会場に対する「みんな YSlow を使っているかい?」との問いかけに,20%くらいの人しか手をあげていなかったのが意外でした。 YSlow は全人類が使うべきだと思います。

内容については,箇条書きで申し訳ないですが,次のような感じでした。 Facebook を名指しでパフォーマンスが悪いサイトの例に出していたのに驚きました。さすがアメリカ。

  • iGoogle ではほとんどページのレンダリングに時間がかかっている
  • empty cache と prime cache の違いを知る
  • Google と LiveSearch は 0% になる
  • 80-90% はフロントエンドにかかっている
  • Facebook はほとんどスクリプトの読み込み。ひどい
  • JavaScript のブロックを回避することが重要
  • cuzillion ← Webページ構造によるパフォーマンス・テストツール。これ面白い!
  • スクリプトはレンダリングに必要なものとそれ以外を分けるべき
  • MSN はスクリプトを動的に挿入してパラレル読み込みを実現している
  • evalよりscript挿入の方がいいよ
  • <script defer> IE only, different domain
  • document.write only IE パラレル
  • パフォーマンス測定には IBM Page Detaierを使っていた
  • 実行順序とインジケーターで切り分けを行う
  • don't scatter inline scripts

OpenSocial

OpenSocial に関するセッションも slide.com の人のプレゼンなどいくつか聞いたのですが,残念ながら,あまりピンと来るものはありませんでした。一応,こちらもメモ程度のものをあげておきます。以前からブログを読ませて頂いていたえーじさんと,こちらで初めて会うことができた(Twitterのおかげ)のですが,やっぱり目新しい情報はあまり無かったと言っていました。OpenSocial に対する日本とは違った盛り上がり方を肌で感じることができたのが一番の収穫かなと思います。

  • lane liabraaten's opensocial - appengine
  • save users from re-registration hell
  • ユーザは,どのSNSにするか選ぶ必要がない
  • 適用範囲はSNSだけじゃないよ
    • profiles,homepage
    • personal dashbords
    • site based social object
    • corporate CRM systems
    • aay web site
  • profile pages - owner,
    home pages - owner is viewer (must be logged in)
    のパターンで表現できる
  • viewer friends are your firend to visit the web site
  • 言語には依存しない Pythonも歓迎
  • socialsite by SUN (powered by shindig)
  • Orkut, Myspace, hi5, Netlog open to 200M useres now
  • container to containerの通信はRESTful APIで実現可能になる

発表の中にFacebookの話題が全く出てこなくて,質問タイムに誰かが「Facebook?」と質問していたのですが,スピーカーの人の答えは「Next questions.」のみ。これには会場の皆も苦笑い。後から少し補足はしていましたが。
Plaxo の Joseph Smarr 氏のプレゼンは,別のを聞きに行っていて見逃しました。えーじさんによると,これは面白かったそう。残念ですが,a2cさんのブログに YouTube とスライドのリンクがあるので,後で見ようと思います。

# MySQL のことをみんな「マイシーケル」って呼んでいた。