首页 > Linux系统管理 > Plack 代码和结构分析-Plack::Builder[译]
2015
07-24

Plack 代码和结构分析-Plack::Builder[译]

Plack::Builder 为中间件的开发提供了特定领域语言 domain specific language (DSL) 的风格. 它看起来就象:

1
2
3
4
5
6
7
8
9
10
11
12
13
use Plack::Builder;
 
my $app1 = sub { ... };
my $app2 = sub { ... };
 
builder {
enable "Deflater";
enable "Session", store => "File";
enable "Debug", panels => [ qw(DBITrace Memory Timer) ];
 
mount "/narwhale" => $app1;
mount "/unicorn"  => $app2;
};

它是怎么样工作的? 这有三个巧妙技巧.

技巧 #1

第一个巧妙的技巧是 builder 块.

1
2
3
4
sub builder(&) {
my $block = shift;
...
}

这个 & 是函数原型. Perl 常常有一些于对传过来给函数的参数进行限制的需求. 这可以看看 perldoc perlsub 中有关 &:

 “&” 需要一个匿名的子程序,其中,如果作为第一个参数传递,不需要 “sub” 的关键字或其后的顿号.

如果我试图传给 builder() 一个标量或数组或任何不是一个匿名函数的东西, 将得到一个编译时错误. 但如果我给它传递一个匿名函数, 编译器才会让事情继续下去.

 

技巧 #2

接下来的技巧是在 Plack::Builder 内部实现 DSL keywords 应对函数名和指定的函数.

1
2
3
4
5
6
7
8
9
package Plack::Builder;
use strict;
use parent qw( Exporter );
our @EXPORT = qw( builder enable enable_if mount );
...
sub enable    {...}
sub enable_if {...}
sub mount     {...}
# etc

技巧 #3

还有一个有趣的想法. 注意这我们使用了 enable, enable_if, 或者 mount 在我们的 builder 块之外会出错. 这能正常是因为在 DSL 的关键字是函数的代码块引用. 默认的代码块内部是 croaks 的错误. 但在 builder 运行时, 这些旨用就会被真实代码所替换.

下面是一些简单的代码来说明它是如何工作的.

1
2
3
4
5
6
7
8
9
10
11
12
our $_enable = sub { Carp::croak(...) }; # << 定义一个代码块引用
 
sub enable { $_enable->(@_) }
 
sub builder(&) {
my $block = shift;
...
local $_enable = sub {...}; # << 暂时分配实际工作代码
...
my $app = $block->();
...
}
最后编辑:
作者:saunix
大型互联网公司linux系统运维攻城狮,专门担当消防员

留下一个回复