Yokohama.pm 出張版 in YAPC::Asia 2009 前夜祭でSchenkerについて話します


Yokohama.pm 出張版 in YAPC::Asia 2009 前夜祭のスピーカー発表(追記あり) - Yokohama Perl Mongers
Yokohama.pm 出張版 in YAPC::Asia 2009 前夜祭を開催します - Yokohama Perl Mongers
http://conferences.yapcasia.org/ya2009/news/451


Yokohama.pm 出張版 in YAPC::Asia 2009 前夜祭でSchenkerについて話すことになりました。


GitHub - spiritloose/Schenker: DSL for quickly creating web applications


というわけでよろしくおねがいします。

Mojolicious::Lite


id:charsbarさんより。


Mojolicious::Lite - Charsbar::Note


Mojolicious::Lite 全く知らなかったです。よさそうですね。


HTTP::Engine使ってるSchenkerにも色々と利点があると思うので、細々とやっていこうかなとおもいます。(H::E::Interfaceいろいろ選べたり、Middleware使えたり、さらにDSL風(パクリ)だったりと。)

Schenker - RubyのSinatraのようなフレームワーク作成中


http://github.com/spiritloose/Schenker


前に RubySinatra を触ってみていいなとおもったので最近作り始めた。

ひととおり機能はそろってきたので公開してみる。


HTTP::Engine + HTTP::Engine::Middleware + HTTPx::Dispatcher + Sinatra風インターフェース
みたいな感じのフレームワーク、っていうかDSL

# myapp.pl
#!/usr/bin/env perl
package MyApp;
use Schenker;

get '/' => sub {
    'Hello, world!';
};

get '/hello/:name' => sub {
    my $args = shift;
    "Hello, $args->{name}!";
};


で `./myapp.pl` すると動く。デフォルトはServerSimpleだけど、CGIでもPOEでもModPerlでもFCGIでもAnyEvent(Remedieに入ってるやつ)でも動く。


まだドキュメントがないけど、RailsのScaffoldで生成されたものを移植したサンプルが http://github.com/spiritloose/schenker-sample にあります。


http://labs.unoh.net/2009/05/sinatra.html を参考にさせていただいて(パクって)チュートリアルを書いてみた。

$ git clone git://github.com/spiritloose/Schenker.git
$ cd Schenker
$ cpan -i .
# app.pl
#!/usr/bin/env perl
package App;
use Schenker;

get '/' => sub {
    'Hello, world';
};
$ ./app.pl
$ curl http://localhost:4567/

Routes

HTTPメソッドにURLとクロージャを渡します。

get '/' => sub {
};
post '/' => sub {
};
put '/' => sub {
};
Delete '/' => sub { # deleteは組み込み関数なので泣く泣く…
};
==追記==

b:id:kazuhookuさん
http://b.hatena.ne.jp/kazuhooku/20090730#bookmark-15017671

よさげ。もともと HTTP メソッドは大文字なんだから、全部 upcase しちゃえば Delete で泣く必要ないんじゃないかなと思った

ちょっと迷ってます。揃えたいんですが、大文字だと今度はHTTP::Request::Commonとかぶったり…

==追記おわり==

パラメータを含めたURLも可能

get '/hello/:name' => sub {
    my $args = shift;
   "Hello $args->{name}";
};


GETパラメータ、POSTパラメータはparam('xxx')かparams->{xxx}で取得できる。


アプリケーションファイルは複数に分けることが可能。
(分けないと見通しがつかない規模ならCatalyst等をお勧めしますが…)

#!/usr/bin/env perl
package App;
use Schenker;

get '/' => sub {
    "Hello world";
};
do 'more_routes.pl';

# more_routes.pl
use strict;
use warnings;

get '/foo' => sub {
    "Foo";
};
1;

Redirect

redirect '/';
redirect 'http://www.google.co.jp';
redirect '/', 303;
redirect '/', 307;

Session

有効にするにはTOPレベルか、configureブロックに書く

enable 'sessions';
get '/' => sub {
    session->set(count => 0);
    session->set(count => session->get('count') + 1);
};

Status

通常では200番のステータスコードになるがstatusメソッドをつかうと変更できる

get '/' => sub {
    status 404;
    "Not found";
};

Filters

イベントの前に実行される

Before sub { # beforeはMoose/Mouseで定義済みなので…
    warn 'before';
};


Nested params は組み込み。

<form>
  <input ... name="post[title]" />
  <input ... name="post[body]" />
  <input ... name="post[author]" />
</form>
param('post'); # { title => '', body => '', author => '' }

Views

viewファイルはroot/viewsに置きます。
今のところTTとText::MicroTemplateが使える。

get '/' do
    tt 'index';     # views/index.tt
    mt 'index';     # views/index.mt
end

Layouts

TTのWRAPPERを使ってください。

tt_options WRAPPER => 'layout.tt';


アプリケーションと同じファイルにviewが書ける。

get '/' => sub {
    tt 'index';
};

__END__
@@ index
hello, world!


PadWalkerが入ってるとローカル変数がそのままテンプレートで使える。

get '/' => sub {
    my $name = 'Michael Schenker';
    tt 'index';
};
__END__
hello, [% name %]

PadWalker入ってない or 使いたくない or Text::MicroTemplateの場合は stash や引数に渡す。

get '/' => sub {
    stash name => 'Rudolf Schenker'
    tt 'tt';
    mt 'mt', {}, stash->{name};
};
__END__
@@ tt
hello, [% name %]
@@ mt
hello, <?= $_[0] ?>
hello, <?= stash->{name} ?>

Models

Schenkerはmodelを提供してないので、好きなのを使ってください。


JSONでも出力してみる

use JSON;
get '/api/items.json' => sub {
    content_type 'application/json';
    to_json({ foo => 'bar' });
};

Helpers

helpersでメソッドを定義するとイベント内やテンプレートで使えます。
が、そのままサブルーチン定義しても一緒です。

helpers bar => sub {
    "$_[0]bar";
};
get '/:name' => sub {
    bar(params->{name})
};

HTTP::Engine::Middleware

Useで指定する。

Use 'HTTP::Engine::Middleware::MobileAttribute';

Schenker自体がいくつか読み込んでます。

Error Handling

not_found
定義されてないURLにアクセスがあった場合に動作。
デフォルトで設定されてますが、変えたいときに。

not_found sub {
    status 404;
    body "Not found";
};

error
例外が投げられたら動作

error sub {
    status 500;
    body 'Internal Server Error';
};

独自の例外を使いたい場合

define_error MyCustomError => sub {
    status 500;
    body 'MyCustomError';
};
get '/' => sub {
    raise MyCustomError;
};

development環境ではデフォルトでスタックトレースが表示されます(CGI::ExceptionManager::StackTrace)。

Configuration

configure development => sub {
    set dbname => 'devdb';
    enable 'feature';
};
configure production => sub {
    set dbname => 'productiondb';
    disable 'feature';
};
configure qw(development production) => sub {
};
get '/whatdb' => sub {
    'We are using the database named ' . options->dbname;
};

Deploy

サンプルアプリケーションを参考にしてください。

iPhone の ケースとスタンドを購入した。


ケースはこういうやつ。



本当はケースとかつけたくないんだけど、使ってるうちに「これ落としたらヤバイなぁ」という思い
が日に日に強くなってきたので購入。バキバキ怖すぎる。


スタンドは、


サンコ- iPhone 3G 可変式USBクレ―ドル USBIPZ7
サンコー
売り上げランキング: 160


これを購入。

裸のまま置いておくのは性に合わないので。


今のところ両方ともまずまず気に入ってる。