Archive for March 2009

OSバージョンによる分岐

written by shn, on Mar 29, 2009 7:58:00 PM.

WINVER的な奴が欲しい。とりあえず、これで良さげ。

#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_2_2

腹が痛い

written by shn, on Mar 23, 2009 12:20:56 AM.

土曜にチーズフォンデュ(溶かしたチーズにパンとか野菜とかを絡める食べ物)、日曜にシュラスコ(giveupするまで、ブラジル人が肉を運んでくる食べ物)と、二日続けてガタイが良いあたりの外国人の食物を食べると、胃が悲鳴を上げたり、万座温泉のような放屁をしたりと大変です。

シュラスコは表参道のバルバッコアグリルで食べました。お客さんの半分ぐらいが外国人だった。しばらく肉はいらんて感じ。

iPhoneでCrash Logから関数の位置を特定する

written by shn, on Mar 15, 2009 2:54:00 AM.

iPhoneの素晴しいところの一つは、Crash Logが本体に保存される事なんですが、

Thread 0 Crashed:
0   libobjc.A.dylib                 0x300c8c18 objc_msgSend + 20
1   Fastweet2k                      0x00016240 0x1000 + 86592
2   UIKit                           0x30b2b414 -[UITextView keyboardInputChanged:] + 80
3   UIKit                           0x30bcaf1c -[UIWebDocumentView keyboardInputChanged:] + 40

このように、デバッグバイナリでもシンボルが出ないときがあります。 symolicatecrashを使ってもだめでがっかり。

でも、dSYMがあるから頑張ればなんとかなるんじゃね?とやってみたらなんとかなった。 普段VisualStudioの微温湯に浸かっている僕には大変でした。

% gdb --quiet Fastweet2k.app.dSYM/Contents/Resources/DWARF/Fastweet2k
(gdb) info line *0x16240
Line 179 of "/Users/shn/Documents/projects/git/fastweet/Classes/TweetViewController.m" starts at address 0x16212 <-[TweetViewController sendPressed:]+118> and ends at 0x162e4 <-[TweetViewController sendPressed:]+328>.

てな感じ。

上記のCrash Logはdebug版バイナリのものだったので、_./build/Debug-iphoneos/_にあるdSYMをgdbで開き、info lineコマンドで、対応するソースコードの位置が出てきます。

しかし、出てきたのは良いが何故ここでハングアップするのか、というか何故あの操作でこの関数が呼ばれるのか不明で泣きそう。

ついでに、symbolicatecrashの解説はここが詳しいです。

2輪 ETC

written by shn, on Mar 14, 2009 8:09:00 PM.

助成もあるし車検のついでに付けるかーと問合せたら、どこも
「予約がいっぱいだが、機械がメーカーにも在庫が無く3月中に付けられるかどうかわからない」 だって!

3日で終了ってどういう事よ!

Firefox null

written by shn, on Mar 8, 2009 1:10:00 AM.

なにこのかっこいいバージョン

Firefox null

Werkzeugで遊ぼう! - Routing編

written by shn, on Mar 7, 2009 2:34:00 AM.

リクエストから、各URLへと対応するハンドラを導くのに、Werkzeugではwerkzeug.routingを使う。

wz_routing.py

#! -*- coding:utf-8 -*-
from werkzeug import run_simple
from werkzeug.routing import Map, Rule, Submount, Subdomain

class WSGIApplication(object):
    def __init__(self):
        self.url_map = Map([
            Rule('/hello', endpoint='hello'),
            Rule('/hello/<string:lang>', endpoint='hello'),
        ])
        self.url_adapter = self.url_map.bind('localhost')

    def __call__(self, environ, start_response):
        endpoint, arguments = self.url_adapter.match(environ['PATH_INFO'])

        handler = getattr(self, 'handle_%s' % endpoint)
        return handler(environ, start_response, **arguments)

    def handle_hello(self, environ, start_response, lang='en'):
        writer = start_response('200 OK', [('Content-Type', 'text/plain; charset=utf-8')])
        if lang == 'en':
            return ['Hello']
        elif lang == 'ja':
            return ['こんにちわ']
        elif lang == 'he':
            return ['הלו']
        return ['no hello yet']

if __name__ == '__main__':
    run_simple('localhost', 4000, WSGIApplication())

$ python wz_routing.pyして、$ curl http://localhost:4000/hello とか、 $ curl http://localhost:4000/hello/ja とかしてみるといろいろなhelloが楽しめると思う。

Ruleには、<int>やら、<float>やらも使えるので、/blog/archive/2009/03/とか、twitter.com/shn/repliseみたいなナウいURLが設計しやすくて良いですね~

__call__の中身は、以下のようにも書き換えられる。

return self.url_adapter.dispatch(
    lambda e, a: getattr(self, 'handle_%s' % e)(environ, start_response, **a),
    path_info=environ['PATH_INFO']
)

goodbyeも楽しみたいなーと思って、/goodbyeにアクセスするとNotFound例外が飛ぶ。こいつもwsgi的な奴なので、ちょちょっとするとエラーを表示してくれる。

from werkzeug.exceptions import HTTPException
try:
    endpoint, arguments = self.url_adapter.match(environ['PATH_INFO'])
except HTTPException, e:
    return e(environ, start_response)
else:
    ...

Submountを使うと、Ruleの塊を指定したディレクトリ以下にマッチしてくれるようにしてくれる。似たようなのにSubdomainてのもあるけど、まだ使ったこと無い。subdomain毎にbind()しないといけないのかな?