第5回 継続を使ったコントローラを作る
吉田 裕美
有限会社イーワイオフィス
2009/2/20
Lispの一種であるScheme。いくつかある処理系の中でも気軽にスクリプトを書けるGaucheでLispの世界を体験してみよう(編集部)
- - PR -
第4回「Gaucheでテンプレートエンジンを作る」では、MVCのビューの部分を作成しました。今回は、継続を使ったコントローラ部分の作成を行い、Webアプリケーションを完成させます。
Webアプリケーションのコントローラの解説に入る前に、プログラムの処理の流れについて少し考えてみます。
例えば、2つの数を入力して足した結果を表示するコンソールアプリケーションであれば、以下のように変数を2つ用意し、2つの数値を入力した後で足した結果を表示するというシンプルなプログラムになります。
(define (console-add) |
しかし、皆さんが書いているようなWebアプリケーションではどうでしょうか。1つのページにAとB、2つの入力欄があれば簡単ですが、1ページ目でAを入力し、2ページ目でBを入力し、3ページ目に表示するようなアプリケーションの場合は、1ページで入力したAの値を2ページ目の入力の間も保持するために、セッションなどの特別な場所に格納するか、2ページ目にhiddenタグを使って埋め込んでおく必要があります。
これは、リクエストごとに起動されるCGIはもちろんですが、アプリケーションサーバ上に常駐して動くアプリケーションの場合も同じです。なぜ、上のコンソールアプリケーションのようにシンプルに書けないのでしょうか。
クロージャ
ここでまた、Schemeの勉強をしましょう。次のようなadd-nという関数を定義します。
(define (add-n n) |
この関数を使ってadd3を定義します。
(define add3 (add-n 3)) |
add3を実行してみましょう。
gosh> (add3 5) |
add3は引数に3を足す関数になっています。同じようにadd4を定義して使ってみると、add4は引数に4を足す関数になっています。
gosh> (define add4 (add-n 4)) |
ところで、最初に定義したadd-nは何でしょうか。定義を見ると、lambda式を戻す関数です。しかも、引数nが足し算の片方に使われています。
従って、add3は(lambda(x) (+ x 3))となり、引数xを受け取り、3を足します。しかも、add3の定義で使った3が、ずっとその後でもどこかに記憶されていて、いつでも3を足す関数として使えます。
このような機構は、クロージャ(Closure)と呼ばれています。Schemeでは、lambda式は実行するプログラム(上の例では(+ x n))だけではなく、定義した際の環境(ここではnの値)も一緒になっているのです。
従って、add3には(lambda(x) (+ x n))とn = 3の環境が一体化して記憶されているのです。
継続ベースのアプリケーション
さて、ここで最初のA+Bのプログラムに戻りますが、クロージャを使って以下のように書き換えてみました。
(define cont #f) |
これを実行すると、
gosh> (continuation-add) |
となります。このプログラムは、Aを入力したところで終了してしまいますが、再度実行するとBの入力と計算結果の表示が行われます。Webアプリケーションに似ていると思いませんか。
プログラムを説明すると、contという広域変数に値がある場合はそれを関数として実行し、cont変数をfalseに戻します。contがfalseの場合は、Aを入力し、B入力以降の処理をクロージャとしてcont変数に代入しています。
ここで特筆すべきことは、aの値は明示的に保存してないにもかかわらず保存されていて、2回目の実行で使えることです。また、(set! cont (lambda()などの余分なコードが入っていますが、処理の大部分は最初に説明したシンプルなプログラムそのままです。
このようなスタイルのプログラムは、継続ベースのアプリケーションと呼ばれています。schemeの継続という言葉は、厳密にはここに書いたものとは異なる側面もありますが、ここではこれ以上は追求しないことにします。
このプログラムでは、継続すべき処理を1つの広域変数にしまっているので現実的なWebアプリケーションには使えません。そこで、次項ではもう少し実用に近い継続ベースのWebアプリケーションを作ってみます。
1/3 |
| Index | |
| 継続を使ったコントローラを作る | |
| Page1 クロージャ 継続ベースのアプリケーション |
|
| Page2 継続ベースのWebアプリケーションを作る モジュール templateモジュール serverプログラム |
|
| Page3 controllerモジュール ORMモジュール userモジュール テンプレート まとめ |
|
| Gaucheでメタプログラミング |
| Coding Edgeお勧め記事 |
| いまさらアルゴリズムを学ぶ意味 コーディングに役立つ! アルゴリズムの基本(1) コンピュータに「3の倍数と3の付く数字」を判断させるにはどうしたらいいか。発想力を鍛えよう |
|
| Zope 3の魅力に迫る Zope 3とは何ぞや?(1) Pythonで書かれたWebアプリケーションフレームワーク「Zope 3」。ほかのソフトウェアとは一体何が違っているのか? |
|
| 貧弱環境プログラミングのススメ 柴田 淳のコーディング天国 高性能なIT機器に囲まれた環境でコンピュータの動作原理に触れることは可能だろうか。貧弱なPC上にビットマップの直線をどうやって引く? |
|
| Haskellプログラミングの楽しみ方 のんびりHaskell(1) 関数型言語に分類されるHaskell。C言語などの手続き型言語とまったく異なるプログラミングの世界に踏み出してみよう |
|
| ちょっと変わったLisp入門 Gaucheでメタプログラミング(1) Lispの一種であるScheme。いくつかある処理系の中でも気軽にスクリプトを書けるGaucheでLispの世界を体験してみよう |
|
TechTargetジャパン
- 実例で学ぶRailsアプリのテスト方法 (2011/12/22)
具体的なWebアプリを例に簡単なテストを使ったリファクタリングについ
て解説する - Railsの人気テストフレームワーク6選! (2011/8/18)
今回からテストを使ったリファクタリングを解説する。まずはRailsで人
気のあるテストフレームワークをいくつか紹介する - ActiveRecordの更新系操作 (2011/6/27)
Railsのモデル層を担当するActiveRecordを使った登録、更新、削除
など、更新系の機能を中心に見ていきます - 実例アプリで学ぶ“Railsらしさ”の基礎 (2011/5/26)
Ruby on Railsで書かれた実例アプリを取り上げて、初心者が陥りがちなコードの書き方を指摘します。より「Railsらしい」コードとは?
|
|

