screenを縦に割る(横分割)

横分割に対応したバージョンをインストール

$ cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/screen co screen
$ cd screen
$ cd src
$ ./coufugure
$ make
$ sudo make install

C-a |

横分割

C-a S

縦分割

C-a tab

リージョン移動

C-a X

カレントリージョンを削除

C-a Q

カレントリージョン以外削除

liftのローカライズ

lift内には様々なありもののモジュールがありそれらを使えば例えばユーザー登録の仕組みなどは簡単に作れるのだがそのままだとエラーメッセージなどが英語のままで困る。またサイトを国際化対応で考えているならばエラーメッセージなどは外部ファイルにまとめておきたい。

lift標準モジュールについては、
src/main/resouces/i18n/lift-core_ja.properties
というファイルで日本語メッセージを書いたファイルをおくとメッセージが日本語になってくれる。
どんな項目があるかは、
http://github.com/dpp/liftweb/tree/master/lift/src/main/resources/i18n/lift-core.properties
を参照の事。

また、アプリ独自のメッセージは
src/main/resouces/lift_ja.properties
に書いておけば、S.?で取得できるようになる。

なお、propertiesファイルなのでUnicode エスケープするのを忘れずに。

Makefileのデバッグ

他人が書いた複雑なMakefileデバッグするときは次のようにするとシンボルなどのデバッグログが出せて便利。warningはファイル名と行番号も出してくれるぞ。

HOGE = hogege

$(info hoge $(HOGE))
$(warning hoge- $(HOGE))

出力例:

hoge hogege
Makefile:6: hoge- hogege

http://developer.apple.com/documentation/DeveloperTools/gnumake/make_8.html#IDX330より

LiftRules.addAroundで追加したaroundがなぜか2度呼ばれる

liftにはaroundと呼ばれるリクエスト処理をハンドルする為の機構が用意されていて、こんなコードで例えばログを残すことができる。と、公式サイトには書いてある。
(参照: http://liftweb.net/index.php/HowTo_hook_into_the_lift%27s_request_processing_cycle)

    S.addAround(List(new LoanWrapper {
		def apply[T](f: => T): T = {
		  TimeHelpers.logTime("何かの処理")(f)
		}  
	}))

が、どうも一回のリクエストで2個ログが表示されるのだ。

INFO - 何かの処理 took 15 Milliseconds
INFO - 何かの処理 took 265 Milliseconds
INFO - Service request (GET) / took 469 Milliseconds

調べてみるとdispatchTableの処理とLiftSession.processRequestの先頭と2回呼ばれている。
どうしてこんなことになっているかと推測するに、dispatchTableはレスポンスが帰ってきたらそこで処理を打ち切る構造になってるが故にまったく処理されなかったときにaroundが不要に呼ばれることに。その後Session処理を呼んだときにやはりaround処理を呼ばないといけないので2度呼ばれるようだ。

そこで、リクエストが処理されたときだけ何かしたい場合は、結果が返ってきたら処理されているという判定を加えればよさそうだ。なのだが、fの戻り型はTとしか規定されていない^^;ハンドラの型が規定されてないってどうよ?

で、Tに一体何が来うるかというと使ってる箇所を調べると1つはTuple2[boolean,Can[Response]]でもう1つはCan[Response]のようだ。
なので将来変わって動かなく可能性があるちょっと危険なコードになった。

    S.addAround(List(new LoanWrapper {
      def apply[T](f: => T): T = {
       val (time,result) = TimeHelpers.calcTime(f)
       def logTime = Log.info("何かの処理 took "+time+" Milliseconds")
       result match {
          case (_,Full(_)) => logTime
          case Full(_) => logTime
          case _ =>
       }
       result
    }}))  

もっと良いやり方を知っている方は是非教えてください。