Kentaro Kuribayashi's blog

Software Engineering, Management, Books, and Daily Journal.

elispはウェブアプリケーション記述言語やったんやー

こんにちわ。昨今、ウェブ開発の進化はすざましいですね。PythonPerlJava、色んな言語で書かれていると思います。
もちろん編集にはEmacsを使っているかと思います。
でも編集だけ?

違うよね!
elispはウェブアプリケーション記述言語なんだよ!

Plack::App::Emacs

package Plack::App::Emacs;
use 5.008008;
use strict;
use warnings;
use parent qw(Plack::Component);
use Plack::Request;
use Encode;
use JSON::PP;

our $VERSION = '0.01';

sub prepare_app {
    my $self = shift;
    $self->{emacsclient} ||= 'emacsclient';
    $self;
}

sub call {
    my ($self, $env) = @_;
    my $req = Plack::Request->new($env);
    my $json = JSON::PP->new->ascii
        ->allow_singlequote->allow_blessed->allow_nonref;
    my $str = $json->encode({
        uri => $env->{PATH_INFO}||'',
        method => $req->method,
        headers => [split( /\n/, $req->headers->as_string)],
        content => $req->content,
    });
    $str =~ s!"!\\x22!g;

    my $command = sprintf q{%s -ne '(plack:handle "%s")'},
        $self->{emacsclient},
        encode($self->{encoding} || 'utf8', $str);

    open(my $f, "$command|");
    binmode $f, ':utf8';
    my $out = <$f>;
    close $f;
    my $res = $json->decode(eval($out));
    $res->[2][0] = encode_utf8 $res->[2][0] if $res;
    $res || [500, ['Content-Type' => 'text/plain'], ['Internal Server Error']];
}

1;

Plack::Appのアプリケーションハンドラを書いたよ。これを起動するpsgiファイルを用意するよ!

app.psgi

use lib qw/lib/;
use Plack::Builder;
use Plack::App::Emacs;

builder {
    mount "/" => Plack::App::Emacs->new;
};

してEmacs側にハンドラを書くよ!

(require 'json)

(defun plack:handle (req)
  (json-encode-array
   '(200 ("Content-Type" "text/plain") ("Hello, World"))))

PSGIプロトコルそのままですね!便利!

起動しよう!

# plackup app.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/

ブラウザでhttp://localhost:5000を開こう!

f:id:antipop:20120128012055p:plain

やたー!
あとはアプリケーション書き放題ですね!
試しに掲示板書いてみるよ!

(以下略)