取势 明道 优术

作者为 扶 凯 发表

上一个文章,我们讲了在 .psgi 的文件中,怎么激活 Plack 的中间件组件和怎么使用 wrap 的类方法.我们提到使用 wrap 来包应用后,如果多个组件的话,会变得相当的繁琐,也不直观,所以我们这讲了一个 DSL 的语法(Domain Specific Language)会让这个更加容易.那就是 Plack::Builder.

Plack::Builder 的使用
在使用的 Plack:Builder 时是那么容易.只需使用关键字 builder 和 enable:

my $app = sub { 
    return [ 200, [], [ "Hello World" ] ];
};

use Plack::Builder;
builder {
    enable "JSONP";
    enable "Auth::Basic", authenticator => sub { ... };
    enable "Deflater";
    $app;
};

这会取得源应用($app) 的内容,然后会用 builder 块中使用了的中间件对整个应用通过 Deflater 来进行 wrap.这个例子中包含了 Auth::Basic 和 JSONP(内到外).他相当于下面这样的写法:
这需要将原来的应用程序($ APP)和包装与Deflater,验证它::基本和JSONP中间件组件(内到外).因此,这相当于:

$app = Plack::Middleware::Deflater->wrap($app);
$app = Plack::Middleware::Auth::Basic->wrap($app, authenticator => sub { });
$app = Plack::Middleware::JSONP->wrap($app);

但注意实际模块加载时,它是和上面反过来的.在这中间件包起来的顺序和 builder/enable DSL 包起来的应用相反,是不一样的.在 builder/enable DSL 中你可以 wrap 那个应用是在最内部做的.第一行加载的模块是在那个洋葱图片的最外面.你可以比较前面的那个洋葱图片,看看它的更加明显,.

在这激活中间件时,通过 Plack::Middleware:: 的前缀来加载的,所以 builder 只要写一个名字,但你想加载其它名字空间的模块,象 MyFramework::PSGI::MW::Foo 也是可以的,你只要写成

enable "+MyFramework::PSGI::MW::Foo";

这使用了 (+) 这个符号,告诉 PSGI 是使用的全名来做类名.

这做了些什么
如果你好奇的 Plack::Builder 做了些什么,你只要看看代码就知道发生了什么,这个 builder 取得代码块然后运行这些中的代码.然后取得结构,然后最后返回这个结果到 $app 中.会对返回的中间件以相反的顺序来进行 warp 的应用.所以最重要的是在最后一行 $app ,他包含了所以内部生成的代码块.

Thanks, Rack
这个 Plack::Builder 的主意全部照抄 Rack::Builder 的灵感.你能看到我们在 Perl 中使用了他们的关键字 🙂 .

来了就留个评论吧! 1个评论