読者です 読者をやめる 読者になる 読者になる

The Arc ChallengeをLiftでやってみる

Scala Lift

ポール・グレアムの"The Arc Challenge"というものがあるらしい。

Write a program that causes the url said (e.g. http://localhost:port/said) to produce a page with an input field and a submit button. When the submit button is pressed, that should produce a second page with a single link saying "click here." When that is clicked it should lead to a third page that says "you said: ..." where ... is whatever the user typed in the original input field. The third page must only show what the user actually typed. I.e. the value entered in the input field must not be passed in the url, or it would be possible to change the behavior of the final page by editing the url.

http://www.paulgraham.com/arcchallenge.html

求められていることは、

  • 最初のページにテキストフィールドと送信ボタンを表示する
  • 二番目のページに「ここをクリック」というリンクを表示する
  • 最後のページで最初に入れたテキストを「あなたが入力したのは・・・」のように表示する

という一連の流れをhiddenパラメータ等で引き回さずに行えということ。

これをLiftでやってみる。やってみるというか、Liftのレポジトリの中にコード例(examples/example/src/main/scala/net/liftweb/example/snippet/ArcChallenge.scala)として入っているのでそれを写経してみる。

snippetを用意して、

package net.liftweb.example.snippet

import net.liftweb.http._
import net.liftweb.http.SHtml._

class ArcChallenge extends StatefulSnippet {
  var dispatch: DispatchIt = {
    case _ => xhtml => ask
  }

  def ask = {
    <p>
    Say Anything:
    { text("", p => phrase = p) }
    { submit("Submit", () => dispatch = { case _ => xhtml => think }) }
    </p>
  }

  def think = submit("Click here to see what you said",
                     () => dispatch = { case _ => xhtml => answer })

  def answer = <p>You said: {phrase}</p>

  private var phrase = ""
}

テンプレートから、

<lift:surround with="default" at="content">
  <lift:ArcChallenge:ask form="post" />
</lift:surround>

のように呼び出す。

このコードが短いと感じるか長いと感じるか、あるいはポール・グレアムが言うように"this is all stuff that any language used to write Web apps would have to have already.(ウェブアプリケーションを書くのに使われるあらゆる言語が備えておくべき事柄)"なのかどうかは人によって思うところは違うと思うが、"Web apps have to do this sort of thing all the time.(ウェブアプリケーションはこういった類のことをいつもやる必要がある)"というのは真実であろう。