<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.jp/~d/styles/rss2japanesefull.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.jp/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>TKMR.blog</title>
    <link>http://blog.tkmr.org/</link>
    <language>ja</language>
    <description>love okome!!</description>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.jp/tkmr_blog" type="application/rss+xml" /><item>
      <title>MySpaceでOpenSocialアプリケーション "OpenIDクライアント" ー (3)</title>
      <description>&lt;p&gt;前回から引き続き、OpenIDの "関連付け" と OpenSocial の汎用データストレージについて&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.tkmr.org/tatsuya/show/417-myspace-opensocial-openid-1"&gt;MySpaceでOpenSocialアプリケーション "OpenIDクライアント" ー (1)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.tkmr.org/tatsuya/show/418-myspace-opensocial-openid-2"&gt;MySpaceでOpenSocialアプリケーション "OpenIDクライアント" ー (2)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;association（共有鍵の交換）&lt;/h2&gt;
&lt;p&gt;OpenIDのspecでは認証リクエスト前にOpenID認証局と共有鍵の交換を行うことが推奨されている。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lab.koshigoe.jp/en2ja/openid-authentication-2_0.html#associations"&gt;参考：http://lab.koshigoe.jp/en2ja/openid-authentication-2_0.html#associations&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本来、鍵交換には&lt;a href="http://ja.wikipedia.org/wiki/Diffie-Hellman%E9%8D%B5%E5%85%B1%E6%9C%89"&gt;Diffie-Hellman鍵共有アルゴリズム&lt;/a&gt;を利用するべき、と思うけど今回DH鍵交換アルゴリズムを実装するのが目的ではないのでsettion_typeは一番単純な "no-encryption" で実装する。&lt;/p&gt;
&lt;p&gt;なお "no-encryption" の場合SSL（https）で通信するべきとのこと（"no-encryption" association sessions MUST NOT be used unless the messages are using transport layer encryption.）&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p&gt;まずOpenID RPからOPへ association リクエストを投げる、前回のHTMLベース探索と同様に OpenSocial API の makeRequest で通信を行い、認証結果を受け取る。&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;br /&gt;openid.association = function(request_option, callback){&lt;br /&gt;  var &lt;span class="keyword"&gt;self&lt;/span&gt; = this;&lt;br /&gt;  var params = {};&lt;br /&gt;  params.contentType = gadgets.io.ContentType.TEXT;&lt;br /&gt;&lt;br /&gt;  //パラメータをクエリーストリングとして付加しURLを組み立てる&lt;br /&gt;  var param = [];&lt;br /&gt;  param.push([&lt;span class="str"&gt;"openid.ns"&lt;/span&gt;,&lt;span class="str"&gt;"http://specs.openid.net/auth/2.0"&lt;/span&gt;]);&lt;br /&gt;  param.push([&lt;span class="str"&gt;"openid.mode"&lt;/span&gt;, &lt;span class="str"&gt;"associate"&lt;/span&gt;]);&lt;br /&gt;  param.push([&lt;span class="str"&gt;"openid.assoc_type"&lt;/span&gt;, &lt;span class="str"&gt;"HMAC-SHA1"&lt;/span&gt;]);&lt;br /&gt;  param.push([&lt;span class="str"&gt;"openid.session_type"&lt;/span&gt;, &lt;span class="str"&gt;"no-encryption"&lt;/span&gt;]);&lt;br /&gt;  var url = this.makeURL(request_option.provider, param);&lt;br /&gt;&lt;br /&gt;  //association HTTPリクエスト&lt;br /&gt;  gadgets.io.makeRequest(url, function(result){&lt;br /&gt;&lt;span class="comment"&gt;    //association レスポンス解析&lt;/span&gt;&lt;br /&gt;  }, params);&lt;br /&gt;}
&lt;/pre&gt;
&lt;p&gt;送る方は簡単 session_type は "no-encryption"&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;共有鍵のキャッシュ -&amp;gt; OpenSocial汎用データストレージ&lt;/h2&gt;
&lt;p&gt;associationレスポンスを解析し有効期限（expire）が切れるまでキャッシュしておく。&lt;/p&gt;
&lt;p&gt;今回はキャッシュのために OpenSocial API の汎用データストレージを利用する。このストレージ領域には key &amp;amp; value で任意の文字列を保存することが可能で、各アプリケーションそれぞれ別の保存領域となり、ユーザ毎にユニークとなるというデータストレージらしい。&lt;/p&gt;
&lt;p&gt;opensocial.DataRequest クラスの newUpdatePersonAppDataRequest(ユーザID, key, value) メソッドを利用する。&lt;/p&gt;
&lt;p style="font: 12.0px Helvetica"&gt;&lt;a href="http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.DataRequest.html#newUpdatePersonAppDataRequest"&gt;http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.DataRequest.html#newUpdatePersonAppDataRequest&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: -webkit-monospace; white-space: pre;"&gt;下記のようにパラメータを解析し結果をJSON形式の文字列へ変換、それをvalue、OPエンドポイントURLをkeyとする。&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;br /&gt;gadgets.io.makeRequest(url, function(result){&lt;br /&gt;  var results = {};&lt;br /&gt;&lt;br /&gt;  //レスポンス結果を解析&lt;br /&gt;  var params = result.data.split(&lt;span class="str"&gt;"\n"&lt;/span&gt;);&lt;br /&gt;&lt;span class="keyword"&gt;  for&lt;/span&gt;(var i=&lt;span class="num"&gt;0&lt;/span&gt;; i &amp;lt; params.length; i++){&lt;br /&gt;&lt;span class="keyword"&gt;    if&lt;/span&gt;(params[i].search(&lt;span class="str"&gt;":"&lt;/span&gt;) &amp;gt; &lt;span class="num"&gt;0&lt;/span&gt;){&lt;br /&gt;      var param = params[i].match(&lt;span class="regex"&gt;/^([^:]*):(.*)/&lt;/span&gt;);&lt;br /&gt;      results[param[&lt;span class="num"&gt;1&lt;/span&gt;]] = param[&lt;span class="num"&gt;2&lt;/span&gt;];&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  //assoc_handle, mac_key, expires等必要な情報をJSON形式の文字列へ&lt;br /&gt;  var value = this.toJSON({&lt;br /&gt;&lt;span class="str"&gt;    "assoc_type"&lt;/span&gt;&lt;span class="sym"&gt;:results&lt;/span&gt;[&lt;span class="str"&gt;"assoc_type"&lt;/span&gt;],&lt;br /&gt;&lt;span class="str"&gt;    "expires_in"&lt;/span&gt;&lt;span class="sym"&gt;:results&lt;/span&gt;[&lt;span class="str"&gt;"expires_in"&lt;/span&gt;],&lt;br /&gt;&lt;span class="str"&gt;    "mac_key"&lt;/span&gt;&lt;span class="sym"&gt;:results&lt;/span&gt;[&lt;span class="str"&gt;"mac_key"&lt;/span&gt;],&lt;br /&gt;&lt;span class="str"&gt;    "session_type"&lt;/span&gt;&lt;span class="sym"&gt;:results&lt;/span&gt;[&lt;span class="str"&gt;"session_type"&lt;/span&gt;]&lt;br /&gt;  });&lt;br /&gt;  &lt;br /&gt;  //汎用データストレージへ保存、keyはOPエンドポイントURL&lt;br /&gt;  var req = opensocial.newDataRequest();&lt;br /&gt;  var key = request_option.provider;&lt;br /&gt;  req.add(req.newUpdatePersonAppDataRequest(req.PersonId.VIEWER, key, value));&lt;br /&gt;  req.send(function(data){&lt;br /&gt;    callback(result, data);&lt;br /&gt;  });&lt;br /&gt;}, params);
&lt;/pre&gt;
&lt;p&gt;本来のDH鍵交換でやる場合は・・・HTTPリクエストをやって、データストレージへ期限切れるまでキャッシュという大枠は変わらない筈。&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;今回の gadgets.io.makeRequest API のようにOpenSocialコンテナ（myspace / orkut等）がプロキシとして働くHTTPリクエストの場合&lt;strong&gt;でも&lt;/strong&gt;、DH鍵交換アルゴリズムなら盗聴の危険性は無いってことで良いのかな。あ、でもOpenSocialコンテナによる改竄の危険はあるのか。&lt;/p&gt;
&lt;p&gt;まあ実装実験ということで。&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;以上&lt;/h2&gt;
&lt;p&gt;ちょっとしたJavaScriptのアプリケーションを作る時に、ちょっとしたデータ保存領域が欲しい事は結構あると思う。（占いアプリで占い履歴とか、占い選択肢とか）&lt;/p&gt;
&lt;p&gt;その時サーバを自分で立ててWebAPIでデータストレージを用意してやるのは面倒、かなり面倒。&lt;/p&gt;
&lt;p&gt;OpenSocial標準のAPIで汎用的なデータストレージが用意されていて、key &amp;amp; value ペアで任意の文字列を保存できるのは結構使い所ありそうだと思う。JSONにしてやれば構造化もできるわけだし。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2116814"/&gt;</description>
      <pubDate>2008-05-03</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/421-myspace-opensocial-openid-3</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2116814/421-myspace-opensocial-openid-3</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/421-myspace-opensocial-openid-3</feedburner:origLink></item>
    <item>
      <title>Railsホスティングサービスheroku.comとソース管理Git</title>
      <description>&lt;p&gt;AmazonEC2上で動いて、Webブラウザから開発・運用できるRailsアプリケーションのホスティングサービスheroku.com&lt;/p&gt;&lt;img src="http://farm4.static.flickr.com/3058/2458939824_03c924f305.jpg" width="500" height="499" alt="2458939824_03c924f305.jpg" style="border:1px #000000 dotted;" /&gt;
&lt;p class="clear"&gt;&lt;a href="http://jp.techcrunch.com/archives/heroku-lifts-ruby-on-rails-development-to-the-cloud/"&gt;Herokuが、ブラウザー内でRuby on Railsの開発を可能に&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://heroku.com/"&gt;Heroku.com&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;がGitによるソース管理 &amp;amp; ローカル開発に対応したそうなので、ひとつ試してみる。Macで&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;Gitとherokuクライアントのインストール&lt;/h2&gt;
&lt;p&gt;まずPCにGitが入ってないのでインストール。そういえばGitが海外のRubistの間で流行ってるらしいねー、Coderepos的な&lt;a href="http://github.com/"&gt;Github&lt;/a&gt;ってGitリポジトリ共有サイトもあるらしいし。で今回のherokuもソース管理にGitを使うのでインストール&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;sudo port install git-core&lt;/strong&gt;
&lt;/pre&gt;
&lt;p&gt;その後、herokuのコマンドラインクライアントをインストール&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;sudo gem install heroku&lt;/strong&gt;
&lt;/pre&gt;
&lt;p&gt;自分用のssh公開・秘密鍵が無ければ用意しておく&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;ssh-keygen -t rsa&lt;/strong&gt;
&lt;/pre&gt;
&lt;p&gt;自分のherokuアカウントと、ssh公開鍵を関連付ける&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;heroku list&lt;/strong&gt;&lt;br /&gt;Enter your Heroku credentials.&lt;br /&gt;Email: mymail@example.com&lt;br /&gt;Password: ********&lt;br /&gt;Uploading ssh public key&lt;br /&gt;=== My Apps&lt;br /&gt;resttest
&lt;/pre&gt;
&lt;p&gt;登録成功、この時点でWeb上から作成済みのアプリケーションがあると、表示される。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;テストアプリケーション作成&lt;/h2&gt;
&lt;p&gt;コマンドラインから新しいアプリケーション "&lt;strong&gt;tktest&lt;/strong&gt;" を作成&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;heroku create tktest&lt;/strong&gt;&lt;br /&gt;Created http://tktest.heroku.com/
&lt;/pre&gt;
&lt;p&gt;ブラウザで開くと確かに作成済み、次にリポジトリからローカルへ落とす&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;b&gt;heroku clone tktest&lt;/b&gt;
&lt;/pre&gt;
&lt;p&gt;裏では git clone tktest@tktest.heroku.com みたいなコマンドを実行してるっぽい。ここで何故かssh-keyが見付からないと言われたので ~/.ssh/config を書いておいた、Protocol 1 は不要だと思う。&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;emacs ~/.ssh/config&lt;/strong&gt;&lt;br /&gt;Host *&lt;br /&gt;IdentityFile ~/.ssh/id_dsa&lt;br /&gt;IdentityFile ~/.ssh/identity&lt;br /&gt;Protocol 2,1
&lt;/pre&gt;
&lt;p&gt;tktestフォルダ内に通常通りRailsアプリのディレクトリができている筈&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;cd ./tktest&lt;/strong&gt;&lt;br /&gt;% &lt;strong&gt;ruby script/server&lt;/strong&gt;
&lt;/pre&gt;
&lt;p&gt;mongrelが立ち上がり、とりあえずローカル開発準備完了&lt;/p&gt;&lt;img src="http://farm3.static.flickr.com/2193/2458134269_34e6fdf90d_o.jpg" width="753" height="190" alt="2458134269_34e6fdf90d_o.jpg" style="border:1px #000000 dotted;" /&gt;
&lt;p class="clear"&gt;　&lt;/p&gt;
&lt;h2&gt;編集、コミット、デプロイ&lt;/h2&gt;
&lt;p&gt;新しいコードを作って適当に編集&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;ruby script/generate scaffold Post body:text&lt;/strong&gt;&lt;br /&gt;.........
&lt;/pre&gt;
&lt;p&gt;とりあえずできた、localhostで確認してからコミットする&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;git add .&lt;/strong&gt;&lt;br /&gt;% &lt;strong&gt;git commit&lt;/strong&gt;
&lt;/pre&gt;
&lt;p&gt;gitの使い方がよく判らないけど、とりあえずコミット完了。本番環境へ反映する&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;git push&lt;/strong&gt;&lt;br /&gt;Enter passphrase for key '.ssh/id_rsa':&lt;br /&gt;Counting objects: 43, done.&lt;br /&gt;Compressing objects: 100% (29/29), done.&lt;br /&gt;.........&lt;br /&gt;HEAD is now at e6b0b72... test&lt;br /&gt;NOTICE: CREATE TABLE will create implicit sequence "posts_id_seq" for serial column "posts.id"&lt;br /&gt;NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "posts_pkey" for table "posts"&lt;br /&gt;(in /mnt/home/userapps/15472)&lt;br /&gt;== 1 CreatePosts: migrating ===================================================&lt;br /&gt;-- create_table(:posts)&lt;br /&gt;-&amp;gt; 0.1817s&lt;br /&gt;== 1 CreatePosts: migrated (0.1818s) ==========================================&lt;br /&gt;
&lt;/pre&gt;
&lt;p&gt;herokuのリポジトリへPushと同時に rake db:migrate と mongrelの再起動までやってくれるぽい。確認してみる&lt;/p&gt;
&lt;p&gt;&lt;a href="http://tktest.heroku.com/posts"&gt;http://tktest.heroku.com/posts&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;うむうむ、動いてる。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;以上&lt;/h2&gt;
&lt;p&gt;まあちょっとしたアプリケーション作るには楽で良いなheroku.com。現在はベータ中で無料、正式サービスになると課金が始まるらしいけどAmazon EC2で動いているので、課金額もそれくらいになるのかな。Google App Engineと比べると面白い機能は無いけど、作ったサービスの人気が出て自分のサーバで運用したくなったときにheroku.comは良いな。Rails &amp;amp; mongrel &amp;amp; MySQL(?) という普通の環境なので。&lt;/p&gt;
&lt;p&gt;例えば突然 heroku.com のサーバが爆発してサービスが止まっても、ローカルにソースコード一式がで揃っているので自分のサーバを用意して復旧できる。データのバックアップだけは気を付ける必要あるけど、ちなみに heroku.com 本番環境の管理はWebからやれ、というポリシーらしい&lt;/p&gt;&lt;img src="http://farm4.static.flickr.com/3002/2458988786_5dd8fa7fe4_o.jpg" /&gt;
&lt;p class="clear"&gt;DB管理画面&lt;/p&gt;&lt;img src="http://farm4.static.flickr.com/3113/2459011484_8c4abb15fb_o.jpg" /&gt;
&lt;p class="clear"&gt;コンソール画面（ruby script/console）&lt;/p&gt;
&lt;p class="clear"&gt;あと、rakeタスクを実行する画面もある。&lt;/p&gt;
&lt;p class="clear"&gt;　&lt;/p&gt;
&lt;p class="clear"&gt;&lt;/p&gt;
&lt;p&gt;そういえば、ちょうど昨日Google app engineでちょっとしたアプリケーションを作る話を読んで&lt;/p&gt;
&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/shinichitomita/20080501"&gt;Google App Engineの使い道、tiny web service&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;確かに「サーバサイドで処理しないとできないけど、わざわざサーバを用意するのは面倒だな」ってときに、Google app engine や heroku.com や appjet.com なんかの環境が便利だなと思った。&lt;/p&gt;
&lt;p class="clear"&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2103061"/&gt;</description>
      <pubDate>2008-05-02</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/419-rails-heroku-com-git</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2103061/419-rails-heroku-com-git</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/419-rails-heroku-com-git</feedburner:origLink></item>
    <item>
      <title>muninプラグインでRailsの処理時間をモニタリング&amp;監視</title>
      <description>&lt;p&gt;そういえば、半年ほど前から&lt;a href="http://fooo.name/"&gt;fooo.name&lt;/a&gt;の監視に&lt;a href="http://munin.projects.linpro.no/"&gt;munin&lt;/a&gt;を入れていて、muninプラグインを書いてRailsのパフォーマンスをモニタリングできるようしているのですが&lt;/p&gt;&lt;img src="http://farm3.static.flickr.com/2333/2458249343_c192ef48a3.jpg" /&gt;
&lt;p class="clear"&gt;その手順を書いておくと誰か嬉しい人がいるかなと思ったので、メモを残しておきます。サーバはAmazon EC2&lt;/p&gt;
&lt;p class="clear"&gt;　&lt;/p&gt;
&lt;p class="clear"&gt;&lt;/p&gt;
&lt;h2&gt;muninのインストール&lt;/h2&gt;
&lt;p class="clear"&gt;apt-getでmuninをインストール&lt;/p&gt;
&lt;p class="clear"&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% &lt;strong&gt;apt-get install munin munin-node&lt;/strong&gt;&lt;br /&gt;% &lt;strong&gt;/etc/init.d/munin-node start&lt;/strong&gt;
&lt;/pre&gt;
&lt;p class="clear"&gt;Apache・MySQL・CPU / メモリ / ネットワーク / ロードアベレージ 辺りのモニタリングが始まる。実際にはcronが設定されていてデフォルト５分に１回モニタリング結果がHTMLとして出力される。出力される場所はconfigファイル /etc/munin/munin.conf にあるので、好みで編集&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% emacs&lt;strong&gt; /etc/munin/munin.conf&lt;/strong&gt;&lt;br /&gt;dbdir /var/lib/munin&lt;br /&gt;htmldir /var/www/munin&lt;br /&gt;logdir /var/log/munin&lt;br /&gt;rundir /var/run/munin
&lt;/pre&gt;
&lt;p class="clear"&gt;あとは /var/www/munin 以下をApacheで見えるように設定、Virtual hostを設定してBasic認証を掛けておいた&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% emacs &lt;strong&gt;/etc/apache2/httpd.conf&lt;/strong&gt;&lt;br /&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;  DocumentRoot /var/www/munin&lt;br /&gt;  ServerName *********&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&amp;lt;Directory "/var/www/munin"&amp;gt;&lt;br /&gt;  AuthType Basic&lt;br /&gt;  AuthName "Munin zone"&lt;br /&gt;  AuthUserFile /etc/apache2/.htpasswd&lt;br /&gt;  Require user ********&lt;br /&gt;&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;Railsのログをmuninでモニタリング&lt;/h2&gt;
&lt;p&gt;あとは、この↓サイトを真似してやればOK&lt;/p&gt;
&lt;p&gt;&lt;a href="http://onrails.org/articles/2007/08/31/monitoring-rails-performance-with-munin-and-a-mongrel"&gt;Monitoring Rails Performance with Munin and a Mongrel&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Railsの出力するlogから total / render / db の時間を見つけ max と avg の値を求め、muninでそれを監視する。Railsアプリケーションの scriptフォルダへ以下のスクリプトを置く&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;% emacs &lt;strong&gt;script/rails_log_monitor.rb&lt;/strong&gt;&lt;br /&gt;・・・・・・&lt;br /&gt;h = Mongrel::HttpServer.new("127.0.0.1", PORT)&lt;br /&gt;h.register("/avg_response_time", ResponseTimeHandler.new(:average))&lt;br /&gt;h.register("/max_response_time", ResponseTimeHandler.new(:max))&lt;br /&gt;h.run.join&lt;br /&gt;&lt;a href="https://dl.getdropbox.com/u/3111/fooo/rails_log_monitor.rb"&gt;rails_log_monitor.rb&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;上記スクリプトを実行すると port 8888 でmongrelが立ち上がる、muninはそこへアクセスし結果を取得する&lt;/p&gt;
&lt;p&gt;% &lt;strong&gt;ruby script/rails_log_monitor.rb&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p&gt;次に、muninプラグインとして下記のスクリプトを /etc/munin/plugins 配下へ&lt;/p&gt;
&lt;p&gt;&lt;a href="https://dl.getdropbox.com/u/3111/fooo/avg_response_time"&gt;avg_response_time&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;avg_response_time と max_response_time という名前で置いておく。結果muninが http://127.0.0.1:8888/#{ファイル名} へアクセスし結果を取得、グラフ化。&lt;/p&gt;&lt;img src="http://farm3.static.flickr.com/2308/2459760378_c25d745e18_o.jpg" /&gt;
&lt;p class="clear"&gt;&lt;/p&gt;
&lt;p class="clear"&gt;&lt;/p&gt;
&lt;h2&gt;以上&lt;/h2&gt;
&lt;p class="clear"&gt;基本&lt;a href="http://onrails.org/articles/2007/08/31/monitoring-rails-performance-with-munin-and-a-mongrel"&gt;このサイト&lt;/a&gt;を真似してやればOK、rails_log_moniter.rb を好きにいじれば ”特定のアクション・コントローラ・処理" 等をグラフ化してモニタリングできる筈。&lt;/p&gt;
&lt;p class="clear"&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2107867"/&gt;</description>
      <pubDate>2008-05-02</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/420-munin-rails</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2107867/420-munin-rails</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/420-munin-rails</feedburner:origLink></item>
    <item>
      <title>MySpaceでOpenSocialアプリケーション "OpenIDクライアント" を試す ー (2)</title>
      <description>&lt;p&gt;↓ このエントリの続き&lt;/p&gt;
&lt;p style="font: 12.0px Helvetica"&gt;&lt;/p&gt;
&lt;p style="font: 12.0px Helvetica"&gt;&lt;a href="http://blog.tkmr.org/tatsuya/show/417-myspace-opensocial-openid-1"&gt;MySpaceでOpenSocialアプリケーション「OpenIDクライアント」を試す ー (1)&lt;/a&gt;&lt;/p&gt;
&lt;p style="font: 12.0px Helvetica"&gt;引き続き、OpenIDのIdentifier入力からOpenID Provider（以下OP） エンドポイントURLの探索までを実装する&lt;/p&gt;
&lt;p style="font: 12.0px Helvetica"&gt;&lt;/p&gt;
&lt;h2&gt;input（入力）&lt;/h2&gt;
&lt;p style="font: 12.0px Helvetica"&gt;&lt;/p&gt;
&lt;p&gt;UIとしてIdentifierを入力するフォームを用意、submitにイベントを追加する。今回この辺りはjQueryを使った。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://farm4.static.flickr.com/3165/2424401283_6b1794b51e_o.jpg" /&gt;&lt;/p&gt;
&lt;pre class="source clear"&gt;
&lt;br /&gt;&amp;lt;form &lt;span class="keyword"&gt;class&lt;/span&gt;=&lt;span class="str"&gt;"rp"&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;input id=&lt;span class="str"&gt;"identify"&lt;/span&gt; type=&lt;span class="str"&gt;"text"&lt;/span&gt; name=&lt;span class="str"&gt;"openid_identifier"&lt;/span&gt; /&amp;gt;&lt;br /&gt;  &amp;lt;input type=&lt;span class="str"&gt;"submit"&lt;/span&gt; value=&lt;span class="str"&gt;"Sign in"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;lt;&lt;span class="regex"&gt;/form&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="regex"&gt;&amp;lt;script type="text/&lt;/span&gt;javascript&lt;span class="str"&gt;"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="str"&gt;  $("&lt;/span&gt;form.rp&lt;span class="str"&gt;").submit(function(){&lt;/span&gt;&lt;br /&gt;&lt;span class="str"&gt;    var ident = $("&lt;/span&gt;&lt;span class="comment"&gt;#identify").attr("value");&lt;/span&gt;&lt;br /&gt;    openid.auth(ident, function(result){&lt;br /&gt;&lt;span class="regex"&gt;      //some&lt;/span&gt;thing &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;    });&lt;br /&gt;  });&lt;br /&gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;formの値を取得し、メインロジックopenid.authを呼ぶ。以後は normalize &amp;gt; discovery &amp;gt; association &amp;gt; authentication &amp;gt; response parse &amp;gt; verify の順に実行していく。&lt;/p&gt;
&lt;p&gt;この辺りはまだOpenSocialに関係無く普通のHTML + JavaScript&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p&gt;ちなみに処理全体の流れは、大体以下のようになる予定。&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;br /&gt;var openid = {&lt;br /&gt;  auth: function(request_ident, callback){&lt;br /&gt;    var &lt;span class="keyword"&gt;self&lt;/span&gt; = this;&lt;span class="comment"&gt;&lt;br /&gt;    //IDの正規化、http://を補足（ 例：tkmr.myopenid.com =&amp;gt; http://tkmr.myopenid.com/ ）&lt;br /&gt;&lt;/span&gt;    request_ident = &lt;span class="keyword"&gt;self&lt;/span&gt;.normalize(request_ident);&lt;span class="comment"&gt;&lt;br /&gt;    //OpenID認証局のエンドポイントURLを探索（ 例：http://tkmr.myopenid.com/ =&amp;gt; http://myopenid.com/server ）&lt;br /&gt;&lt;/span&gt;    &lt;span class="keyword"&gt;self&lt;/span&gt;.discovery(request_ident, function(request_option){&lt;br /&gt;&lt;span class="comment"&gt;      //共有鍵の交換（任意） - 未実装&lt;/span&gt;&lt;br /&gt;&lt;span class="comment"&gt;      //var assoc_handle = self.association();&lt;/span&gt;&lt;br /&gt;&lt;span class="comment"&gt;      //discoveryで見付かったOpenID認証局エンドポイントURLへ認証リクエストを投げる（IFrameで代用）&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;      self&lt;/span&gt;.auth_request(request_option, function(response){&lt;br /&gt;&lt;span class="comment"&gt;        //認証結果を確認、IFrameのURLから取得&lt;/span&gt;&lt;br /&gt;        var res = &lt;span class="keyword"&gt;self&lt;/span&gt;.auth_response_parse(response);&lt;span class="comment"&gt;//認証結果の署名を確認&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;        if&lt;/span&gt;(&lt;span class="keyword"&gt;self&lt;/span&gt;.verify(res)){&lt;br /&gt;          callback(res);&lt;br /&gt;        }&lt;span class="keyword"&gt;else&lt;/span&gt;{&lt;br /&gt;          callback(&lt;span class="keyword"&gt;false&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}
&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;normalize（正規化）&lt;/h2&gt;
&lt;p&gt;参考：&lt;span style="color: #0000EE; text-decoration: underline;"&gt;&lt;a href="http://lab.koshigoe.jp/en2ja/openid-authentication-2_0.html#normalization"&gt;http://lab.koshigoe.jp/en2ja/openid-authentication-2_0.html#normalization&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;ユーザの入力したIdentifierの正規化を行う、正式な仕様としては XRI の正規化をサポートする必要があると思うが今回は未実装&lt;/p&gt;
&lt;p&gt;とりあえずIdentifierが http で始まらない場合 http:// を付加しておいた。&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;br /&gt;openid.normalize = function(identify){&lt;br /&gt;  var new_ident = identify.search(&lt;span class="regex"&gt;/^(http|https):\/\//&lt;/span&gt;) &amp;gt; &lt;span class="num"&gt;0&lt;/span&gt; ? identify : &lt;span class="str"&gt;"http://"&lt;/span&gt; + identify;&lt;br /&gt;&lt;span class="keyword"&gt;  return&lt;/span&gt; new_ident;&lt;br /&gt;}
&lt;/pre&gt;&lt;br /&gt;
&lt;p style="font: 12.0px Helvetica"&gt;&lt;/p&gt;
&lt;h2&gt;discovery（探索）&lt;/h2&gt;
&lt;p&gt;参考：&lt;a href="http://lab.koshigoe.jp/en2ja/openid-authentication-2_0.html#discovery"&gt;http://lab.koshigoe.jp/en2ja/openid-authentication-2_0.html#discovery&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span style="font-size: 12px; font-weight: normal;"&gt;正規化後、Identifier（例：http://tkmr.myopenid.com ）からOPエンドポイントURL（例：http://myopenid.com/server ）を知る必要があり、その探索方法として下記の３種類がある&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;　・HTMLベース探索&lt;a href="http://lab.koshigoe.jp/en2ja/openid-authentication-2_0.html#html_disco"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　・XRI （ &lt;a href="http://d.hatena.ne.jp/ZIGOROu/20080202"&gt;XRIのリンク集 - Yet Another Hackadelic&lt;/a&gt; ）&lt;/p&gt;
&lt;p&gt;　・Yadis （ &lt;a href="http://gihyo.jp/dev/feature/01/openid/0003?page=2"&gt;第3回　OpenIDプロトコルの特徴－DiscoveryとSREG&lt;/a&gt; ）&lt;/p&gt;
&lt;p&gt;今回の実装では、&lt;a href="http://lab.koshigoe.jp/en2ja/openid-authentication-2_0.html#html_disco"&gt;HTMLベース探索&lt;/a&gt; を試す（XRIとYadisによる探索は未実装）&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;br /&gt;openid.discovery = function(ident, callback){&lt;br /&gt;  switch(ident.split(&lt;span class="str"&gt;"://"&lt;/span&gt;)[&lt;span class="num"&gt;0&lt;/span&gt;]){&lt;br /&gt;&lt;span class="keyword"&gt;  case&lt;/span&gt; &lt;span class="str"&gt;"http"&lt;/span&gt;:&lt;br /&gt;    openid.html_discovery(ident, callback);&lt;br /&gt;&lt;span class="keyword"&gt;    break&lt;/span&gt;;&lt;br /&gt;&lt;span class="keyword"&gt;  case&lt;/span&gt; &lt;span class="str"&gt;"xri"&lt;/span&gt;:&lt;br /&gt;    openid.xri_discovery(ident, callback);&lt;br /&gt;&lt;span class="keyword"&gt;    break&lt;/span&gt;;&lt;br /&gt;  default:&lt;br /&gt;    alert(&lt;span class="str"&gt;"error!!!!!"&lt;/span&gt;);&lt;br /&gt;&lt;span class="keyword"&gt;    break&lt;/span&gt;;&lt;br /&gt;  }&lt;br /&gt;}
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;HTMLベース探索の実装&lt;/h3&gt;
&lt;p&gt;ユーザのIdentifier（URL）に存在するHTMLを取得し、OPのエンドポイントURLを探し出す。&lt;/p&gt;
&lt;pre&gt;
&lt;br /&gt;例：&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;  &amp;lt;link rel="&lt;strong&gt;openid2.provide&lt;/strong&gt;r" href="&lt;strong&gt;認証局エンドポイントURL&lt;/strong&gt;" /&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;
&lt;/pre&gt;
&lt;p&gt;まずIdentifier（URL）にあるコンテンツを取得する必要がある、今回はHTTPリクエストを OpenSocial APIの gadgets.io.makeRequest で投げる。&lt;br /&gt;&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;br /&gt;openid.html_discovery = function(identify, callback){&lt;br /&gt;  var params = {};&lt;br /&gt;  params.contentType = gadgets.io.ContentType.TEXT;&lt;br /&gt;  gadgets.io.makeRequest(identify, function(res){&lt;br /&gt;&lt;span class="comment"&gt;    //取得結果(HTML)のパース&amp;amp;解析処理&lt;/span&gt;&lt;br /&gt;  }, params);&lt;br /&gt;}
&lt;/pre&gt;
&lt;p&gt;gadgets.io.ContentTypeは XML・JSON・TEXT・FEED の４種類が用意されていて、XMLならXMLHttpRequestのresponseXMLが返ってきたりと、それぞれ想像通りに動く。&lt;/p&gt;
&lt;p&gt;・ContentType：&lt;a href="http://code.google.com/apis/opensocial/docs/0.7/reference/gadgets.io.ContentType.html"&gt;http://code.google.com/apis/opensocial/docs/0.7/reference/gadgets.io.ContentType.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;・RequestParameter：&lt;a href="http://code.google.com/apis/opensocial/docs/0.7/reference/gadgets.io.RequestParameters.html"&gt;http://code.google.com/apis/opensocial/docs/0.7/reference/gadgets.io.RequestParameters.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;また任意のヘッダをリクエストへ付けることも可能&lt;/p&gt;
&lt;p&gt;・Header ：&lt;a href="http://code.google.com/intl/ja_ALL/apis/opensocial/docs/0.7/reference/gadgets.io.RequestParameters.html#HEADERS"&gt;http://code.google.com/intl/ja_ALL/apis/opensocial/docs/0.7/reference/gadgets.io.RequestParameters.html#HEADERS&lt;/a&gt;&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;br /&gt;params[gadgets.io.RequestParameters.HEADERS] = {&lt;span class="str"&gt;"Accept-Language"&lt;/span&gt; : &lt;span class="str"&gt;"ja"&lt;/span&gt;};&lt;span style="font-family: Helvetica; white-space: normal;"&gt;　&lt;/span&gt;&lt;br /&gt;
&lt;/pre&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p&gt;今回の対象はHTMLのため ContentType はTEXT に設定、単純なStringとしてHTMLが返ってくるので、そのHTML内にある目的の &amp;lt;link rel="openid2.provider" href="***" /&amp;gt; タグを探す&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;br /&gt;var results = {}&lt;br /&gt;var links = res.data.match(&lt;span class="regex"&gt;/&amp;lt;link[^&amp;gt;]*&amp;gt;/&lt;/span&gt;g);&lt;br /&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;(var i=&lt;span class="num"&gt;0&lt;/span&gt;; i &amp;lt; links.length; i++){&lt;br /&gt;  var link = links[i];&lt;br /&gt;&lt;span class="keyword"&gt;  if&lt;/span&gt;(link.search(&lt;span class="regex"&gt;/rel.*openid2.provider/&lt;/span&gt;) &amp;gt; &lt;span class="num"&gt;0&lt;/span&gt;){&lt;br /&gt;    results.provider = link.match(&lt;span class="regex"&gt;/href="([^"]*)"/&lt;/span&gt;)[&lt;span class="num"&gt;1&lt;/span&gt;];&lt;br /&gt;  }&lt;span class="keyword"&gt;else&lt;/span&gt;{&lt;br /&gt;&lt;span class="keyword"&gt;    if&lt;/span&gt;(link.search(&lt;span class="regex"&gt;/rel.*openid2.local_id/&lt;/span&gt;) &amp;gt; &lt;span class="num"&gt;0&lt;/span&gt;){&lt;br /&gt;      results.local_id = link.match(&lt;span class="regex"&gt;/href="([^"]*)"/&lt;/span&gt;)[&lt;span class="num"&gt;1&lt;/span&gt;];&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;callback(results);
&lt;/pre&gt;
&lt;p&gt;ついでに rel="openid.server" も探しておいた方が良いかも。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h3&gt;おまけ：Yadis探索を実装&lt;/h3&gt;
&lt;p&gt;するためにはレスポンスヘッダの内容を知る必要がある、はず。OpenSocial / makeRequestのドキュメントには特に記述が無かったのでレスポンスヘッダへのアクセスは不明・・・&lt;/p&gt;
&lt;p&gt;ただ、makeRequest の通信内容を見る限りでは取得可能なように見える。&lt;/p&gt;&lt;img src="http://farm3.static.flickr.com/2032/2425995276_e50c14d522_o.jpg" /&gt;
&lt;p class="clear"&gt;レスポンスヘッダさえ取れれば、あとは x-xrds-location に設定されたURLにあるXRDS文章を取得し、XRDSの仕様に従ってOPエンドポイントURLを見つける、で良いのかな。&lt;/p&gt;
&lt;p&gt;XRIは・・・、仕様から勉強しておきます：）&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p&gt;以上、今回はOpenID Providerの認証エンドポイントURLの探索まで実装しました。&lt;/p&gt;
&lt;p&gt;それでは明日へ続く&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040942"/&gt;</description>
      <pubDate>2008-04-19</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/418-myspace-opensocial-openid-2</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040942/418-myspace-opensocial-openid-2</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/418-myspace-opensocial-openid-2</feedburner:origLink></item>
    <item>
      <title>MySpaceでOpenSocialアプリケーション "OpenIDクライアント" を試す ー (1)</title>
      <description>&lt;p&gt;先々週、MySpace JapanのOpenSocialプラットフォーム対応が発表された&lt;/p&gt;
&lt;p&gt;&lt;a href="http://journal.mycom.co.jp/news/2008/03/28/031/index.html"&gt;マイスペースが開発者向けプラットフォームを発表 - OpenSocialに完全準拠&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;ということで、久しぶりにOpenSocialを色々といじってみようと思う。何かネタが無いとやりづらいので「OpenSocial上で動くOpenIDクライアント（Relying Party）」というネタで試してみよう。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;OpenSocial ver 0.7&lt;/h2&gt;
&lt;p&gt;OpenSocial自体については Ver 0.5 の頃&lt;a href="http://blog.tkmr.org/tatsuya/show/406-google-opensocial-api-mixi-javascript-gadget"&gt;Orkut上で試した&lt;/a&gt;ので、今回はそれを振り返りつつ Ver 0.7 までで新しくなった部分をMySpace上で試してみる。&lt;/p&gt;
&lt;h2&gt;Ver 0.7変更点&lt;/h2&gt;
&lt;p&gt;・外部サイトへHTTPリクエストを投げるAPI追加（XML・JSON・Text・Feed（RSS or Atom?））&lt;/p&gt;
&lt;p&gt;　　&lt;a href="http://code.google.com/apis/opensocial/docs/0.7/reference/gadgets.io.html#makeRequest"&gt;http://code.google.com/apis/opensocial/docs/0.7/reference/gadgets.io.html#makeRequest&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;・取得可能なプロフィール情報の項目追加（性別・好きな音楽・本 等々）&lt;/p&gt;
&lt;p&gt;　　&lt;a href="http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.Person.Field.html"&gt;http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.Person.Field.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;・各アプリケーション毎のデータストレージ API 追加（ 任意の key &amp;amp; value のペアでサーバへ保存される、アプリケーション + ユーザID + key でユニークとなる）&lt;/p&gt;
&lt;p&gt;　　&lt;a href="http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.DataRequest.html#newUpdatePersonAppDataRequest"&gt;http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.DataRequest.html#newUpdatePersonAppDataRequest&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;・Activityが実装されつつある？（「○○さんが××をしました」みたいな通知API）&lt;/p&gt;
&lt;p&gt;　　&lt;img src="http://data.tumblr.com/PiewZhiOE7hbyxw5wegoPzjh_400.png" /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;・環境情報が追加（実行中の画面やドメインが取れる、ホーム画面・プロフィール画面・専用画面、orkut.com・myspace.com）&lt;/p&gt;
&lt;p&gt;・ネームスペース変更多数（gadgets）&lt;/p&gt;
&lt;p&gt;他色々と。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p&gt;外部サイトへのHTTPリクエストを行う makeRequest API がなかなか使い所ありそうなので、これを今回は試す。あとデータストレージも試してみよう。&lt;/p&gt;
&lt;p&gt;ということで、無理矢理っぽいけど「OpenIDへのログイン→ログイン履歴保存」という流れで実験。&lt;/p&gt;
&lt;p&gt;ちなみに、外部HTTPリクエストを行う makeRequest APIの仕様は、プロクシを経由することでクロスドメインAjaxが可能、といった代物で以下のようにリクエストが飛ぶ&lt;/p&gt;
&lt;p&gt;　クライアント ＞ プロクシ（proxy.myspace.com等） ＞ 外部サイト&lt;/p&gt;
&lt;p&gt;意外に細かい部分で気が利いていて、任意のヘッダが設定可能 &amp;amp; 任意のメソッドが設定可能（GET/ POST / PUT / DELETE）&lt;/p&gt;
&lt;p&gt;Basic認証や無理矢理やれば WSSE認証も多分できそう。AtomPubクライアント in OpenSocialなんてのも面白そう。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;MySpace Developer Platform&lt;/h2&gt;
&lt;p&gt;OpenSocial仕様外の部分で、MySpace独自API（ユーザの投稿写真・ビデオ等）もあり、リファレンスはこちら&lt;/p&gt;
&lt;p&gt;&lt;a href="http://developer.myspace.com/community/myspace/myopenspace.aspx"&gt;MySpace Developer Platform&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;この辺りも将来的にはOpenSocial APIとして足並みそろえていくのかな。&lt;/p&gt;
&lt;p&gt;個人的に写真・ビデオ・音楽といった一般的な情報はOpenSocialに含めてＯＫじゃないかと思う。逆に、株取引SNSの「注目の銘柄」や競馬SNSの「最近買った馬券」なんてサービスのドメインにべったり寄った情報は独自APIという方向に進む、のかな。線引きが難しい。&lt;/p&gt;
&lt;p&gt;また、MySpaceとOpenSocialの関係については&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlog.agektmr.com/archives/37"&gt;OpenSocialとかどうよ？的な勉強会(!?)に参加してきた - Tender Surrender&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;こちらが、アプリケーション互換性の問題からマネタイズまで、判りやすくまとめられているので参考に。&lt;/p&gt;
&lt;h3&gt;MySpaceデベロッパー登録 ＞ アプリケーション作成&lt;/h3&gt;
&lt;p&gt;実際にMySpace上でアプリケーションを作成するには、デベロッパーとして登録する必要があるので登録。この辺り、登録から初めてのアプリケーション作成まで、こちらのサイトで分かり易くままとめられている&lt;/p&gt;
&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/yorihito_tanaka/20080408"&gt;MySpaceアプリケーションを作ろう - ラーニング人生&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;この手順に従ってやれば簡単にできる、筈。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;実装方針&lt;/h2&gt;
&lt;p&gt;・OpenIDの&lt;strong&gt;基本的&lt;/strong&gt;な流れを実験する&lt;/p&gt;
&lt;p&gt;　　・XRI や Yadis による探索は未実装&lt;/p&gt;
&lt;p&gt;　　・関連付け（共有鍵の交換）は未実装&lt;/p&gt;
&lt;p&gt;　　・OPから受け取った署名の照合も未実装・・&lt;/p&gt;
&lt;p&gt;・処理フローはこんな感じで&lt;/p&gt;
&lt;p&gt;　　・input （ユーザによるidentifierの入力）&lt;/p&gt;
&lt;p&gt;　　・normalize（identifierの正規化）&lt;/p&gt;
&lt;p&gt;　　・discovery（OP Endpoint URLの探索）&lt;/p&gt;
&lt;p&gt;　　・association（共有鍵の交換）※未実装※&lt;/p&gt;
&lt;p&gt;　　・authentication（認証リクエスト）&lt;/p&gt;
&lt;p&gt;　　・response（認証結果のパース）&lt;/p&gt;
&lt;p&gt;　　・verify（署名の確認）※未実装※&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;以上&lt;/h2&gt;
&lt;p&gt;それでは明日へ続く、次回は実装を&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040943"/&gt;</description>
      <pubDate>2008-04-13</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/417-myspace-opensocial-openid-1</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040943/417-myspace-opensocial-openid-1</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/417-myspace-opensocial-openid-1</feedburner:origLink></item>
    <item>
      <title>rsync + subversion + Amazon S3 = dropbox</title>
      <description>&lt;p&gt;Google app engineのアカウントが申し込み間に合わなくてくやしいので、&lt;a href="https://www.getdropbox.com/"&gt;Dropbox&lt;/a&gt;についてでも書こう。　&lt;/p&gt;
&lt;h2&gt;rsync + Amazon S3 + subversion × 全自動 = dropbox&lt;/h2&gt;
&lt;p&gt;「気軽に複数PCでファイル共有できるオンラインストレージ」という触れ込みで登場した&lt;a href="https://www.getdropbox.com/"&gt;Dropbox&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jp.techcrunch.com/archives/dropbox-the-online-storage-solution-weve-been-waiting-for/"&gt;Techcrunch - Dropbox: みんなが待ち望んでいたオンラインストレージソリューションかも&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;現在5GBまで無料のオンラインストレージで、実際のストレージにはAmazon S3を利用しているらしい。WindowsとMac用のクライントがあり、これが良くできていて&lt;/p&gt;
&lt;p&gt;ファイルの変更を検知して全自動でオンラインストレージへ保存し続けてくれる。しかもソース管理ツール的な履歴機能付き、編集の衝突も検知して上手く回避してくれる。&lt;/p&gt;
&lt;p&gt;さらに友人・知人と共有するSharedフォルダも作れてソーシャル的な展開も考えているみたい、試していないけど。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;h2&gt;動作例&lt;/h2&gt;
&lt;p&gt;例えば、このフォルダへ&lt;/p&gt;&lt;img src="http://farm3.static.flickr.com/2046/2403772842_f5fba53b41_o.jpg" width="1157" height="575" alt="2403772842_f5fba53b41_o.jpg" /&gt;
&lt;p class="clear"&gt;普通にメモ帳でテキストを保存する&lt;/p&gt;&lt;img src="http://farm3.static.flickr.com/2406/2404007628_ccf6dd4446.jpg" /&gt;
&lt;p class="clear"&gt;ファイルが自動でオンラインストレージに同期される！&lt;/p&gt;&lt;img src="http://farm4.static.flickr.com/3133/2403780088_b022d6fc1f_o.jpg" /&gt;
&lt;p class="clear"&gt;　&lt;/p&gt;
&lt;h2&gt;履歴管理・衝突回避・その他&lt;/h2&gt;
&lt;p class="clear"&gt;プログラマならこの辺が気になるだろうと思うので補足。&lt;/p&gt;
&lt;p class="clear"&gt;履歴機能もしっかりしている、普通に個人で書くコードくらいなら履歴管理まかせても良いくらい&lt;/p&gt;&lt;img src="http://farm3.static.flickr.com/2025/2403002045_7ac4f1742f_o.jpg" /&gt;
&lt;p class="clear"&gt;さあここで大変！自宅と会社で編集したファイルが衝突した！！&lt;/p&gt;&lt;img src="http://farm4.static.flickr.com/3180/2403017837_92ef0e82cf_o.jpg" /&gt;
&lt;p class="clear"&gt;衝突したファイルはリネームされて保存される。上書きされて消えた！ってことは起こらない。まあ現実的な対応かな、しいていうなら「衝突ファイル一覧」を見たいくらいかな、RSSとかで。&lt;/p&gt;
&lt;p class="clear"&gt;あと基本的にインストール後現れる「Dropbox」フォルダ以下が同期される、でもどうせならホームフォルダ辺りをこのDropbox以下にシンボリックリンクでリンクさせとくと超快適&lt;/p&gt;
&lt;p class="clear"&gt;　・Windowsの場合 : &lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;file link -symbolic リンク先 リンク元&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p class="clear"&gt;　・Macの場合 ： &lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;ln -s リンク元 リンク先&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p class="clear"&gt;Macは普通だけど、Windowsにシンボリックリンクがあるのをこの件で調べて知った・・&lt;/p&gt;
&lt;p class="clear"&gt;　&lt;/p&gt;
&lt;p class="clear"&gt;Dropbox本当に細かい部分で気が利いていて良い、しかも何気に感動したのが全くストレスが無いこと。&lt;/p&gt;
&lt;p class="clear"&gt;今まで、WebDAVで複数PCを同期、なんて方法も試したけどどうも書き込み＆読み込みが遅くストレスになって結局やめた。&lt;a href="http://box.net/"&gt;Box.net&lt;/a&gt; とか。&lt;/p&gt;
&lt;p class="clear"&gt;でもDropboxの場合、ユーザはローカルのHDDを普通に読み書きする、その後バックグラウンドでゆっくり同期を行っているんだ思う。&lt;/p&gt;
&lt;p class="clear"&gt;あくまでも我々はローカルHDDを読み書きするので、本当に存在を忘れるくらい快適。&lt;/p&gt;
&lt;p class="clear"&gt;　&lt;/p&gt;
&lt;p class="clear"&gt;ローカルHDDをキャッシュに使う、という発想はWebDAVになかったんだな、まあWebプロトコルのWebDAVとクライアントアプリケーションのDropboxでは性質が全く違うので当然なんだけど。&lt;/p&gt;
&lt;p class="clear"&gt;全データをオンラインに保存する時代になると、ローカルHDDは只のキャッシュになるんだなと思う。&lt;/p&gt;
&lt;p class="clear"&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;全データをオンラインに保存する時代 ＝「アクセス権限制御」の時代&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p class="clear"&gt;「データをブログに書く」じゃなくて、「もうウェブにはのってて、パブにするかどうか決めるだけで情報は出る」べきだと思っていた。この「パブにするインターフェイス」みたいなものが効率化すればいいと。このためには文字列一致検索なり、属性絞込みなりについて、最高のインターフェイスがあって、筋肉運動くらい自由で詳細に（あるいはペンとか本のページをくくるくらい自由に詳細に）権限管理ができるべきだった。&lt;br /&gt;&lt;/p&gt;

  &lt;p class="clear"&gt;&lt;/p&gt;

  &lt;p class="clear"&gt;&lt;a href="http://toukubo.com/post/25520816"&gt;ウェブ3時代は「アクセス権限制御」の時代だと思えてきた - tokubo.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class="clear"&gt;以前この↑文章を読んで、色々考えていた世界がDropboxで実現しそうな感じ。実際は5GBなんてちんけな容量なので「世界の片鱗が見えた」くらいだけどそれでも大きな進歩だ。&lt;/p&gt;
&lt;p class="clear"&gt;自分の書いたテキスト、写真、楽曲、メール、ソースコード、コンフィグファイル、ブックマーク、ブラウザの履歴、コンピュータの操作履歴、、、全部オンラインストレージへ同期されていて&lt;/p&gt;
&lt;p class="clear"&gt;API経由で自由に加工可能な世界がきっと来る。&lt;/p&gt;
&lt;p class="clear"&gt;　&lt;/p&gt;
&lt;p class="clear"&gt;実際、@ITでのDropbox開発者へのインタビューでもAPIの話が出ていて&lt;br /&gt;&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p class="clear"&gt;同社は現在すでにいくつかのオンラインサービス提供者と協力して、DropboxをWebアプリケーションから利用できるようAPIを整備している。となれば、例えばデジカメの写真をFlickrにアップロードするのに、Webブラウザや専用アプリケーションを用いる必要はなくなり、ふつうにフォルダにファイルをコピーするだけで、写真を公開できるようになる。逆に、Flickrにアップロードしたファイルを、ローカルのPCの画像編集ソフトを使ってダイレクトに編集ができるようになる。&lt;br /&gt;&lt;/p&gt;

  &lt;p class="clear"&gt;&lt;a href="http://www.atmarkit.co.jp/news/200704/09/dropbox.html"&gt;http://www.atmarkit.co.jp/news/200704/09/dropbox.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class="clear"&gt;写真は全てオンラインに載ってて、あとは共有したい写真・フォルダを選びFlickrへ権限を与えるだけでデータがFlickrへ流れ・同期され公開される。「自分は全てFlickrで公開する」なんて人は全権限Flickrに与えるんだろう。&lt;/p&gt;
&lt;p class="clear"&gt;または編集したい写真はPicnik（オンライン写真編集サービス）で編集する。Picnikに権限を与えて自動処理・一括処理も可能だろう。これはBox.netとPicnikで既に実現されている&lt;a href="http://labs.gmo.jp/blog/ku/2007/12/openbox.html"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="clear"&gt;&lt;a href="http://labs.gmo.jp/blog/ku/2007/12/openbox.html"&gt;ほかのサービスとくっつけられるストレージサービスOpenBoxを自分でくっつける - bits and bytes&lt;/a&gt;&lt;/p&gt;
&lt;p class="clear"&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;Dropboxで写真をオンラインと同期し、APIが用意されていれば&lt;/p&gt;
&lt;p class="clear"&gt;・Flickrに権限を与え写真共有&lt;/p&gt;
&lt;p class="clear"&gt;・&lt;a href="http://jp.techcrunch.com/archives/extend-your-brain-with-evernote-private-beta-invites/"&gt;Evernote&lt;/a&gt;に権限を与えておくことで画像検索&lt;/p&gt;
&lt;p class="clear"&gt;・Picnikに権限を与え写真編集&lt;/p&gt;
&lt;p class="clear"&gt;・基本のフロントエンドは今まで通りのアプリケーションでＯＫ（ iPhoto とか）&lt;br /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;・ローカルHDDがキャッシュしているのでレスポンスもＯＫ&lt;/p&gt;
&lt;p class="clear"&gt;　&lt;/p&gt;
&lt;p class="clear"&gt;音楽なら&lt;/p&gt;
&lt;p class="clear"&gt;・&lt;a href="http://muxtape.com/"&gt;Muxtape&lt;/a&gt;に権限を与え、ミックステープ化＆音楽共有&lt;/p&gt;
&lt;p class="clear"&gt;・オンライン楽曲編集サービスに権限を与える&lt;/p&gt;
&lt;p class="clear"&gt;・楽曲検索サービスに権限を与える&lt;/p&gt;
&lt;p class="clear"&gt;・基本のフロントエンドは今まで通りのアプリケーションでOK（ iTunesとか）&lt;/p&gt;
&lt;p class="clear"&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;テキストならさらに色々な二次加工・二次利用が可能だろう。&lt;/p&gt;
&lt;p class="clear"&gt;個人のライフログは全てオンラインに存在して、色々なサービスへ権限を与えることで過激に面白く加工してくれるんだろう、ブラウザのアクセス履歴は&lt;a href="http://pathtraq.com/"&gt;Pathtraq&lt;/a&gt;へ、IMEの変換履歴は&lt;a href="http://www.social-ime.com/"&gt;Social IME&lt;/a&gt;へ。&lt;/p&gt;
&lt;p class="clear"&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;さらに、DropboxはWebDAVと違ってユーザを待たせない、というかシンボリックリンクや同期の設定等を済ませれば&lt;/p&gt;
&lt;p class="clear"&gt;普通に生活しているだけでオンラインストレージとデータが保存されている。あとはそれを見たい人 or 加工したいWebサービスへ権限を与えておくだけだ。&lt;/p&gt;
&lt;p class="clear"&gt;基本的にユーザの時間を邪魔しない、これは重要だと思う。&lt;/p&gt;
&lt;p class="clear"&gt;&lt;/p&gt;
&lt;p class="clear"&gt;&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p style="font: 12.0px Helvetica"&gt;インターネットでどんなサービスを使うにしても、時間をかけないではできない。だからユーザが新しいサービスを使いはじめるには、今まで使っていた何かを止めないといけないし(自分はtumblrのdashboardをみはじめてdiggを見るのを止めた)、今使っているサービスを、新しいサービスを使うために使わなくなったりする(twitterをつかいはじめてmixiをやめた、とか)。&lt;/p&gt;

  &lt;p style="font: 12.0px Helvetica"&gt;&lt;a href="http://ido.nu/kuma/2008/03/09/era-of-no-overhead-blogging/"&gt;ゼロオーバーヘッド・ブロギングの時代&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class="clear"&gt;この話を見てから、悶々と考えていたゼロオーバーヘッドなサービス、Dropboxは何気に満たしているなと思う&lt;/p&gt;
&lt;p class="clear"&gt;今までもFTPを使ってファイルをサーバへアップロードすればオンラインストレージへ溜めておくことはできた、WebDAVでも良いけど、でも「全ファイル」するのはコストがかかりすぎてできなかったし誰もやろうと思わなかった。cronやスケジューラとスクリプトを頑張って書けば全自動も可能だろう、でもその手間は一般人にとって相当なコストだ。&lt;/p&gt;
&lt;p class="clear"&gt;でも現実に、近い将来全データをオンラインストレージへ保存することは可能になりつつある、これはAmazon S3でストレージ容量が劇的に下がったのも大きいだろうし、その土台はHDDやメモリ・CPUのチープ革命が支えてるんだろう。&lt;/p&gt;
&lt;p class="clear"&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040944"/&gt;</description>
      <pubDate>2008-04-10</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/416-rsync-subversion-amazon-s3-dropbox</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040944/416-rsync-subversion-amazon-s3-dropbox</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/416-rsync-subversion-amazon-s3-dropbox</feedburner:origLink></item>
    <item>
      <title>画像検索サービスEvernote</title>
      <description>&lt;p&gt;ベータ中のOCRサービスEvernote ↓&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jp.techcrunch.com/archives/extend-your-brain-with-evernote-private-beta-invites/"&gt;Evernoteで自分の脳を拡張する（プライベートベータご招待）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;のベータサービスアカウントが届いたので試してみた。サインアップページから本登録&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.skitch.com/20080316-n6t84urg7s4g3ur9yftca543i2.jpg" width="495" height="337" alt="Evernote Invitation-only Beta - Firefox (Build 0000000000)" /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;CAPTCHAがある。。。&lt;/p&gt;
&lt;p&gt;さっそく試してみよう、Evernoteのスキャン力とCAPTCHA、どっちが上か？&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.skitch.com/20080316-xpe719wcasya3nagarxb5k5phi.jpg" alt="Evernote" width="493" height="366" /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;一文字目 "b" は認識&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.skitch.com/20080316-renccanpmp2b46xufypnt5g5bt.jpg" alt="Evernote" width="494" height="324" /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;二文字 "b8" は無理。。：(&lt;/p&gt;
&lt;p&gt;もう少し弱いCAPTCHAなら解けるかも、ってところか。色々試してみたけど、なかなか性能良い印象。&lt;/p&gt;
&lt;p&gt;あとメールに写真を添付して投稿もできる。日本語は未対応ぽい。&lt;/p&gt;
&lt;p&gt;ここから&lt;a href="http://www.evernote.com/prereg/"&gt;登録&lt;/a&gt;して、二週間待ちくらいでアカウント届いた。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p&gt;で、関係ないけど最近読んだ本の話を少し&lt;/p&gt;
&lt;p style="text-align:center"&gt;&lt;/p&gt;
&lt;div style="text-align: left;"&gt;
  &lt;img src="http://ecx.images-amazon.com/images/I/2133ZP0M5EL.jpg" /&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div class="clear" style="text-align: left;"&gt;
  &lt;a href="http://www.amazon.co.jp/gp/redirect.html%3FASIN=415011451X%26tag=adriaantijsse-20%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/415011451X%253FSubscriptionId=0PZ7TM66EXQCXFVTMTR2"&gt;&lt;/a&gt;&lt;a href="http://www.amazon.co.jp/gp/redirect.html%3FASIN=415011451X%26tag=adriaantijsse-20%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/415011451X%253FSubscriptionId=0PZ7TM66EXQCXFVTMTR2"&gt;"しあわせの理由 (ハヤカワ文庫SF)" (グレッグ イーガン)&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;「しあわせの理由」はグレッグイーガンの短編集で、中身も面白かったけど文末の解説が面白かった。&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;span style="font-style: italic;"&gt;　円周率というものを完全に記述するのに無限のメモリーが絶対必要かというとそんなことはない。「無限のメモリーさえあれば、無限に計算を続けられる円周率計算 のプログラム」は実は有限のメモリーに収められるからだ。「つまりこのプログラムで 計算した数」と定義することで、本来無限のメモリーの必要な情報を、有限の情報のみ で完全に記述できてしまう。&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;

  &lt;p&gt;&lt;span style="font-style: italic;"&gt;・・・・・・・&lt;/span&gt;&lt;/p&gt;

  &lt;p&gt;&lt;span style="font-style: italic;"&gt;　ついでにもっと妙なことを考えてみよう、０から９までの数字とAからZまでの英大文字、それにスペースや記号であわせて四十文字ぐらいあれば英語の文章が作れる。 この文字に二桁の背番号を振る。０は「00」、9は「09」でAは「10」、スペースは 「36」という具合だ。円周率は数字がバラバラに並んでいて無限に続くのだから、その中には何兆桁目かもれないが、どこかに&lt;/span&gt;&lt;/p&gt;&lt;span style="font-style: italic;"&gt;「0200010009010136201022182010351436233436322912」&lt;/span&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
  &lt;span style="font-style: italic;"&gt;と続いている部分が必ずあるはずだ。この数字列を上の背番号表で解読すると&lt;/span&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
  &lt;span style="font-style: italic;"&gt;「&lt;/span&gt;&lt;strong&gt;&lt;span style="font-style: italic;"&gt;20010911 KAMIKAZE NY WTC&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-style: italic;"&gt;」&lt;/span&gt;&lt;br /&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
  &lt;span style="font-style: italic;"&gt;となる。すごいでしょ。この調子でいけば、いままでの人類の過去から未来までの悠久の歴史すべてを円周率の中に読み取ることができるだろう。たかだか有限のノストラダムスの詩文の中から無理してこじつけるより、はるかに確実な無限の大予言・それが有限のプログラムから生み出される。&lt;/span&gt;

  &lt;p&gt;&lt;span style="font-style: italic;"&gt;（坂村 健）&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;と、そこから「円周率に意味を見いだすのは、見ている自分自身」という話から、イーガンの作品解説に繋がっていく（確かに&lt;a href="http://www.ringolab.com/note/daiya/archives/004829.html"&gt;順列都市&lt;/a&gt;なんてこの話そのもの）で、これはこれで面白かった。でも、その後に偶然読んだこれ ↓&lt;/p&gt;
&lt;div style="text-align: left;"&gt;
  &lt;img src="http://ecx.images-amazon.com/images/I/210EKMJ3N8L.jpg" /&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div class="clear" style="text-align: left;"&gt;
  &lt;a href="http://www.amazon.co.jp/gp/redirect.html%3FASIN=4003279212%26tag=adriaantijsse-20%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/4003279212%253FSubscriptionId=0PZ7TM66EXQCXFVTMTR2"&gt;&lt;/a&gt;&lt;a href="http://www.amazon.co.jp/gp/redirect.html%3FASIN=4003279212%26tag=adriaantijsse-20%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/4003279212%253FSubscriptionId=0PZ7TM66EXQCXFVTMTR2"&gt;"伝奇集 (岩波文庫)" (J.L. ボルヘス)&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;の中の「バベルの図書館」この解説は&lt;a href="http://www.google.co.jp/search?hl=ja&amp;amp;client=firefox-a&amp;amp;rls=org.mozilla%3Aen-US%3Aunofficial&amp;amp;hs=AgW&amp;amp;q=%E3%83%90%E3%83%99%E3%83%AB%E3%81%AE%E5%9B%B3%E6%9B%B8%E9%A4%A8+%E3%83%9C%E3%83%AB%E3%83%98%E3%82%B9&amp;amp;btnG=%E6%A4%9C%E7%B4%A2&amp;amp;lr="&gt;ネットに山ほど転がっている&lt;/a&gt;と思うので、乱暴に要約すると「無限の広さを持ち無限の本数の蔵書がある図書館」の話で、その中でも全く同じテーマが語られていて&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;span style="font-style: italic;"&gt;ある天才的な司書が図書館の基本的な法則を発見した。この思想家のいうには、いかに多種多様であっても、全ての本は行間、ピリオド、コンマ、アルファベットの二十五字という、おなじ要素からなっていた。また彼は、全ての旅行者が確認するに至ったある事実を指摘した。&lt;/span&gt;&lt;/p&gt;

  &lt;p&gt;&lt;span style="font-style: italic;"&gt;広大な図書館に、同じ本は二冊ない。彼はこの反論の余地のない前提から、図書館は全体的なもので、その書棚は二十数個の記号のあらゆる可能な組み合わせを、換言すれば、あらゆる言語で表現可能なもののいっさいをふくんでいると推論した。&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;思い返せば、昔読んだ「&lt;a href="http://www.amazon.co.jp/%E7%A0%82%E3%81%AE%E6%9C%AC-%E9%9B%86%E8%8B%B1%E7%A4%BE%E6%96%87%E5%BA%AB-%E3%83%9C%E3%83%AB%E3%83%98%E3%82%B9/dp/4087602400"&gt;砂の本&lt;/a&gt;」も全く同じテーマだったのに、当時は気付かなかった。&lt;strong&gt;無限&lt;/strong&gt;に続く本や図書館（や数字）があるとして、その中には人類の、過去全ての歴史だけでなく未来の出来事も全て書いてあるのか・・・「3/15 ブログでボルヘスについて書く」という文章も確実に書いてある！&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p&gt;で、その無限の知識を持つ「砂の本」でも「バベルの図書館」でも、結局人間は何もできずに翻弄されるだけってのが面白いな。「砂の本」も「バベルの図書館」にも索引（インデックス）が無くて、結局人間が扱えるものじゃなかった。&lt;/p&gt;
&lt;p&gt;逆に言うともし「砂の本」に索引が付いてたり、「バベルの図書館」に全てを理解した司書（文中では「書物の人」と表現されている）がいれば、無限の知識を人間が利用することができる。「書物の人」は文中では&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;span style="font-style: italic;"&gt;他の&lt;/span&gt;&lt;strong&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: normal;"&gt;すべての本の鍵であり完全な要約である&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-style: italic;"&gt;一冊の本が存在し、ある司書がそれを読みとおし、神に似た存在となった。&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;と表現されている。無限の情報を持つ「バベルの図書館」よりも、その要約である一冊の本の方に価値がある。&lt;/p&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p&gt;これ、Web上に無限に近い情報があっても Google が持つ索引（インデックス）を使って要約を提供してくれないと、上手く活用することができない。ってのに通じるし、AutoPagerizeやLDRizeが広まったことでメタデータの重要性が高まってきているのにも通じると感じた。無限のデータもメタデータがあって初めて価値がでる。&lt;/p&gt;
&lt;p&gt;無理矢理話を最初のEvernoteに戻すと、、Evernoteの技術は面白いし凄い。ただ個人が持ってる少量のデータなんて大したことないんだから、Web全体の画像を対象にしてメタデータを付けてくれたら面白いな。&lt;/p&gt;
&lt;p&gt;これ、半年後になってみたら、EvernoteがGoogleに買収されててGoogle Image searchとして実現されてたりして。&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040945"/&gt;</description>
      <pubDate>2008-03-16</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/415-evernote</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040945/415-evernote</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/415-evernote</feedburner:origLink></item>
    <item>
      <title>デブサミ2008 - 「言語の現在・過去・未来を語る」メモ</title>
      <description>&lt;div class="slim"&gt;
  &lt;p&gt;今週、developer summit 2008に行ってきたのでメモ。&lt;/p&gt;

  &lt;p&gt;&lt;a href="http://www.seshop.com/event/dev/2008/timetable/Default.asp?mode=detail&amp;amp;eid=105&amp;amp;sid=607&amp;amp;tr=09_DevelopmentStyle(Special)#607"&gt;ネットコミュニケーション 2.0&lt;/a&gt; が面白かったけど、これのレポートは山ほど見かけるので&lt;/p&gt;

  &lt;p&gt;&lt;a href="http://www.seshop.com/event/dev/2008/timetable/Default.asp?mode=detail&amp;amp;eid=105&amp;amp;sid=555&amp;amp;tr=05_DevelopmentStyle(Language+%26+API)#555"&gt;言語の現在・過去・未来 - まつもとゆきひろ・波村大悟&lt;/a&gt; このセッションのメモを残しておきます。&lt;/p&gt;&lt;br /&gt;

  &lt;p&gt;その他、見つけた範囲では&lt;/p&gt;

  &lt;p&gt;・ C# についてのまとめは、こちらが詳しい &lt;a href="http://d.hatena.ne.jp/NyaRuRu/20080215/p3"&gt;【13-B-7】言語の現在・過去・未来を語る』話題メモ - C# side - NyaRuRuの日記&lt;/a&gt;&lt;/p&gt;

  &lt;p&gt;・ Matz日記　&lt;a href="http://www.rubyist.net/~matz/20080213.html"&gt;デブサミ2008 1日め (ディープな1日)&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;

  &lt;h2&gt;言語の現在・過去・未来を語る&lt;/h2&gt;

  &lt;p&gt;&lt;br /&gt;
  &amp;lt;&amp;lt;自己紹介&amp;gt;&amp;gt;&lt;/p&gt;

  &lt;p&gt;まつもとゆきひろ（以下：ま）&lt;br /&gt;
  15年前から趣味でRubyを開発、現在は本業へ&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  波村大悟（以下：波）&lt;br /&gt;
  MS US本社でC#開発、テストリード。C# 開発の初期から参加&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;&amp;lt;Ruby, C#の開発体制&amp;gt;&amp;gt;&lt;/p&gt;

  &lt;p&gt;波：&lt;/p&gt;

  &lt;p&gt;・Develop team（実装）, Test team（テスト）, Design team（言語デザイン） の三チームとPM、と「C#の父」アンダース。合計約20人くらい？&lt;/p&gt;

  &lt;p&gt;・Test teamとDevelop teamの違いは、５つある機能のうち「一つでも動けばPerfectly！と言うのがDevelop team」「一つでも動かないとダメ！と言うのがTest team」&lt;/p&gt;

  &lt;p&gt;　＞Test teamも開発に関わる（？）&lt;/p&gt;

  &lt;p&gt;・週三回のデザインMtg&lt;/p&gt;

  &lt;p&gt;・ユーザ＆一般開発者の要望を取り込みつつ、最後はアンダースが設計を決める。　＞「マクロが欲しい」は良く上がってくるが大抵アンダースが却下（笑&lt;/p&gt;

  &lt;p&gt;ま：&lt;/p&gt;

  &lt;p&gt;・日本語／英語のML (ruby-dev) でコミュニケーション・「こんな機能よくない？」「じゃあ入れよう」&lt;/p&gt;

  &lt;p&gt;・柔軟、反面だれもやりたがらない機能はなかなか実装されない&lt;br /&gt;&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  &amp;lt;&amp;lt;非互換性 =&amp;gt; 言語の進化&amp;gt;&amp;gt;&lt;/p&gt;

  &lt;p&gt;波：&lt;br /&gt;&lt;/p&gt;

  &lt;p&gt;・C#は結構大きく変化している&lt;/p&gt;

  &lt;p&gt;　＞ジェネリクスは C# 1.0 の開発＆リリースと平行して開発された、C# 2.0としてリリースする前に丸ごと書き直されたけど。かなり大きな変化&lt;/p&gt;

  &lt;p&gt;・言語が大きくVerアップして進化するとき、非互換性が問題になりやすい。&lt;/p&gt;

  &lt;p&gt;　＞MSのサポート規模を考えると、非互換性はまずい（10年は機能を保証。機能の削除できない）&lt;/p&gt;

  &lt;p&gt;・Rubyはどうか？&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  ま：&lt;/p&gt;

  &lt;p&gt;・そんなに気にしない、そろそろ1.9で「ぎゃ！」と皆に言ってもらわないと (笑&lt;/p&gt;

  &lt;p&gt;・オープンソースコミュニティは鮫、開発が止まると死ぬ。常に進化し続けることがオープンソースコミュニティを駆動する。&lt;/p&gt;

  &lt;p&gt;・駄目な部分は直す。&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  波：&lt;/p&gt;

  &lt;p&gt;・C#にも直したい設計はある。使う前から完璧な設計は難しい。（nullの扱い、voidの扱い）&lt;/p&gt;

  &lt;p&gt;・言語は言語設計者の想像しない所で、思わぬ使い方をされる。非互換性は意外な部分で出る（イテレータのMSIL（中間言語）コードを変更しただで苦情がきた）&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  &lt;br /&gt;
  ま：&lt;/p&gt;

  &lt;p&gt;・Rubyも開発当初はWebなんてなかった、ましてRailsなんて想像のしようがない。（言語は設計者の想像しない範囲で使われる）&lt;/p&gt;

  &lt;p&gt;・PowerPointは「プレゼンテーション」しかできない、プログラミング言語は「何でも」できてしまう。範囲が広い。&lt;/p&gt;

  &lt;p&gt;・範囲が広いから15年続いたのかも&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  波：15年は凄い、モチベーションの維持は？&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  ま：&lt;/p&gt;

  &lt;p&gt;・常に新しいテーマが生まれてくる&lt;/p&gt;

  &lt;p&gt;　＞Hello worldを表示するのに半年（IOクラス作って、Stringクラス作って、、）&lt;/p&gt;

  &lt;p&gt;　＞GCに手を付けて一年&lt;/p&gt;

  &lt;p&gt;・JavaとRubyは実は同じ年&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  波：&lt;/p&gt;

  &lt;p&gt;・そのJavaも最近では動的型付言語によってきている&lt;/p&gt;

  &lt;p&gt;・アンダースも最近は「RubyにできてC#にできないわけがない！Rubyのこの機能を取り込め！」と言っている（笑&lt;/p&gt;

  &lt;p&gt;　＞動的型付とメタプログラミング&lt;/p&gt;

  &lt;p&gt;　＞暗黙的型付け、型宣言を var で （　var x = new X();　）&lt;/p&gt;

  &lt;p&gt;　　＞C# 1.0の頃から可能だったが、スクリプト言語と間違われるのが嫌でやめた&lt;/p&gt;

  &lt;p&gt;　　＞当時はスクリプト言語の地位が低かった&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  ま：&lt;/p&gt;

  &lt;p&gt;C#はコンパイル時に実現しているので大変そう、でも開発環境でエディタの補完等はやりやすい&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  波：&lt;/p&gt;

  &lt;p&gt;CodeGearが Ruby &amp;amp; Rails のコード補完をやっているが、あれはランタイムを実行？&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  ま：&lt;/p&gt;

  &lt;p&gt;・多分そう、エディタの裏でRubyランタイムを実行している。&lt;/p&gt;

  &lt;p&gt;・C#も6.0 くらいではタイプリファレンスで凄いことに（？・・聞き取れず）&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  波：丁度今考えているとこ・・・・&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  &amp;lt;&amp;lt; LINQ &amp;gt;&amp;gt;&lt;/p&gt;

  &lt;p&gt;ま：LINQのクエリ式は思い切った変更だと思う&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  波：あの構文を正式に決定するのに相当時間がかかった&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  （例を出す）&lt;/p&gt;

  &lt;p&gt;var hoge = from x in Products&lt;/p&gt;

  &lt;p&gt;　　　　　where x.ID == 100&lt;/p&gt;

  &lt;p&gt;　　　　　select x;&lt;/p&gt;

  &lt;p&gt;ま：&lt;/p&gt;

  &lt;p&gt;・言語設計者的には入れたくない。よくアンダースが許した（笑&lt;/p&gt;

  &lt;p&gt;・&lt;a href="http://itpro.nikkeibp.co.jp/article/COLUMN/20070606/273878/?P=5"&gt;HaskleやPythonのリスト内包表現&lt;/a&gt;を真似るなら from より for では？&lt;/p&gt;

  &lt;p&gt;&lt;br /&gt;
  波：&lt;/p&gt;

  &lt;p&gt;・「俺の言語を汚すな」と言っていた（笑、最初一年は反対していた&lt;/p&gt;

  &lt;p&gt;・from ではなく当初は foreach文を拡張することも検討した&lt;/p&gt;

  &lt;p&gt;　foreach(var x in Products) . where x.ID == 1&lt;/p&gt;

  &lt;p&gt;・RailsのO/Rマッピングも凄い、テーブル定義からマッピングをダイナミックにやっていて驚いた&lt;br /&gt;&lt;/p&gt;

  &lt;p&gt;・LINQは一人のエンジニアが実装を担当している&lt;/p&gt;

  &lt;p&gt;　・凄い、機械みたいなやつ&lt;/p&gt;

  &lt;p&gt;　・急に静かになったと思ったら、大量のコードを一気にコミットしてた（笑&lt;/p&gt;

  &lt;p&gt;　&lt;/p&gt;

  &lt;p&gt;&amp;lt;&amp;lt;RubyにLINQ&amp;gt;&amp;gt;&lt;/p&gt;

  &lt;p&gt;ま：&lt;/p&gt;

  &lt;p&gt;・（ブロックとメソッドのチェーンでやると？）パフォーマンスが問題&lt;/p&gt;

  &lt;p&gt;・Rubyの構文木をCで取り出してSQLにしている連中がいた（笑 、パフォーマンスも問題ないと言っていた&lt;/p&gt;

  &lt;p&gt;　&amp;gt;&amp;gt; 多分これ？ &lt;a href="http://www.infoq.com/jp/news/2007/10/data-query-with-ambition"&gt;http://www.infoq.com/jp/news/2007/10/data-query-with-ambition&lt;/a&gt;&lt;/p&gt;

  &lt;p&gt;　&lt;/p&gt;

  &lt;p&gt;&amp;lt;&amp;lt;言語設計の醍醐味&amp;gt;&amp;gt;&lt;/p&gt;

  &lt;p&gt;ま：言語でどうやって表現するか？言語は人間の考えに影響を与える&lt;/p&gt;

  &lt;p&gt;波：できなかったことを可能にする。機械語でも理論上できるはずだが現実には高級言語でないと不可能なことがある&lt;/p&gt;

  &lt;p&gt;　&lt;/p&gt;

  &lt;p&gt;&amp;lt;&amp;lt;Ruby &amp;amp; C# のうらやましいところ&amp;gt;&amp;gt;&lt;/p&gt;

  &lt;p&gt;ま：膨大なリソース（Microsoft）を使って開発できることがうらやましい。&lt;/p&gt;

  &lt;p&gt;波：オープンソースのフレキシブルさがうらやましい。Microsoftではオープンソースへの参加も難しい&lt;/p&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040946"/&gt;</description>
      <pubDate>2008-02-29</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/414-2008</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040946/414-2008</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/414-2008</feedburner:origLink></item>
    <item>
      <title>On Lisp「22章 非決定性」をRubyで試してみる</title>
      <description>&lt;p style="text-align: left;"&gt;&lt;img src="http://ecx.images-amazon.com/images/I/21BYBlSsmXL.jpg" width="114" height="160" /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;&lt;a href="http://www.amazon.co.jp/gp/redirect.html%3FASIN=4274066371%26tag=adriaantijsse-20%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/4274066371%253FSubscriptionId=0PZ7TM66EXQCXFVTMTR2"&gt;"On Lisp―Advanced Techniques for Common Lisp" (Paul Graham)&lt;/a&gt;&lt;/p&gt;
&lt;p class="clear"&gt;を読んだ。&lt;/p&gt;
&lt;p&gt;・Lispの基礎から、マクロ、遅延評価、Schemeと継続、継続をCommonLispで実装して、継続を使った非決定的アルゴリズムの実装、Prolog&lt;/p&gt;
&lt;p&gt;初めて関数型プログラミング、というかLispを勉強した身にとっては全編興味深い、特に22章の「非決定性」が面白かった。&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://user.ecc.u-tokyo.ac.jp/~tt076524/onlispjhtml/nondeterminism.html"&gt;On Lisp - 非決定性&lt;/a&gt;&lt;/p&gt;

  &lt;p&gt;非決定的アルゴリズムはある意味では超自然的な予見に基づいて動作するものだ．超能力を持ったコンピュータに触れることのない私達に，どうしてそんなものが必要なのだろうか？\ それは非決定的アルゴリズムを決定的アルゴリズムでシミュレートできるからだ．純粋に関数的なプログラム ---すなわち副作用の一切ないもの--- では，非決定性は特に直截的になる．純粋に関数的なプログラムでは非決定性はバックトラックを用いた探索で実現できる．&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;バックトラックによる非決定性の実装例が紹介されてる、乱暴に言うと「複数の選択肢がある時、その時点の継続を保存し&lt;strong&gt;とりあえず&lt;/strong&gt;一つの選択肢を選んで処理を続ける。成功すればOK、もし選択が失敗してた場合選択前の過去に戻って、別の選択肢を選んで処理を継続する」で良いのかな。&lt;/p&gt;
&lt;p&gt;とりあえず理解のためにRubyで実装してみた。&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;span class="keyword"&gt;class&lt;/span&gt; Nond
  &lt;span class="keyword"&gt;def&lt;/span&gt; initialize
    @paths = []
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def&lt;/span&gt; choose(choises)
    &lt;span class="keyword"&gt;if&lt;/span&gt; choises.empty?
      failed
    &lt;span class="keyword"&gt;else&lt;/span&gt;
      &lt;span class="keyword"&gt;return&lt;/span&gt; callcc &lt;span class="keyword"&gt;do&lt;/span&gt; |c|
        @paths.unshift(lambda{ c.call( choose(choises[&lt;span class="num"&gt;1&lt;/span&gt;..choises.length]) ) })
        choises[&lt;span class="num"&gt;0&lt;/span&gt;]
      &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def&lt;/span&gt; failed
    &lt;span class="keyword"&gt;if&lt;/span&gt; @paths.empty?
      raise &lt;span class="str"&gt;"Can't find more choises."&lt;/span&gt;
    &lt;span class="keyword"&gt;else&lt;/span&gt;
      @paths.shift.call
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ruby1.8 にも継続があるので、ほぼ本のまま。試してみる。&lt;/p&gt;
&lt;pre class="source"&gt;
@nond = Nond.new

&lt;span class="keyword"&gt;def&lt;/span&gt; parlor_trick(sum, firsts, secounds)
  first = @nond.choose(firsts)
  secound = @nond.choose(secounds)

  &lt;span class="keyword"&gt;if&lt;/span&gt; sum == first + secound
    &lt;span class="str"&gt;"The sum of #{first} #{secound}"&lt;/span&gt;
  &lt;span class="keyword"&gt;else&lt;/span&gt;
    @nond.failed
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

p parlor_trick(7, [&lt;span class="num"&gt;1&lt;/span&gt;,&lt;span class="num"&gt;2&lt;/span&gt;,&lt;span class="num"&gt;3&lt;/span&gt;,&lt;span class="num"&gt;4&lt;/span&gt;,&lt;span class="num"&gt;5&lt;/span&gt;], [&lt;span class="num"&gt;1&lt;/span&gt;,&lt;span class="num"&gt;2&lt;/span&gt;,&lt;span class="num"&gt;3&lt;/span&gt;,&lt;span class="num"&gt;4&lt;/span&gt;])
&lt;/pre&gt;
&lt;p&gt;二組の数字のリストから加算の結果が sum と等しい組み合わせを返す。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.skitch.com/20080210-mkmuxy72gcqhjrncgjtnr9hibm.jpg" alt="30BF30FC30DF30CA30EB 2014 screen 2014" /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;実行してみると確かに3と4で7になってる。&lt;/p&gt;
&lt;p&gt;もう一例、今度は名前のリストから "Igor" を見つける&lt;br /&gt;&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;span class="keyword"&gt;def&lt;/span&gt; igor(names)
  name = @nond.choose(names)
  &lt;span class="keyword"&gt;if&lt;/span&gt; name==&lt;span class="str"&gt;"Igor"&lt;/span&gt;
    p &lt;span class="str"&gt;"Found Igor!"&lt;/span&gt;
  &lt;span class="keyword"&gt;else&lt;/span&gt;
    @nond.failed
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

p igor([&lt;span class="str"&gt;"Yakov"&lt;/span&gt;, &lt;span class="str"&gt;"Yulli"&lt;/span&gt;, &lt;span class="str"&gt;"Raisa"&lt;/span&gt;, &lt;span class="str"&gt;"Iwan"&lt;/span&gt;, &lt;span class="str"&gt;"Igor"&lt;/span&gt;, &lt;span class="str"&gt;"Daniel"&lt;/span&gt;, &lt;span class="str"&gt;"Egor"&lt;/span&gt;])
&lt;/pre&gt;&lt;img src="http://img.skitch.com/20080210-x6puyfff1myrck5kc4r2hrwn4x.jpg" alt="30BF30FC30DF30CA30EB 2014 screen 2014 170" /&gt;
&lt;p&gt;　&lt;/p&gt;
&lt;p class="clear"&gt;肝の関数 choose と fail の実装を見れば納得できるけど、アプリケーションのコードだけを見るとまるで choose が超能力で正解を導き出したように見える、その実装も「失敗したら過去に戻ってやり直す」てのは凄いな。&lt;/p&gt;
&lt;p&gt;この22章非決定性の発展で、24章ではLispの埋め込み言語としてPrologを実装してるけど、ここまでいくと正直理解があいまい。。また読み直そう&lt;/p&gt;
&lt;p&gt;&lt;a href="http://user.ecc.u-tokyo.ac.jp/~tt076524/onlispjhtml/prolog.html"&gt;On Lisp - Prolog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Prolog面白そうだな、どこから勉強するのが良いんだろ。とっかかりとして。&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040947"/&gt;</description>
      <pubDate>2008-02-07</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/413-on-lisp-22-ruby</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040947/413-on-lisp-22-ruby</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/413-on-lisp-22-ruby</feedburner:origLink></item>
    <item>
      <title>Google Social Graph API と fooo.name</title>
      <description>&lt;h2&gt;Google Social Graph API&lt;/h2&gt;
&lt;p&gt;Googleが面白いAPIを出した、Web上にあるソーシャル情報に関するメタデータ（XFNとFOAF）をGoogleがクロールしてWebAPI化する &lt;a href="http://code.google.com/apis/socialgraph/"&gt;Google Social Graph API&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;これに合わせて &lt;a href="http://fooo.name/"&gt;fooo.name&lt;/a&gt; の本人リンクにも、メタデータとして rel="me" を付けました（メタデータ的に "me" は意味が間違っている気もするけど）&lt;a href="http://fooo.name/accounts/tkmr"&gt;http://fooo.name/accounts/tkmr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;これでfooo.nameが整えたデータもGoogle APIに反映されるかな。そういえば昔 fooo.nameでもXFN解析やろうかなと思ったけど「XFNなんてどうせ誰もつけてねえよ」と思って無視してた、でもこう見ると意外に面白いな。。&lt;/p&gt;
&lt;p&gt;例えばTwitter、Twitterは "me" や "contact" というXFNのメタデータを埋め込んでいるので上手くソーシャルグラフが取れてる。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://socialgraph-resources.googlecode.com/svn/trunk/samples/findcontacts.html?q=http%3A%2F%2Ftwitter.com%2Ftkmr"&gt;http://socialgraph-resources.googlecode.com/svn/trunk/samples/findcontacts.html?q=http%3A%2F%2Ftwitter.com%2Ftkmr&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;逆にXFNやFOAFを埋め込んでないサイトの関係は取れない、http://blog.tkmr.org/ と http://twitter.com/tkmr が "me" の関係なのは自分（や一部の人）は判るけどメタデータとしてマークアップしてないのでGoogleには判らない。まあ当然の話だけど。&lt;/p&gt;
&lt;h2&gt;メタデータ&lt;/h2&gt;
&lt;p&gt;Social Graph API に近い目的をもった&lt;a href="http://fooo.name/"&gt;fooo.name&lt;/a&gt; はSocial Graph API があれば要らないか？と考えると、fooo.nameは他人がメタデータを補完する、Social Graph APIは本人が書いたorシステムが書いたメタデータを集める。レイヤーの違いというポジションがあるかも。fooo.nameの利用者がカオスなWebにメタデータを補完してくれる。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.skitch.com/20080203-x23eduwxbimwsr98dqgdhcs9s8.jpg" /&gt;&lt;/p&gt;
&lt;p class="clear"&gt;Social Graph API はGoogleらしいアプローチで面白いし王道だと思う。でも現実的にWebの大部分にはメタデータが付いてないし、自分のサイトにリンクを貼るとき rel="me" を付ける人なんてネットユーザの1%にもすぎないと思う。&lt;/p&gt;
&lt;p&gt;例えば、皆が "次のページ" へのリンクにメタデータ rel="next" を付けるとAutoPagerize（とOpera）で超快適にネットブラウジングできるけど、それを強制することはできないし、なかなかそう上手くもいかないので AutoPagerizeはWikiで各サイトのメタデータ（SITEINFO）を登録して人間が補完している。なんだかんだで microformats が本当に世界中で整備されるのは、Web 99.0 ぐらいまで待つ必要があるのかなーと思う。ので今はある程度人間が補完する部分も必要なんじゃないかな；)&lt;/p&gt;
&lt;p&gt;ちなみにこの辺、otsuneさんが「メタデータとしてxFolkを付けよう」と啓蒙活動をしてて偉いと思う。&lt;a href="http://www.otsune.com/diary/2007/11/08/1.html#200711081"&gt;http://www.otsune.com/diary/2007/11/08/1.html#200711081&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;Googleと分散クローラ&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;結局、XFNやFOAFをクロールするだけなら、今回Googleは技術的に大した事やってないとも言える。まあ、それは冗談として；D&lt;/p&gt;
&lt;p&gt;Googleは数億オーダーのデータを扱える、その量が凄い。数千台のサーバ群が常時動いててWebをクロールしまくってる、でクロールしたテラバイト級のデータをGFSなんかにガンガンぶちこんで、MapReduceで数千台規模のサーバ群が解析する。想像だけどおおまかにこんな情報工場が24時間365日フル稼働してるんだと思う。十二分に凄い。&lt;/p&gt;
&lt;p&gt;これと同じことを個人でやるのは余りにもつらい、、のでオープンな分散Webクローラがあれば面白いのかなと最近思う。常時Webをクロールし続けるサーバ群のP2Pネットワークがあって、URLのドメインとかをキーにして分散ハッシュテーブル的に目的のピアを探索する、とか。XPathで //a[@rel="me"] とクエリーを投げるとマッチするページを返す、とか。&lt;/p&gt;
&lt;p&gt;- *.user.jsというファイル名&lt;/p&gt;
&lt;p&gt;- @include http://example.com/* という文字列が含まれる&lt;/p&gt;
&lt;p&gt;ページを探すクエリーを投げる事ができれば、http://example.com 向けのGreasemonkeyスクリプトのリストを取れる。とか色々できそう。&lt;/p&gt;
&lt;p&gt;「ネットに 繋がってないパソコン ただの箱」じゃないけど、Webにある情報だけで十分相当な事ができる。ちょうど今日クリップボードをWebで共有するサービス &lt;a href="http://jp.techcrunch.com/archives/controlc-turning-cut-paste-into-a-web-service"&gt;ControlC&lt;/a&gt; というのを見つけて登録してみた。Win/Mac/Linux 用のネイティブアプリをインストールして、Ctrl+C するだけでWebにアップされるというサービスで「これは面白い！」と思ったけど、いざPCの中を探してもこれといってクリップしたい情報がない。しかたないのでWeb上のページをクリップ試してみたんだけど、これならTumblr + Tomblooで十分だった；D&lt;/p&gt;
&lt;p&gt;続々と情報にURLが付いてWebに繋がってきている、あとはWebから目的のデータを取り出すクエリーを変えるだけで相当色々な可能性があるのに、現状それを自由にできるのはGoogleだけでまだまだ試し尽くされていないってのはもったいない。&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;そういえば分散型クローラと言えば「&lt;a href="http://buzztter.com/ja"&gt;buzztter&lt;/a&gt;の裏側で動いているTwitter用クローラが、Twitterのトラフィックが膨大で大変。分散クローラを作りたい」という話も見た事がある&lt;/p&gt;
&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: 12px Helvetica;"&gt;&lt;/p&gt;
&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: 12px Helvetica;"&gt;&lt;a href="http://d.hatena.ne.jp/darashi/20071106/1194365071"&gt;[buzztter]buzztterの裏側とその周辺技術&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;twitterのデータをキャッシュしてインデックスし続けるサーバ群がいれば、今盛り上がっているキーワードを抽出するクエリー (buzztter) 以外にも、場所／時間で抽出するクエリ、@名前で行われるコミュニケーションの流れを抽出するクエリ、、まだまだ色々な切り出し方を試せると思う。&lt;/p&gt;
&lt;p&gt;Googleもきっと内部では、Webクローラが収集した一次データは各サービスで共有して、メインの検索用に加工した二次データ／イメージ検索用の二次データ／Social Graph API用の二次データ・・・とそれぞれ加工してる、んだと思う。極論すれば&lt;/p&gt;
&lt;p&gt;- イメージ検索 - //img&lt;/p&gt;
&lt;p&gt;- Social Graph API - //a[@rel="me"]&lt;/p&gt;
&lt;p&gt;と膨大な一次データからそれぞれ違うクエリーで切り出している、と言えなくもない。かも。&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040948"/&gt;</description>
      <pubDate>2008-02-04</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/412-google-social-graph-api-fooo-name</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040948/412-google-social-graph-api-fooo-name</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/412-google-social-graph-api-fooo-name</feedburner:origLink></item>
    <item>
      <title>[rails plugin] javascript_test - script.aculo.usのunittest.jsでTDD&amp;BDD</title>
      <description>&lt;p&gt;via &lt;a href="http://drnicwilliams.com/2008/01/04/autotesting-javascript-in-rails/"&gt;Dr Nic - Autotesting Javascript in Rails&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;script.aculo.usのunittest.jsを使ったRailsプラグインの &lt;a href="http://dev.rubyonrails.com/svn/rails/plugins/javascript_test/"&gt;javascript_test&lt;/a&gt; なかなか良さそう。generatorでテストのひな形作成、auto_testに対応してくれる。unittest.js単体もBDD的な記述、ベンチマーク、辺りが良い。&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;span class="comment"&gt;#インストール&lt;/span&gt;
ruby script/plugin install javascript_test
mkdir test/javascript
ln -s vendor/plugins/javascript_test/assets/ test/javascript/assets

&lt;span class="comment"&gt;#テスト作成&lt;/span&gt;
ruby script/generate javascript_test hoge
&amp;gt; create test/javascript/hoge_test.html
&amp;gt; create public/javascripts/hoge.js

&lt;span class="comment"&gt;#テスト書いて&lt;/span&gt;
&lt;span class="comment"&gt;# test/javascript/hoge_test.html&lt;/span&gt;
testTruth: function() {with(this) {
  assertEqual(X, &lt;span class="str"&gt;"hoge"&lt;/span&gt;);
}}

&lt;span class="comment"&gt;#実際のjsコード&lt;/span&gt;
&lt;span class="comment"&gt;# public/javascripts/hoge.js&lt;/span&gt;
X = &lt;span class="str"&gt;"hoge"&lt;/span&gt;;

&lt;span class="comment"&gt;#テスト実行&lt;/span&gt;
rake test&lt;span class="sym"&gt;:javascripts&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;手元のMacだとSafariとFireFoxが自動で立ち上がって、テスト結果が表示される筈&lt;/p&gt;
&lt;p&gt;&lt;img name="7c4f2f965a5a9d4550e6c68aaf75017d.png" height="197" width="764" src="http://gyazo.com/7c4f2f965a5a9d4550e6c68aaf75017d.png" style="" /&gt;&lt;/p&gt;
&lt;p&gt;BDD的に書きたくても大丈夫。String, Array, Number辺りの基本クラスを拡張して、shouldEqualみたいなメソッドを追加してくれる。&lt;/p&gt;
&lt;pre class="source"&gt;
Test.context(&lt;span class="str"&gt;"BDD-style testing"&lt;/span&gt;,{
  &lt;span class="str"&gt;"setup"&lt;/span&gt;: function(){
    console.log(&lt;span class="str"&gt;"Now setup!!"&lt;/span&gt;);
    hoge = &lt;span class="str"&gt;"Test"&lt;/span&gt;;
  },
  &lt;span class="str"&gt;"teardown"&lt;/span&gt;: function(){
    console.log(&lt;span class="str"&gt;"Now teardown!!"&lt;/span&gt;);
  },
  &lt;span class="str"&gt;"should automatically add methods to strings"&lt;/span&gt;: function(){
    hoge.shouldEqual(&lt;span class="str"&gt;"Test"&lt;/span&gt;);
    hoge.shouldNotEqual(&lt;span class="str"&gt;"HoHoHo"&lt;/span&gt;);
    hoge.shouldNotBeNull();
    hoge.shouldBeA(String);
    hoge.shouldNotBeA(Number);
  }
});
&lt;/pre&gt;
&lt;p&gt;unittest.jsについて、詳細はこちらのサイトが詳しい。&lt;/p&gt;
&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;&lt;/p&gt;
&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;&lt;a href="http://www.greenspace.info/mt/2007/02/sciptaculousuni.html"&gt;script.aculo.usのUnitTestの使い方 前編 - Yak blog&lt;/a&gt;&lt;/p&gt;
&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;&lt;/p&gt;
&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;&lt;a href="http://www.greenspace.info/mt/2007/02/22/scriptaculousun.html"&gt;script.aculo.us付属のユニットテスト(unittest.js)の使い方 後編 - Yak blog&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040949"/&gt;</description>
      <pubDate>2008-01-06</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/411-rails-plugin-javascript-test-script-aculo-us-unittest-js-tdd-bdd</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040949/411-rails-plugin-javascript-test-script-aculo-us-unittest-js-tdd-bdd</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/411-rails-plugin-javascript-test-script-aculo-us-unittest-js-tdd-bdd</feedburner:origLink></item>
    <item>
      <title>2008年書き初め</title>
      <description>&lt;p&gt;今年の書き初めはJavaScripでSchemeっぽい物、70行くらいで書き捨て。置く所が無かったのでAppJetに置いた。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://tk-scheme.appjet.net/"&gt;http://tk-scheme.appjet.net/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;AppJetは第三者の書いたコードを気軽に読み込み&amp;amp;実行できるのが良いな、eval(wget("http://hogehoge"))とか。最悪悪いコードが入って来ても困るのはappjet.netだし；D&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;"第三者のコードを気軽に実行できる" ってことで何か面白いことができないかな。&lt;/p&gt;
&lt;p&gt;例えば、GoogleのMapReduceを独自にオープン／分散／P2Pで実現しようと思うと、まずネックなのが（色々あるけど）実行ロジックをworkerへ送り込む方法だと思う。&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://blog.yappo.jp/yappo/archives/000549.html"&gt;GoogleのMapReduceをいまさら妄想した - YappoLogs&lt;/a&gt;&lt;/p&gt;

  &lt;p&gt;実際問題としてオレオレでMapReduce作る時に考える事は、データとコードを各worker serverに送る仕組みを真っ先に考えなければいけない。単純にjobを分散出来た所で、それはMQとかに毛が生えた程度の面白さしかないから&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;worker群がいて、そこへロジックと処理すべきデータを送り込む。データは良い、でもロジックはセキュリティとパフォーマンスの懸念が常にあって "絶対安全" というのが難しい、と思ってたけど実際こうやってAppJetが動いているのをみると、何とかなるかなと思ってくる。AppJetの場合サーバサイドJavaScriptを多分Rhinoとかで動かしてると思うんだけど、パフォーマンスのチェックとかはどうやってるんだ。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jp.techcrunch.com/archives/appjet-makes-simple-web-apps-a-breeze/"&gt;TechCrunch Japanese - AppJet、シンプルなウェブアプリ制作を簡単に&lt;/a&gt;&lt;/p&gt;世界中のPCの空きCPUを有効利用するのに、SETI@homeも面白いと思うけどオープンなMapReduceをやると面白いと思うんだけどな。今後放っといても絶対オープンにならない物だけに。&lt;br /&gt;
&lt;blockquote&gt;
  &lt;p&gt;新入社員がグーグルの発想のスケールに慣れるまでに数カ月はかかるという。「ある日、誰かが、数千台のコンピューターを一斉にぶん回すような“ヤバイ”仕事を考えつく。すると“ヤツは分かってきたみたいだな”ということになる」&lt;/p&gt;

  &lt;p&gt;&lt;a href="http://business.nikkeibp.co.jp/article/world/20071221/143754/"&gt;http://business.nikkeibp.co.jp/article/world/20071221/143754/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;こんな面白そうな話、放っとくのは勿体ない。&lt;/p&gt;
&lt;p&gt;で、あまり関係ないけどSchemeっぽい物を書き始めたけど、なんか違うな。Scheme on JavaScriptならもっとちゃんとしたのがあるし&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mono.kmc.gr.jp/~yhara/w/?BiwaScheme"&gt;BiwaScheme&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;なんだろ、(map 実行ロジック データリスト) と書いてmapが並列に分散する様な。いっそこんな感じにJavaScriptの配列で良いんじゃないか&lt;/p&gt;
&lt;p style="font-size:130%;"&gt;&lt;a href="http://scm-test.appjet.net/?code=[scm.map,%20function(n){return%20n*n;},%20[10,%2020,%2030,%2040]]"&gt;[scm.map, function(n){return n*n;}, [10, 20, 30, 40]]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;上手くまとまんない、もうちょっと考えてみよう。&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040950"/&gt;</description>
      <pubDate>2008-01-06</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/410-2008</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040950/410-2008</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/410-2008</feedburner:origLink></item>
    <item>
      <title>Railsプラグイン - ActiveJaxの密結合な実装にビックリ</title>
      <description>&lt;p&gt;ActiveJaxというRailsプラグインを見つけた&lt;/p&gt;
&lt;p&gt;&lt;img src="http://gyazo.com/004933cf1afafbab2c94d84753a27cc6.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rails.simpltry.com/active_jax.html"&gt;ActiveJax - Simpltry Rails&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;「ActiveRecordのモデルをJavaScriptから叩ける」と書いてあり、RESTなWebAPIを叩く&lt;a href="http://giantrobots.thoughtbot.com/2007/4/2/jester-javascriptian-rest"&gt;Jester&lt;/a&gt;の競合になりそうかな、と思ったら全然違った。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.tkmr.org/tatsuya/show/301-jester-restfull-rails-javascript"&gt;Jester-RESTfullなRails向けJavaScriptライブラリ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Jesterの場合はあくまでもRESTなWebAPIに向かって、それっぽいURLでアクセスする。Railsのscaffold resourceで作られたWebAPIを想定してるけど、細かくカスタムも可能で別にPerlでもPHPでもJava, C# 相手は何でも良い。&lt;/p&gt;
&lt;p&gt;ActiveJaxの場合は、ActiveRecordモデルの構造を見て動的にJavaScriptを作成しちゃう。こんな感じ&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;span class="comment"&gt;#Model&lt;/span&gt;
&lt;span class="keyword"&gt;def&lt;/span&gt; _active_jax_meta()
  @@active_jax_meta.values.each &lt;span class="keyword"&gt;do&lt;/span&gt; |ajc|
    &lt;span class="keyword"&gt;if&lt;/span&gt; ajc[&lt;span class="sym"&gt;:finders&lt;/span&gt;].empty?
      ajc[&lt;span class="sym"&gt;:finders&lt;/span&gt;] =  ajc[&lt;span class="sym"&gt;:class&lt;/span&gt;].public_methods.select { |m| m.match(&lt;span class="regex"&gt;/\Afind/&lt;/span&gt;)  }.reject { |m| ajc[&lt;span class="sym"&gt;:class&lt;/span&gt;].superclass.respond_to?(m) &amp;amp;&amp;amp; !m.match(&lt;span class="regex"&gt;/\Afind\Z/&lt;/span&gt;) &amp;amp;&amp;amp; !m.match(&lt;span class="regex"&gt;/\Afind_all\Z/&lt;/span&gt;) }
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
  @@active_jax_meta
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="comment"&gt;#Controller&lt;/span&gt;
&lt;span class="keyword"&gt;def&lt;/span&gt; js
  response.headers[&lt;span class="str"&gt;"Content-Type"&lt;/span&gt;] = &lt;span class="str"&gt;"text/javascript"&lt;/span&gt;
  Dir.glob(File.join(RAILS_ROOT, &lt;span class="str"&gt;"app"&lt;/span&gt;, &lt;span class="str"&gt;"models"&lt;/span&gt;) + &lt;span class="str"&gt;"/**/*.rb"&lt;/span&gt;).each { |f| require f }
  Dir.glob(File.join(RAILS_ROOT, &lt;span class="str"&gt;"app"&lt;/span&gt;, &lt;span class="str"&gt;"controllers"&lt;/span&gt;) + &lt;span class="str"&gt;"/**/*.rb"&lt;/span&gt;).each { |f| require f }
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="comment"&gt;#View  &lt;/span&gt;
&amp;lt;% ActiveRecord::Base._active_jax_meta.keys.each &lt;span class="keyword"&gt;do&lt;/span&gt; |klass| -&lt;span class="str"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="str"&gt;  ActiveJax.&amp;lt;%= klass.name.to_s -%&amp;gt;&lt;/span&gt; = {};
  &amp;lt;% klass.active_jax_finders.each &lt;span class="keyword"&gt;do&lt;/span&gt; |finder| -&lt;span class="str"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="str"&gt;    ActiveJax.&amp;lt;%= klass.name.to_s -%&amp;gt;&lt;/span&gt;.&amp;lt;&lt;span class="str"&gt;%= finder -%&amp;gt; =&lt;/span&gt; ActiveJax.query_function(&lt;span class="str"&gt;"/active_jax/service"&lt;/span&gt;, {klass: &lt;span class="str"&gt;"&amp;lt;%= klass.name.to_s -%&amp;gt;"&lt;/span&gt;, finder:&lt;span class="str"&gt;"&amp;lt;%= finder -%&amp;gt;"&lt;/span&gt;});
  &amp;lt;% &lt;span class="keyword"&gt;end&lt;/span&gt; -&lt;span class="str"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="str"&gt;&amp;lt;% end -%&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;「俺はRailsさえあれば良い！ペロカパ！」って人はこれでも良いんだろうけど、なんだこれ。ある意味凄い、ビックリ。Jesterと比べるとこんな感じ&lt;/p&gt;
&lt;p&gt;　・Jester = RESTfullなWebAPIを作ってくれれば、空気を読んでそれっぽいURIにアクセスするよ。カスタムも可能。サーバのことは知らない&lt;/p&gt;
&lt;p&gt;　・ActiveJax = ActiveRecordのクラス名やメソッドを解析して、それっぽいJavaScriptのオブジェクトを出力するよ。ControllerやViewは自動生成するから気にしないで；)&lt;/p&gt;
&lt;p&gt;みたいな。JesterみたいにWebAPIでサーバ &amp;amp; クライアントが分かれていると&lt;/p&gt;
&lt;p&gt;　・クライアント= Jester以外のライブラリから叩く、API公開して色々叩いてもらう&lt;/p&gt;
&lt;p&gt;　・サーバ = 重い機能をRails以外で書き直す&lt;/p&gt;
&lt;p&gt;と粗結合になって色々おいしい事がある。例えばの話で、はてブWebAPI用に作ったJavaScriptのUIでdel.icio.usを叩けたりする、Tumblr用のツールでsoup.ioが叩けたりする。（WebAPIが似ていれば）&lt;/p&gt;
&lt;p&gt;まあ明らかに書き捨てのWebアプリケーションとかなら、ActiveJax的な密結合も楽で良いけど。ちゃんとするなら、ちょっと面倒でも粗結合が良い、まあ当然の話で。&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040951"/&gt;</description>
      <pubDate>2007-12-08</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/408-rails-activejax</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040951/408-rails-activejax</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/408-rails-activejax</feedburner:origLink></item>
    <item>
      <title>自由にアクセス制御可能なJavaScriptサンドボックスを作る</title>
      <description>&lt;p&gt;
追記：早速破られた！
&lt;/p&gt;
&lt;pre&gt; 
safeCall("var w=(function(){return this;}).call();w.alert(w.document.cookie);");
id:kazuhooku - http://b.hatena.ne.jp/kazuhooku/20071206#bookmark-6709542
&lt;/pre&gt;
&lt;p&gt;
サイ本よく見ると確かに「オブジェクトのメソッドとして呼び出された関数内でも、入れ子にされた関数内のthisはグローバルオブジェクトを参照します」て書いてあった。あとMDCにも &lt;a href="http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Reference:Operators:Special_Operators:this_Operator"&gt;http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Reference:Operators:Special_Operators:this_Operator&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
=========
&lt;/p&gt;
&lt;p&gt;
面白い記事があった、GreasemonkeyのunsafeWindowを安全にすることは可能か
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://d.hatena.ne.jp/brazil/20071205/1196814940"&gt;[JavaScript] GM_xmlhttpRequestを使えなくする - 実用&lt;/a&gt;
&lt;br/&gt;
&lt;a href="http://d.hatena.ne.jp/ku0522/20071205/1196819346"&gt;GM評価のsandbox - ゼロメムはてな支店&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
この記事はGreasemonkeyのunsafeWindowについて（GM実行中サイトが悪意を持っていた場合 or XSSの穴が合った場合対策）だけど
自分もちょうど、JavaScriptを安全に実行する方法が無いか考えていたので、ここに書いてみる。まず目的は
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;・自サイト上でユーザにJavaScriptを（限定的に）許可したい&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
例えば、はてなダイアリー等でユーザがブログパーツを張れるよう許可するとか。但し&lt;br/&gt;
・document.cookie等、危険な機能は操作不能にする&lt;br/&gt;
・あくまでサイト上でJSを許可する（iframeは不可）&lt;br/&gt;
&lt;/p&gt;
&lt;p&gt;
で、幾つか考えられるのが以下。
&lt;/p&gt;
&lt;p&gt;
・iframe内で実行&lt;br/&gt;
iframeを生成して、そのwindowの中で実行させる。これなら確実に安全なサンドボックスが用意できそうだなと思うけど、今回はスルー
&lt;/p&gt;
&lt;p&gt;
・Facebookアプローチ（変数・関数名にプレフィックスを付けて無害化）&lt;br/&gt;
Facebookがユーザに許可するJSでは、変数・関数名にプレフィックスを付けて無害化するらしい&lt;br/&gt;
&lt;a href="http://kawa.at.webry.info/200708/article_3.html"&gt;[Facebook] FBJSでFacebookアプリ内でJavaScriptを利用 - Kawa.netブログ（川崎有亮）&lt;/a&gt;&lt;br/&gt;
面白いな、とも思うけど無害化するロジックに穴があるとセキュリティホールになりそうな気がする。
&lt;/p&gt;
&lt;p&gt;
で、色々調べていて一つ思ったんだけど、こんなのどうだろう
&lt;/p&gt;
&lt;pre class="source"&gt;
function safeCall(users_code){
  var sandbox = {
    window: null,
    document: null,
    alert: null
  };
  with(sandbox){
    console.log(eval(users_code));
  }
}
&lt;/pre&gt;&lt;p&gt;
これならsandboxオブジェクト内に列挙したwindow, document, alert,,,等は、無効化してevalできる筈
&lt;/p&gt;&lt;p class="clear"&gt;
&lt;a href="http://www.flickr.com/photos/tkmr2000/2089473686/" title="sandbox1 by tatkmr2000, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2197/2089473686_8ce907e889_o.png" alt="sandbox1" height="275" width="388" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p class="clear"&gt;
確かに列挙したオブジェクトはnullになる、逆に許可したいオブジェクトは含めなければ良い筈。Sandbox.myDocument.myGetElementByIdみたいに許可するネームスペース／クラスを決めてそれを叩いて貰えば制御可能になるかな。と思ったけど、deleteでプロパティ削除されると意味ない
&lt;/p&gt;&lt;p class="clear"&gt;
&lt;a href="http://www.flickr.com/photos/tkmr2000/2089473696/" title="sandbox2 by tatkmr2000, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2368/2089473696_0634a8faa8_o.png" alt="sandbox2" height="188" width="382" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p class="clear"&gt;
じゃあvarで宣言すればどうだろ？
&lt;/p&gt;&lt;pre class="source"&gt;
function sandbox(){
  var window = null;
  var document = null;
  var alert = null;
  this.do = function(code){
    with(this){
      console.log(eval(code));
    }
  }
}
&lt;/pre&gt;&lt;p&gt;
原則varで宣言した変数はdelete不可能な筈、これで一応大丈夫？
&lt;/p&gt;&lt;p class="clear"&gt;
&lt;a href="http://www.flickr.com/photos/tkmr2000/2089473704/" title="sandbox3 by tatkmr2000, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2301/2089473704_43bf3e5cbd_o.png" alt="sandbox3" height="293" width="413" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p class="clear"&gt;
どうだろ、やっぱり抜け穴がある気がしてならない。。

あと、実際にはwindowのプロパティを列挙する必要がある。
&lt;/p&gt;&lt;p class="clear"&gt;
&lt;a href="http://www.flickr.com/photos/tkmr2000/2089473698/" title="window_properties by tatkmr2000, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2146/2089473698_cc728de246_o.png" alt="window_properties" height="283" width="948" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p class="clear"&gt;
で実際に運用する時は、無害なタグとして記述して貰ってsandbox経由に実行すれば良いかな。今流行の俺俺スクリプト風に
&lt;/p&gt;
&lt;pre class="source"&gt;
&amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/my-safe-javascript&amp;quot;&lt;/span&gt;&amp;gt;
  alert(&lt;span class="str"&gt;&amp;quot;Hello world from sandbox!!&amp;quot;&lt;/span&gt;);
&amp;lt;&lt;span class="regex"&gt;/script&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
とか書いて貰って、ページ起動時に //script[@type="text/my-safe-javascript"] な要素を探してsandbox経由で実行みたいな。//script[@type="text/javascript"] はサーバ側のフィルタで潰す
&lt;/p&gt;&lt;p&gt;
うーん、どうだろ？やっぱ何か抜けがあるかな、ある気がする。きっとあるな。
&lt;/p&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040952"/&gt;</description>
      <pubDate>2007-12-06</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/407-javascript</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040952/407-javascript</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/407-javascript</feedburner:origLink></item>
    <item>
      <title>Google OpenSocial API - mixiに期待しつつJavaScript Gadgetを試す</title>
      <description>&lt;p&gt;sandbox.orkut.com のアカウントが使えるようになったので、GoogleのOpenSocial APIを試してみた。OpenSocial Protocolについて詳細はこちらのサイトが詳しいようです&lt;/p&gt;
&lt;p&gt;&lt;a href="http://teahut.sakura.ne.jp/b/2007-11-04-1.html"&gt;OpenSocial Protocol - たけまる&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;このブログに書いてある通り、OpenSocial Protocolは&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;クライアント用のJavaScript API&lt;/li&gt;

  &lt;li&gt;サーバ用のOpenSocial Data API&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;の２種類があって、サーバ側 OpenSocial Data APIの実装はまだ無いみたい。ということで今回試したのはJavaScriptクライアントの方。ドキュメントへ書いてある通り、Orkut上で試してみる。あとこのドキュメントを開いとく&lt;/p&gt;
&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;&lt;/p&gt;
&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;&lt;a href="http://code.google.com/apis/opensocial/docs/javascript/index.html"&gt;OpenSocial API Developer's Guide&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;sandbox.orkut.comへ登録&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://code.google.com/support/opensocialsignup/"&gt;http://code.google.com/support/opensocialsignup/&lt;/a&gt; から登録、数時間でメールが届いた。普通のwww.orkut.comとデータの互換性はある、唯一アプリケーションがsandboxでしか有効にならない。&lt;/p&gt;
&lt;h2&gt;Google Gadgets Editor&lt;/h2&gt;
&lt;p&gt;便利なので Google Gadgets Editorを利用する。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.google.com/apis/gadgets/docs/gs.html#Scratchpad"&gt;http://code.google.com/apis/gadgets/docs/gs.html#Scratchpad&lt;/a&gt; で自分のiGoogleホームに追加しておくと便利かも。自分のサーバがあれば、そこにXMLを置くだけでもOK。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/tkmr2000/1856272461/" title="Photo Sharing"&gt;&lt;img src="http://farm3.static.flickr.com/2002/1856272461_7a5f60c71f.jpg" width="500" height="147" alt="Google Gadgets Editor" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="clear"&gt;デフォルトのHello worldアプリで試してみた、右のhello.xmlのリンクURLをコピー。&lt;a href="http://sandbox.orkut.com/MyApps.aspx"&gt;http://sandbox.orkut.com/MyApps.aspx&lt;/a&gt; を開いて「Add an application by URL：」へ張り付けて「add application」を実行。プロフィールを表示して「Hello, world!」が表示されればOK&lt;/p&gt;
&lt;h2&gt;OpenSocialAPIを叩く&lt;/h2&gt;
&lt;p&gt;まず試しということで「OpenSocial APIから自分（Owner）の情報を取ってプロフィールURLを見つける、そのURLをfooo.nameから検索して結果を画面に表示」をやってみた。&lt;/p&gt;
&lt;pre class="source"&gt;
&lt;span class="comment"&gt;//自分の情報を取得&lt;/span&gt;
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(&lt;span class="str"&gt;'OWNER'&lt;/span&gt;), &lt;span class="str"&gt;'owner'&lt;/span&gt;);
req.send(onLoadFriends);
&lt;/pre&gt;
&lt;p&gt;複数件の情報取得を一度のリクエストでまとめて取ることを想定しているらしい。他にも色々とある &lt;a href="http://code.google.com/apis/opensocial/docs/javascript/reference/opensocial.DataRequest.html"&gt;http://code.google.com/apis/opensocial/docs/javascript/reference/opensocial.DataRequest.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;で、結果をコールバック関数のonLoadFriendsで処理する。ちなみにOwnerなのにonLoadFriendsという名前なのは&lt;a href="http://code.google.com/apis/opensocial/docs/javascript/index.html#ListFriends_Intro"&gt;サンプルコード&lt;/a&gt;をコピッてるから：）&lt;/p&gt;
&lt;pre class="source"&gt;
var owner = dataResponse.get(&lt;span class="str"&gt;'owner'&lt;/span&gt;).getData();
var url = owner.getField(opensocial.Person.Field.PROFILE_URL);
&lt;/pre&gt;
&lt;p&gt;指定したキー（owner）でPersonオブジェクトを取得、&lt;a href="http://code.google.com/apis/opensocial/docs/javascript/reference/opensocial.Person.html"&gt;この仕様に従って&lt;/a&gt;情報を抜き出す、今回はプロファイルURLを取った。あとはいつも通りJavaScriptで書けばOK&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/tkmr2000/1856559183/" title="Photo Sharing"&gt;&lt;img src="http://farm3.static.flickr.com/2130/1856559183_ff1ef340de_o.png" width="703" height="318" alt="Open social gadget test" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="clear"&gt;OrkutのプロファイルURLからfooo.nameで検索、結果を表示。自分の持ってる他のページ一覧が表示されている。本当は「フレンドの〜」てのがSNSぽくて面白いと思ったけど、Orkutのフレンドがいないのでできなかった：(&lt;/p&gt;
&lt;p&gt;やってみて特別難しいことは無い、このパーツも結局IFrameで動くので普段通りJavaScriptで作ればOK、Google Gadgets作った経験のある人はさらに楽なのかも。作ったパーツがMySpace／mixi／VOX?／Friendster なんかで汎用的に動くのは良い。ただ今現在だと「OrkutでGoogle gadgetsが動く」という状況と変わらないのであんまり面白くないな、まずはmixiの対応に期待かも。&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;最初 GoogleがMySpaceがFacebookが、という話を聞いてる時点では割とどうでも良かったけど、mixiが参加するなら日本としても面白くなりそう。&lt;/p&gt;
&lt;p&gt;適当だけど一応書いたコードこれ ↓ 途中PROFILE_URLが相対パスで「死ね」と思った、しかもパーツが動くドメインは変なドメインなので 「&lt;a href="http://d.hatena.ne.jp/brazil/20070103/1167788352"&gt;相対パスを絶対パスに変換する&lt;/a&gt;」この手も使えなかった。http://www.orkut.comベタ書き、駄目だなー&lt;/p&gt;
&lt;pre class="source"&gt;
&amp;lt;&lt;span class="num"&gt;?x&lt;/span&gt;ml version=&lt;span class="str"&gt;"1.0"&lt;/span&gt; encoding=&lt;span class="str"&gt;"UTF-8"&lt;/span&gt; &lt;span class="num"&gt;?&amp;gt;&lt;/span&gt;
&amp;lt;Module&amp;gt;
 &amp;lt;ModulePrefs title=&lt;span class="str"&gt;"Open Social Test"&lt;/span&gt;&amp;gt;
   &amp;lt;Require feature=&lt;span class="str"&gt;"opensocial-0.5"&lt;/span&gt;/&amp;gt;
 &amp;lt;&lt;span class="regex"&gt;/ModulePrefs&amp;gt;&lt;/span&gt;
&lt;span class="regex"&gt; &amp;lt;Content type="html"&amp;gt;&lt;/span&gt;
&lt;span class="regex"&gt; &amp;lt;![CDATA[&lt;/span&gt;
&lt;span class="regex"&gt; &amp;lt;script type="text/&lt;/span&gt;javascript&lt;span class="str"&gt;"&amp;gt;&lt;/span&gt;
&lt;span class="str"&gt;  function getData() {&lt;/span&gt;
&lt;span class="str"&gt;    var req = opensocial.newDataRequest();&lt;/span&gt;
&lt;span class="str"&gt;    req.add(req.newFetchPersonRequest('OWNER'), 'owner');&lt;/span&gt;
&lt;span class="str"&gt;    req.send(onLoadFriends);&lt;/span&gt;
&lt;span class="str"&gt;  }&lt;/span&gt;
&lt;span class="str"&gt;  function onLoadFriends(dataResponse) {&lt;/span&gt;
&lt;span class="str"&gt;    var owner = dataResponse.get('owner').getData();&lt;/span&gt;
&lt;span class="str"&gt;    var url = owner.getField(opensocial.Person.Field.PROFILE_URL);&lt;/span&gt;
&lt;span class="str"&gt;    url = absolutePath(url);&lt;/span&gt;
&lt;span class="str"&gt;    insertScript("&lt;/span&gt;http&lt;span class="sym"&gt;:/&lt;/span&gt;/fooo.name&lt;span class="regex"&gt;/tako3/&lt;/span&gt;json/likely/&lt;span class="str"&gt;"+url);&lt;/span&gt;
&lt;span class="str"&gt;  }&lt;/span&gt;
&lt;span class="str"&gt;  function tako3(res){&lt;/span&gt;
&lt;span class="str"&gt;    var output = "&lt;/span&gt;&lt;span class="str"&gt;";&lt;/span&gt;
&lt;span class="str"&gt;    for(var i=0; i &amp;lt; res.length; i++){&lt;/span&gt;
&lt;span class="str"&gt;      output += "&lt;/span&gt;&amp;lt;li&amp;gt;&lt;span class="str"&gt;"+res[i]+"&lt;/span&gt;&amp;lt;&lt;span class="regex"&gt;/li&amp;gt;";&lt;/span&gt;
&lt;span class="regex"&gt;    }&lt;/span&gt;
&lt;span class="regex"&gt;    document.getElementById("foooList").innerHTML += "&amp;lt;ul&amp;gt;"+output+"&amp;lt;/u&lt;/span&gt;l&amp;gt;&lt;span class="str"&gt;";&lt;/span&gt;
&lt;span class="str"&gt;  }&lt;/span&gt;
&lt;span class="str"&gt;  function insertScript(url){&lt;/span&gt;
&lt;span class="str"&gt;    var script = document.createElement('script');&lt;/span&gt;
&lt;span class="str"&gt;    script.type = 'text/javascript';&lt;/span&gt;
&lt;span class="str"&gt;    script.src = url;&lt;/span&gt;
&lt;span class="str"&gt;    document.body.appendChild(script);&lt;/span&gt;
&lt;span class="str"&gt;  }&lt;/span&gt;
&lt;span class="str"&gt;  function absolutePath(path){&lt;/span&gt;
&lt;span class="str"&gt;    return "&lt;/span&gt;http&lt;span class="sym"&gt;:/&lt;/span&gt;/www.orkut.com&lt;span class="str"&gt;"+path;&lt;/span&gt;
&lt;span class="str"&gt;  }&lt;/span&gt;
&lt;span class="str"&gt;  _IG_RegisterOnloadHandler(getData);&lt;/span&gt;
&lt;span class="str"&gt;  &amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="str"&gt;  &amp;lt;div id="&lt;/span&gt;foooList&lt;span class="str"&gt;"&amp;gt; &amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="str"&gt;  ]]&amp;gt;&lt;/span&gt;
&lt;span class="str"&gt;  &amp;lt;/Content&amp;gt;&lt;/span&gt;
&lt;span class="str"&gt;&amp;lt;/Module&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.jp/~r/tkmr_blog/~4/2040953"/&gt;</description>
      <pubDate>2007-11-05</pubDate>
      <guid isPermaLink="false">http://blog.tkmr.org/tatsuya/show/406-google-opensocial-api-mixi-javascript-gadget</guid>
      <link>http://feeds.feedburner.jp/~r/tkmr_blog/~3/2040953/406-google-opensocial-api-mixi-javascript-gadget</link>
    <feedburner:origLink>http://blog.tkmr.org/tatsuya/show/406-google-opensocial-api-mixi-javascript-gadget</feedburner:origLink></item>
    <item>
      <title>fooo.nameから検索して一発でLDR購読するブックマークレットとGreasemonkeyスクリプト</title>
      <description>&lt;p&gt;何か見ているページに関連するページを&lt;a href="http://fooo.name/"&gt;fooo.name&lt;/a&gt;から検索して、一発でlivedoor readerのフィード購読画面へ飛ばすブックマークレットを作った↓&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="javascript:location.href='http://fooo.name/accounts/search/'+window.location.href+'?redirect_to_LDR=true';"&gt;関連ページをLDRで購読&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;何かページを見ているときにこのブックマークレットを実行すると、そのURLの持ち主が持っている他のページをfooo.nameから検索、見つかった場合はLDRのフィード購読画面へ飛ばす。こんな感じ↓&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photo_zoom.gne?id=1846447405&amp;amp;size=o" title="Photo Sharing"&gt;&lt;img src="http://farm3.static.flickr.com/2223/1846447405_a5b5bc33f7.jpg" width="500" height="411" alt="tkmrLDRDescrip" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="clear"&gt;この場合だと http://blog.tkmr.org/ の持ち主である自分が持ってる、はてブ／del.icio.us／LDR／twitter／tumblr・・・なんかのRSSが列挙されている。見つからなかった場合はfooo.nameの情登録ページへ飛びます。もし判る情報があれば登録・追加して頂けると助かります：）&lt;br /&gt;
&lt;a href="http://fooo.name/main/aboutme"&gt;ちなみに fooo.name の説明はこちら&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;あと、一人当たり数十件くらい楽に表示されて煩雑になるので、そのフィードの概要を確認するためのGreasemonkeyスクリプトも書いた。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.tkmr.org/javascripts/feedDescriptionForLDR.user.js"&gt;feedDescriptionForLDR.user.js&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;LDRのフィード購読画面で↑の画面のように、最新４件のエントリタイトルを表示する。&lt;br /&gt;
このGreasemonkeyスクリプトを入れておけば。&lt;/p&gt;
&lt;div style="margin-left:10pt;"&gt;
  &lt;p&gt;Webを眺めているときに気になる人（ページ）を見つけた&lt;br /&gt;
  　&lt;span style="font-family:serif;"&gt;↓&lt;/span&gt;&lt;br /&gt;
  その持ち主が持っている他のページをfooo.nameから検索&lt;br /&gt;
  　&lt;span style="font-family:serif;"&gt;↓&lt;/span&gt;&lt;br /&gt;
  LDR購読画面でエントリ概要が表示されるので、追いかけたいフィードを吟味して購読&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;という流れが割と手軽にできるかなと。　&lt;/p&gt;
&lt;p&gt;ーーー以下余談ーーーー&lt;/p&gt;
&lt;p&gt;例えば何か面白い記事を見かけたとして、その記事をはてなブックマークに投げて終わりじゃなくてそのブログを購読して、さらにその人の他のサイトも購読して、その人のはてブやTwitterも購読して、ってのが生まれれば良いなと思う。幸い1000件くらいは楽に追いかけられるLDRっていう道具があるんだし。はてブの "人気エントリー" を追いかけるよりは、自分が興味ある人のブックマークを追いかけた方が面白いし、またその方がはてブ全体の情報に多様性が生まれて健全だと思う。というか別にはてブに限定した話じゃなくて、Web全体として。&lt;/p&gt;
&lt;p&gt;皆が一つの人気ランキングを見てその記事をブックマークすれば、ランキング上位の物はより上位に、下位の物はより下位に行くのは当然の話で、有名な情報はより有名に、無名な情報は無名なまま、という状況が起こりそうでまずい。じゃあそれを防ぐにはどうすれば良いか、と言われると答えは判らないけど、人の繋がりがキーになるんじゃないかなと考えている。人と人の繋がりが滑らかなクラスタリングを作って、上手く分散する。また逆に分散しすぎないよう多趣味な人間がブリッジになってクラスタを繋ぐ。じゃあどうやって実現するのが良いかと言うと難しいんだよな・・・&lt;/p&gt;
&lt;p&gt;ーーーー追記ーーーーー&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;tako3.comで同じことをやる場合はこちら↓&lt;/p&gt;
&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/fuba/20071104/119414707