2009年 07月 03日

Android 環境構築

きたる 7/10 に docomo から Android ケータイがでるので機種変 (+ キャリア変更 SB → Docomo) をしたい。が、まじでめんどいのでメモ……

名義の関係で MNP を利用できないっぽくてとても困る。名義人との距離がありすぎるので、本人確認書類の原本を安全に借りることができない…… (SSH/SCP できればいいのに) 前に帰ったときに名義人変更しとけばよかった。

なのでやるとしたら

  • 新規契約して旧番号を連絡先にしている機関に手続しまくって旧番号を捨てる
    • 現実的じゃない……
      • 会社・金融機関・住宅・友達・あとなんかあったっけ
  • 二重契約にする
    • 既存のケータイをホワイトプランオンリーにして 980/month にする?
      • 緊急用にしか使わないケータイを維持し続けることになる (最低でも2年ぐらいは……)
      • ないなー
  • 7/10 を諦めて次に実家に帰ったときに名義変更・MNP 手続きをしてくる
    • 8月に帰るつもりなのでこれが一番現実的かなぁ

gerry++

食べすぎた……

2009年 07月 04日

Scala で WAF を書きはじめる、前の第一歩

じゃう゛ぁとかよくわからないし的なレベルではじめようとすると前段階で躓くので、Rack とか HTTP::Engine 的に、あとはハンドラを書けばokみたいな状態にするまでのメモ

Java なウェブアプリは WAR とかいう形式にしてやると、サーブレットコンテナ (Jetty とか TomCat とか?) というものがよしなに起動してくれるようになるらしいです。GAE/J もそう。なので、それに沿ったものを作ります。

.
|-- src
|   |-- META-INF
|   |   `-- jdoconfig.xml
|   `-- net
|       `-- lowreal
|           `-- skirts
|               `-- HttpRequestDispatcher.scala
`-- war
    |-- WEB-INF
    |   |-- classes
    |   |   |-- META-INF
    |   |   |   `-- jdoconfig.xml
    |   |   `-- net
    |   |       `-- lowreal
    |   |           `-- skirts
    |   |               `-- HttpRequestDispatcher.class
    |   |-- lib
    |   |   `-- scala-library.jar
    |   |-- logging.properties
    |   `-- web.xml
    |-- css
    |   `-- base.css
    |-- images
    |-- index.html
    |-- js
    `-- static

war ディレクトリ以下が公開される (WEB-INF を除く) ディレクトリで、WEB-INF 以下にアプリケーション実体があり、WEB-INF/web.xml でルーティング設定をします。

web.xml ではふつう、URI -> Servlet の対応を XML で書くっぽいですが、そこらへんのことをむしろ自分でやりたいわけなので

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
  <filter>
    <filter-name>HttpRequestDispatcher</filter-name>
    <filter-class>net.lowreal.skirts.HttpRequestDispatcher</filter-class>
    <init-param>
      <param-name>foo</param-name>
      <param-value>hogehoge</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>HttpRequestDispatcher</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

というふうにフィルタで全部横取りします。

あとはフィルタ書けばいいだけなので

package net.lowreal.skirts

import javax.servlet._
import javax.servlet.http.{HttpServlet, HttpServletResponse, HttpServletRequest}

class HttpRequestDispatcher extends Filter {
  var static = """^/(?:css|js|images|static).*""".r
  val through = """^/_.*""".r
  var router:HttpRouter = null

  def init (filterConfig: FilterConfig) = {
    println("initializing...")

    val config_foo = filterConfig.getInitParameter("foo")

    println("initialized config: " + config_foo)
  }

  def doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) = {
    // ここでなんかする
    (request, response) match {
      case (req: HttpServletRequest, res: HttpServletResponse) =>
        val path    = req.getRequestURI
        val statics = static
        path match {
          case statics() =>
            chain.doFilter(request, response)
          case through() =>
            chain.doFilter(request, response)
          case _ =>
            // router.dispatch(req, res)
        }
      case _ => chain.doFilter(request, response)
    }
  }

  def destroy () = {
    println("destroy")
  }
}

アプリケーション起動時に init がよばれ、リクエストごとに doFilter がよばれてくるので、doFilter で request, response を適当にいじくればいいことになります。ここで chain.doFilter(request, response) をすればデフォルトのハンドラが呼ばれるっぽいので、普通は war 以下の static なものがそのまま返されます。

throught() は GAE/J のテストログインハンドラのためのやつです。(/_login? とかを GAE/J 側がハンドルしてる)

2009年 07月 05日

ゆの in Scala

//#! scala

object X {
	var mes = ""
	def / (o: => Any) = this
	def < (m:Symbol)  = { mes = m.toString; this }
	def ! () = { println("ひだまりスケッチ×365 " + mes + "!") }
}

(0 to 10).foreach {
	X / _ / X < '来週も見てくださいね!
}

ふつうにかくとふつうにできてしまうのでおもしろくない。 → これがおもしろい http://d.hatena.ne.jp/kmizushima/20080710/1215654623

don't say sanitize

2009年 07月 06日

ケータイのメールで起こされる夢をみた。なんか女の子からメールがきて、とても切ない気分になった。ふと時刻をみると昼の11時で、「やばい、遅刻だ!!!」

というところで現実にガバッっと起きて、急いで時計を確認したら、午前4時

2009年 07月 07日

本当にコード書くのが遅くて困る…… もともとプログラムを早く書くのが得意とはいえないが、それにしてもひどいだろう。気が落ちている。

Scala で書いてる個人的なアプリケーションは、今月中にどこかでリリースしたいなぁ。書こうと思ってから数ヶ月経っているわけだし…… しかし仕事も詰まってる。

仕事で Perl, JS, AS と書いて、個人的に Scala, Ruby をそれなりに書く生活が続いてる。飽きなくて良い。それぞれ良いところ、使い所があると思う (好き嫌いはあるけれど……)。


僕は最近 Scala が結構いいと思っていて、なんでかっていうと

  • 変数に型がある。コンパイル時にそれなりに考慮される (安全)
  • 必要以上に型を書く必要がない (型推論)
  • 既存の資産の上に乗っている (Java)
    • Java のクラスはいまいち使い勝手がよくないけど……
  • 関数型的にも、オブジェクト指向的にも書ける (TIMTOWTDY)
    • 逆に、Scala のコードを全てちゃんと理解しようとするならどちらも知ってないといけない
  • implicit def
    • 安全なオープンクラスのようなもの

あたりが気にいってる。十分に書きやすいなら、型がついていたほうが安心できていいし、Java という巨大な既存資産を無駄にしない姿勢が好きだ。

一方で、LL として使おうとするとちょっとやりにくい部分もある。

  • コンパイルが遅い (かなり遅い)
  • 正規表現リテラルがない
    • メタキャラクタをエスケープするかしないかでとても重要
    • """regexp""".r とか書きたくない
  • LL なら普通はあるようなメソッドがない。あるいは名前が違う
    • replace (search:Regex, replace:(Matcher => String)) みたいなのとか……
    • List#join 的なものは mkString という高機能なものになっている
  • scaladoc がダメすぎる
    • 書きなおそうと思ったら scaladoc がそもそもビルドできなかった……

簡単なスクリプトを書くような分野には向いてないと思うけど、軽めのウェブアプリケーションとかだとちょうどよくて、Java と LL の中間ぐらいにピッタリとハマる言語だと思う。

また女生徒読んだし……素で泣くし……

Ruby っぽいブロックのとりかた

object Main extends Application {
	def rubylike (s:Int, e:Int)(f:Int => Unit) = {
		(s to e).foreach { i =>
			f(i)
		}
	}

	rubylike(1, 10) { i =>
		println(i)
	}
}

部分的にカリー化して最後に関数をひとつだけとるようにすると、いい感じに書ける

2009年 07月 11日

ぼくの親程度の世代だと、インターネット日常でつかうようなことがないので、インターネットの技術がいくらプッシュな技術であっても、全く意味がない。コンピュータを開いて、なんかするっていう、能動的にプルする行動が必要だ。

そういう意味で、手紙、郵便、電話は、まだしばらくは、最強のプッシュ技術なのだと、ウェブフックなんていう少々不毛なことをやりつつ考えた。

gerry++

Android で Hello World するまで

cd ~/project/hello-world-android
android create project --target 3 --path . --activity HelloWorld --package com.example.HelloWorld
ant debug
adb install bin/HelloWorld-debug.apk

次からは

adb install -r bin/HelloWorld-debug.apk


src/com/example/HelloWorld/HelloWorld.java をみると、R.layout.main というのが view に設定されてる。res/layout/main.xml が実体っぽい。適当に書きかえて

adb debug
adb install -r bin/HelloWorld-debug.apk

するととりあえず自動的に起動中のアプリが終了してインストールが走るようになる

ファイルシステム

adb install されたアプリケーションは /data/app に入っている。これは

$ adb shell
# ls /data/app
# exit

とかでわかる

開発

adb shell "am start -a android.intent.action.MAIN -n com.example.HelloWorld/.HelloWorld"

.HelloWorld の部分は AndroidManifest.xml の /manifest/application/activity/@android:name っぽい?

http://gist.github.com/145085 Rakefile

Scala, ant

ant の compile タスクを修正して scalac が走るようにする。

カレントディレクトリの tools 以下に scala-compiler.jar を、libs 以下に android-library.jar をおいて

build.xml の最後に

    <target name="compile" depends="dirs, resource-src, aidl">
        <javac encoding="ascii" target="1.5" debug="true" extdirs=""
            srcdir="gen"
            destdir="bin/classes"
            bootclasspath="${android-jar}">
        </javac>

        <javac encoding="ascii" target="1.5" debug="true" extdirs=""
            srcdir="src"
            destdir="bin/classes"
            bootclasspath="${android-jar}">
        </javac>

        <taskdef resource="scala/tools/ant/antlib.xml" classpath="tools/scala-compiler.jar:libs/android-library.jar" />
        <scalac
            force="changed" deprecation="on"
            srcdir="src" includes="**/*.scala"
            destdir="bin/classes">
            <classpath>
                <pathelement location="${android-jar}"/>
                <fileset dir="libs" includes="*.jar"/>
            </classpath>
        </scalac>
    </target>

を書く、これだと scala-library.jar の変換で死ぬので

$SDKHOME/platforms/android-1.5/tools/dx 

に javaOpts="-Xmx512M" とか書くととりあえず通る。20秒ぐらいかかる

2009年 07月 12日

hookhub というのをつくりました

http://www.hookhub.com/

  1. Web Hook に対応したサイトからのフックを受けて、
  2. それをいい感じに JS で加工し、
  3. 他のサービスにリクエストを投げたり、自分にメールを送ったりすることができます。

例えば、

  • はてブしたエントリを twitter に
  • github に push したら twitter に
  • Google Code にコミットしたら twitter に

とか

  • はてブで [あとで読む] タグをつけたら、Remember the milk にタスクをつくる
  • はてブのお気に入りユーザが [culture] タグをつけたら即自分にメールを投げるとか

とか、些細なことを自分でホストすることなくできるようになります。

こういったルールは全て JavaScript で書くようになっていますが、Fork と Config 機能で他の人のをコピってすぐ使えたりします。

例えばはてブ → twitterとかだと、

  1. http://www.hookhub.com/cho45/hook/1004 を Fork して Save
  2. Config で twitter_user, twitter_pass を入れる
  3. はてブの「イベント通知を受けとるURL」に Hook URI を入力すればできます


ちなみに GAE + Scala でつくっていて、フック起動時の JS の実行には Rhino を使っています。Rhino では頑張ってサンドボックスを作っていろいろ制限をかけているつもりです。

  • 松尾大社
  • 洛西竹林公園
  • (六孫王神社)

どっちもとても遠かった…… 松尾大社は距離的には上賀茂と同じぐらいっぽいけど、四条通りをひたすら西にというのがとてもだるかった。鴨川は楽しいけど、四条通りは退屈だからなぁ……

その後、ひたすら桂川を下って竹林公園へいったけど、こっちは結構登った場所にあるので自転車だと大変だった。16時すぎの入園時間過ぎについてしまったけどオマケして入れてもらった……

松尾大社、盤座まで行きたかったけど、独りではだめらしいので諦めた。

2009年 07月 13日

リア充の人達は、こちらが些細なことで強烈な不安感を抱くというのをいいことに、ちょこちょこと、世間からはとがめられないようなことを大量にして、こちらのバッファを溢れさえ、殺そうとしてくる。

バッファを全て埋めるほどしなくとも、バッファをある程度埋めてやりさえすれば、徐々に処理能力は落ちていくし、そうなると、処理落ちに対する不安によって勝手にバッファが埋まっていくようになる。簡単である。

洛西竹林公園は、思ったより広くなかった。ただ、その周辺 (竹の径 (みち)) というのがとても広範囲だった。

2009年 07月 14日

竹林も、神社と同じように、いつも、どこで見ても、懐しい感じがする。

考えてみると、よく自分の夢には竹林がでてくる。たんぼだらけの田舎で、竹林がある。近くに、山に入る道があり、そこを入っていくと、小さな神社がある。よく見る。

となりのトトロのバス停のイメージが近いけど、今調べてみたら、あれは竹林ではなかった。何が発端でそういう懐かしさを抱くのかよくわからない。

竹林は、すごく安定した、守りを感じる。こういうのは、深めていくと信仰になるのかもしれないが、竹林信仰というのは聞いたことがない……

Google App Engine がマイブームだけど、いまいち使いかたがわかってない。

datastore api って想像していたよりもずっと遅くて、普通に read するだけでも結構 CPU Time を消費してしまう (50-80msec?)。ここらへんの感覚は、デプロイしてみないとわからないのでとてもやりにくい。

hookhub.com のトップは、最近フックされたウェブフックを表示しているけど、毎回 datastore に last_hooked 的なプロパティでソートしてつつひいて、さらにそれぞれについての 10 回ぐらい user 情報をひいたりすると、それだけで GAE のログに「最適化が必要なページ」として警告がでる。

少なくともどこかの段階でちゃんとキャッシュしないといけないけど、いまいち感覚がわからない。アプリケーション内のメモリにインスタンスキャッシュさせていけばいいのか、それとも memcache をつかえばいいのか…… 普通どうするんだろ?

今のところ、view を部分的に memcache に入れるような (TT Cache みたいなの) のを入れて、とりあえず警告はでなくなった。むずかしい…… 今はソート済みクエリをキャッシュしてないけど、これも expire つきで memcache に入れたほうがよさそうな気がする。

赤のリクエストが memcache にテンプレートキャッシュするようにしたときのリクエストで、一時的に memcache api も消費したので時間がかかってる。直後から api_cpu_ms が半減しているので、キャッシュの効果はあったようだ。だけど全体としての応答時間はまだまだ極めて遅い……

ちなみにユーザ情報を index つきで一発だけしかひいてない /help の応答時間は 100msec 以下になってる。

datastore はログを見ていると、割と timeout するので、ちゃんとエラー処理をすべきだろう。今はなんもしてないので 500 がでる。

近頃のディスプレイは解像度高いから、写真のサムネを 700 か 800 にしてもよさそうだなぁ → 700にしてみた。fotolife、オリジナル画像が存在する写真のサムネを現在の設定でつくりなおすコマンドがほしい。

2009年 07月 15日

2009年 07月 16日

2009年 07月 17日

2009年 07月 16日

gerry++

2009年 07月 18日

2009年 07月 19日

昨日は伏見稲荷大社へ。前にいったときは、何もない平日の、何もない夕方で人が殆どいなかったけれど、今回はそれなりに人がいた。今日、明日と祭らしく、その準備もしていた。

前と同じ道を辿ってもしかたがないので、一般的な参道をはずれたほうの道をいってみた。竹の下道・弘法の滝のほう。ただ、結構しんどくて、サンダルでいけそうな感じでもなかったので途中でひきかえしてきた。

途中、外国人観光客な人に写真をとってくれ的なことを言われた。英語圏でもないっぽかった。「なんて言ってシャッターきればいいんだ?」と悩んだ。

2009年 07月 20日

昨日は、なんか新しいところに行きたい気分ではなかったので、頭を使わずだらだらと賀茂川を上っていくだけでいける上賀茂神社へ。適当にぼーっと境内をまわり、帰りに下鴨に寄って帰ってきた。下鴨では御手洗 (みたらし) なんちゃらな祭をやっていて賑わっていた。そういえば経団連会長って御手洗 (みたらい) だよなぁとかどうでもいいことを考えた。

上賀茂神社の境内に「沙瑛の楓」とかいうのがあって独りでウけてた。ちなみにひだまりスケッチのさえさんの字は沙英なので微妙に違う。あれ、なんの由緒も書いてないけど、なんで沙瑛の楓なのだろう……ぐぐってみたけどよくわからなかった。

なんとなく一昨日も昨日も広角ズームのみを持ってでかけたけど、被写界深度の感覚が狂うので大変だった…… 帰ってきて現像してみるとピントがあってて欲しい部分までちゃんとピントがあってないことが多々ありまくった。広角なので普段より絞る必要ないだろ、って思ったらそうでもなく、収差の影響かなんかで結構ひどかった。レンズのこともよくわかってないし、画角的にも慣れてなくてめんどくさい。

金銭ベースでモノゴトを考えると、マイノリティへのメッセージというのは、そうでない場合に比べて金にならないので、価値がない事になってしまう。結果、既にずいぶんと良い思いをし、金を十分に持っている人がさらにいい思いをし、そうではない人達は少々そこから溢れたものを拾うだけで、ただ、差が広がっていくだけになる。

溢れものでもマイノリティの役に立てばいい、というのもあるけど、幸せというのは絶対的なものではないので、結果差が広がるならば、それは失敗であると思う。

2009年 07月 21日

混乱をきたして攻撃的になっている。ひきこもりたい

カアは、悲しくて、いやだ。可哀想で可哀想でたまらないから、わざと意地悪くしてやるのだ。カアは、野良犬みたいに見えるから、いつ犬殺しにやられるか、わからない。カアは、足が、こんなだから、逃げるのに、おそいことだろう。カア、早く、山の中にでも行きなさい。おまえは誰にも可愛がられないのだから、早く死ねばいい。

これまでの私の自己批判なんて、まるで意味ないものだったと思う。批判をしてみて、厭な、弱いところに気附くと、すぐそれに甘くおぼれて、いたわって、角(つの)をためて牛を殺すのはよくない、などと結論するのだから、批判も何もあったものでない。何も考えない方が、むしろ良心的だ。

本能、という言葉につき当ると、泣いてみたくなる。本能の大きさ、私たちの意志では動かせない力、そんなことが、自分の時々のいろんなことから判って来ると、気が狂いそうな気持になる。どうしたらよいのだろうか、とぼんやりなってしまう。否定も肯定もない、ただ、大きな大きなものが、がばと頭からかぶさって来たようなものだ。そして私を自由に引きずりまわしているのだ。

やれ生活の目標が無いの、もっと生活に、人生に、積極的になればいいの、自分には矛盾があるのどうのって、しきりに考えたり悩んだりしているようだが、おまえのは、感傷だけさ。自分を可愛がって、慰めているだけなのさ。

お父さんが、いなくなったからって、こんなにも卑屈になるものか。情なくなって、何も言えなくなっちゃった。帰って下さい、帰って下さい。私の父は、立派なお方だ。やさしくて、そうして人格が高いんだ。お父さんがいないからって、そんなに私たちをばかにするんだったら、いますぐ帰って下さい。

いまのあの子に泣きながら慕われているその「おねえちゃん」を羨しく思うのだ。私にだって、あんなに慕って甘えてくれる弟が、ひとりでもあったなら、私は、こんなに一日一日、みっともなく、まごついて生きてはいない。生きることに、ずいぶん張り合いも出て来るだろうし、一生涯を弟に捧げて、つくそうという覚悟だって、できるのだ。ほんとうに、どんなつらいことでも、堪えてみせる。

人生、限られた時間しかないのだから、使うに限度があるお金をどう得るかではなく、一時間・一日をどう生きるかのほうが重要だ。でも、どうしたらいいかよくわからない。がむしゃらに何かやったって意味がない、リア充は途中からそれら全てを奪っていくから。

嬉しさの指標がなくなっている。褒められても嬉しくない、自分が満足していないからだ。嫌味なのではと穿った考えをしてしまう。素直に受け取ればいいのだけれども、どう考えてももっといいものがあるし、いいひとがいる。

日記も書けないようでは人生終わりだ

カアは、それなりに生きていける程度ではあるが、生きていくのが難しい犬である。あの時点での、若い世代への答えであると思う。

そういえば、上賀茂の式年遷宮が21年なのは、神職の人もよくわからないといっていた。たぶん職人の負担を軽減するために伊勢とずらしてあるのだろうといっていた。

2009年 07月 22日

そういえば伏見稲荷大社近くの歯科のマークがおもしろかった。

2009年 07月 23日

何をやるにしても、見当もつかないような方法で、優れたことをする人がいて、そういう人には、決してかなわない。上に人がいて、追っ掛ける気になるなら、それはとても楽しくて、よいことなのだけれど、追っ掛ける気もなれないほどに、離れていれば、そういう気もなくなり、立ち尽すしかない。

気概を持ってとりくめなければならない、気骨を持ってないのはだめだと、しばしば聞かれることだけれど、そんなこと、「そうじゃない」と、否定する人はまずいないだろう。「その通りです」と、「仰る通りです」と、思って聴くけれど、どうすればそういう心になるかは、全く聞かされない。本人達も、一種の才能によって、それを実現してきたわけだから、伝えられない。そのくせに、他人には、結果的にできたこと、「おまえらとは違うのだ」といわんばかりに、教訓めいたことは存分にいう。

しかし時々、とてもうまく言葉を使いこなす人がいて、そんな人は、上に書いたような、わかりきったことをただ繰り返して、却って他人のやる気を奪うようなことではなく、淡々と事実だけを、飾らずに言葉にして、「それでいいなら、自分にできそうだ」と、やる気をわかせてくれる。ただし、そういう人は極めて少ない。

人とできるだけ関わりたくないが、そうもいかない。思うことをいっていると、他人樣のやる気を奪う結果になる。全くよくない。そう思っても、たびたび何もかもどうでもよくなり、他人のことを全く考えずにいるようになる。

2009年 07月 24日

京都の神社を google map にプロットする

地図にマップされたやつがなかったのでてきとうに……

を元にプロット。京都府神社庁からは郵便番号 (京都市内ものだけ) をスクレイピングし、Google の geocode にあらかじめかけておいたやつを表示している (青のマーカー)。Wikipedia からは、JSONP の API を使って、神社一覧を取得し、さらにそれぞれに神社のページに埋め込まれている緯度経度情報を JSONP でとってきてる。


Wikipedia のほうは動的なので京都市以外でも

とか、カテゴリからひっぱってこれる。北海道の神社は今のところ全く緯度経度情報を持ってないのでプロットされない。

2009年 07月 25日

WAF の設計方法

結局、アプリケーション (not Web App = WWW 非依存) なものを Web っぽい部分とつなぐ Dispatcher (Router) があればよくて、あとはおまけっぽいので、HTTP::Engine + Router で WAF っぽい部分は終わりになるような気がした。

http://subtech.g.hatena.ne.jp/cho45/20090517/1242556113

と書いたのですが、あれを書いたときから、「そうだろうか?」というのを薄々と思っていました。Web + App ではなく、WebApp にしてしまうのもいいんじゃないかということについてです。

Web + App は大人気 Sinatora もそういう考えっぽいですが (誤解しているかもしれません)、Web というのが App へのインターフェイスの一つにすぎず、例えば CLI + App という組み合せもあるし、Desktop GUI + App という組み合せも考慮されています。ロジックのテストはしやすそうでいいですね。でも、もっと富豪的でもおこられないんじゃないかなぁとも思うのです。

WebApp の場合、Web (というより HTTP) を唯一のインターフェイスとして提供し、例えば CLI だろうが GUI だろうが、HTTP を仲介するようにします。HTTP + App, CLI → HTTP + App, GUI → HTTP + App。これは例えば GAE だと、そもそもこういう方法をとることしかできません。Cron も HTTP で特定のURLが叩かれるだけです。ユーザ向けAPIみたいなのがだいたいのサービスでありますが、それをアプリケーションのオーナーまで権限を拡張しているような感じです。

これは一昔前のシェルに入れない CGI サーバみたいな趣きがあって古い気もしますが、こうすると Web + App に比べていくつか楽をできるようになります。「楽」とは違うかもしれません。自然と良い方向にアプリケーションが進化する、という感じでしょうか。

  • バッチ処理だろうがなんだろうが、専用の CLI 環境みたいなのを考えなくても、他のハンドラと同じように書ける
  • 自然と結合テストを書くようになる
    • Web + App にすると App のまでのテストは書いても、Web 側の結合テストを怠りがち
      • 最終的にユーザがみるのは Web なインターフェイスなのだから、ちゃんと書かないとだめ
  • 自然と API に必要な機能が揃う
    • CLI から叩こうと思ったとき必要な機能が勝手にできる

一方、微妙なところもあります

  • バッチ処理しかしないサーバーでも HTTPD を立ち上げてることになる
  • 各ハンドラだけの実行をしにくい
  • テストが遅くなりがち

この辺はフレームワークでモックリクエストを充実させたら解決できます、というかちゃんとしたモックリクエストの仕組みがテストのために必須です。

[めんどくさくなったのでまた考えて追記する]

2009年 07月 26日

2009年 07月 25日

DBIx::RewriteDSN

http://search.cpan.org/~satoh/DBIx-RewriteDSN/lib/DBIx/RewriteDSN.pm

というのを作ってみました。DBI->connect に渡しされた dsn を別の場所で一括して書きかえるモジュールです。

  • dsn がハードコードされている
  • ソースコードが膨大で DBI->connect を全部探しだすのが困難
  • DB 情報を管理する Config インスタンスがない

ような場合に、それなりに安全にテスト環境を構築するのに使えると思います。

例えば

use DBI;
use DBIx::RewriteDSN -rules => q{
    (dbi:mysql:database=foobar;host=192.168.0.1) $1

    # fallback
    dbi:mysql:database=([^;]+)(?:host=.+)? dbi:mysql:database=$1_test;host=127.0.0.1
};

みたいな感じにすると、dbi:mysql:database=foobar;host=192.168.0.1 についてはそのまま繋いで、それ以外はローカルホストに繋ぎにいくようになります。ローカルにDBがなければエラーになるだけなので意図せず production に繋ぐような事故が防げると思います。

2009年 07月 27日

昨日は鞍馬寺 (由岐神社) → 貴船神社にいってきた。雨がふったりやんだりする、なんともいえない天気で、行こうかどうか悩んだけど、行ってよかった。鞍馬山にいる間、短時間に晴れたり豪雨になったり繰替えして、面白かった。かえって得した気分だった。狙って晴れの日、雨の日に行くことはできるけど、こういう天気は滅多にない、雨、雨上がり、曇り、晴れ。

鞍馬寺とかは、普通に山登りだった。山登りって、今まであんまりいい経験がなかったんだけど、今回は見るものすべて美しく感じたので、テンションあがりまくって、疲れた気分にさえならなかった。足はガクガクいっていたけど「なんでガクガクいってんだろう……」とか頭で考えてた。

貴船神社あたりは、川床の店がたくさんあった。本社のほうでは七夕飾りをやっていたので、僕も「フミにご縁がありますように」と書いてきた。短冊とかたぶん小学生か中学生以来すぎて独りでウケてた。ちなみに「フミ」は、コード (プログラミングは文芸だと信じています) とか、日記とか、文乃さんとか、文江さんとか、そういうのです……

なんというか、貴船あたりは時代が違うような錯覚に陥いってしまい、洋服ってなんか違和感あるなぁとかいうレベルだった。雨でリアルなコントラストが強かったせいかもしれない。

とにかくまぁ、昨日は、肺一杯に良い空気を吸いこんで気分がよかった。空気は記録に残せないし、行って価値が絶対にある。そして「緑」というのは、やっぱり眼で見ないと、確実な色ではないなぁと感じた。

あのへん、秋になったら本当に紅葉がすごそうだなぁと思った。そうでなくても、普通にまた行きたい。昨日のような天気であっても、それなりに人がいたから、普通の日はかなりやばそうだなぁと思った。

ディスプレイの輝度落として作業すると彩度をあげすぎたり、さげわすれたりする。。

2009年 07月 28日

下り坂にみえる錯視みたいだ

突き当たり、右です

2009年 07月 29日

2009年 07月 30日

2009年 07月 31日