2009/01/05

[Common Lisp] UCW で Arc Challenge

UCW で Arc Challenge を書いてみた。

Arc より短かいく書くのは無理なので、なるべく UCW っぽく書いてみたつもり。

UCW として今回必要だったものは次のとおり

  • サーバ(standard-server)
  • アプリケーション(arc-challenge-application)
  • ウィンドウコンポーネント(arc-challenge-window)
  • foo 入力コンポーネント(input-foo-component)
  • リンク表示コンポーネント(click-here-component)
  • foo 表示コンポーネント(you-said-component)
  • エントリポイント(index.ucw)

また UCW はコンポーネント指向なので arc-challenge-window をウィンドウコンポーネントとして定義し、そのボディ部分としてinput-foo-component, click-here-component, you-said-componentの3つのコンポーネントを定義した。

また UCW は継続ベースなのでエントリポイントと言う入口(最初に表示するページ)を定義する。エントリポイントでは (call 'arc-challenge-window) によってarc-challenge-window を表示している。

arc-challenge-window は initialize-instance :after で input-foo-componentを設定しているので foo 入力コンポーネントが表示される。

input-foo-component のフォームの :action で、call-component で arc-challenge-window の body 部分を切り替えることで、リンクの表示と foo の入力の表示を行っている。このあたりが継続っぽいところだと思う。

#|
http://www.paulgraham.com/arcchallenge.html
(defop said req
(aform [w/link (pr "you said: " (arg _ "foo"))
(pr "click here")]
(input "foo")
(submit)))
|#

(eval-when (:compile-toplevel :load-toplevel :execute)
(require :ucw))

(in-package :ucw-user)

;; サーバのインスタンスを生成
(defvar *arc-challenge-server*
(make-instance 'standard-server
:backend (make-backend :httpd :port 9090)))

;; アプリケーションを定義
(defclass arc-challenge-application (standard-application
cookie-session-application-mixin)
()
(:default-initargs
:url-prefix "/arc-challenge/")) ; http://localhost:9090/arc-challenge/xxx

;; アプリケーションのインスタンスを生成
(defvar *arc-challenge-application* (make-instance 'arc-challenge-application))

;; サーバにアプリケーションを登録
(register-application *arc-challenge-server* *arc-challenge-application*)

;; ウィンドウコンポーネント
(defcomponent arc-challenge-window (standard-window-component)
()
(:default-initargs
:title "Arc Challenge"))

;; body の設定
(defmethod initialize-instance :after ((self arc-challenge-window) &rest rest)
(declare (ignore rest))
(with-slots (body) self
(setf body (make-instance 'input-foo-component :window self))))

;; ウィンドウの描画
(defmethod render ((self arc-challenge-window))
(<:h1 "Arc Challenge")
(call-next-method))

;; foo 入力コンポーネント
(defcomponent input-foo-component ()
((window :initarg :window)))

;; その描画
(defmethod render ((self input-foo-component))
(let ((foo ""))
(<ucw:form
:action (flet ((goto (&rest rest)
(with-slots (window) self
;; arc-challenge-window の body 部分を切り替える。
(call-component self (apply #'make-instance rest)))))
;; リンク表示コンポーネント
(goto 'click-here-component)
;; foo 表示コンポーネント
(goto 'you-said-component :foo foo))
"foo "
(<ucw:input :type "text" :accessor foo)
(<:submit))))

;; リンク表示コンポーネント
(defcomponent click-here-component () ())

;; その描画
(defmethod render ((self click-here-component))
(<ucw:a :action (answer)
"click here"))

;; foo 表示コンポーネント
(defcomponent you-said-component ()
((foo :initarg :foo)))

;; その描画
(defmethod render ((self you-said-component))
(<:div "you said: "
(<:as-html (slot-value self 'foo)))
(<ucw:a :action (answer) "ok"))

;; エントリポイントを定義
(defentry-point "index.ucw" (:application *arc-challenge-application*)
()
(call 'arc-challenge-window))

;; エラー発生時にデバッガを起動
(setf ucw-core:*debug-on-error* t)

;; サーバスタート
(defun start-arc-challenge ()
"http://localhost:9090/arc-challenge/index.ucw
にアクセスしてください。"

(startup-server *arc-challenge-server*))

[Common Lisp] ucw-core

ANN: UCW-CORE is ready. The future is now!

UCW が復活(?)のきざし。嬉しいな。

clbuild の my-projects に次を追加してインストールしてみた。

# UCW
ucw-core get_darcs http://common-lisp.net/project/ucw/repos/ucw-core/
rfc2388-binary get_darcs http://common-lisp.net/project/ucw/repos/rfc2388-binary/
rfc2109 get_darcs http://www.common-lisp.net/project/rfc2109/rfc2109/
local-time get_darcs http://common-lisp.net/project/local-time/darcs/local-time
yaclml get_darcs http://common-lisp.net/project/bese/repos/yaclml/
cl-mime get_tarball http://www.bobturf.org/software/cl-mime/cl-mime-0.5.3.tar.gz
cl-qprint get_tarball http://www.bobturf.org/software/cl-qprint/cl-qprint-0.2.1.tar.gz

(require :ucw) をしてから ./dome/dome.lisp をロードし(ucw-standard::startup-demo) とすると、サーバが起動する。

http://localhost:9090/demo/index.ucw にアクセスするとデモページが表示される。すんなりいった。

デモページの Test Form input でちゃんと日本語が通ることも確認できた。

あと ./manual/example-code.lisp にちょっとした例題があって、./manual/getting-started.txt に UCW の説明がある。

今日は動いた、ってとこまでで。

2009/01/04

[本] ドラゴンランス秘史 ドワーフ地底王国の竜

近所の本屋で『ドラゴンランス秘史 ドワーフ地底王国の竜』を買って読んでる。ここのところずっと本の購入を自粛していたので、本を買うこと自体も嬉しい。それもドラゴンランスだからね。

サイコー!!

[日記] 今日で

休みもおしまい。そんなことがこれほどまで嫌だとはな。他の道を探す一歩手前くらい嫌だと思ってる。困ったものだ。

ここ数年の変化は私には好ましくないものなんだよな。気持ちは諦めに傾いている。それならいっそとことん利用するか、とも思う。

2009/01/03

[日記] 注文してしまった

お腹痛い。

2009/01/02

[日記] 元日

元日から焼き肉など食べたため気持ち悪くて眠れない。年末ジャンボの当選番号を確認。。。今年もちゃんと働くしかないか。

元旦は零時過ぎて近所の神社に家族で御参り。白人系(?)の巫女さんが素敵。甘酒と焚き火が暖かい。

昼ごろにつれあいの実家に行って、みんなで御参り。義姉家族と一緒に凧揚げをして焼き肉を食べた。まだしゃべれない姪とたくさんお話した。

娘の乳歯がようやく抜けた。煎餅えらい。

思いがけない人から年賀状が届いて嬉しかった。ちゃんとどこかで生きているんだね、うん。

さて、ホットミルクで飲みましょう。