extman 0.2.3代码简单分析(2)
上回介绍了extman 目录的结构,下面举个简单的例子说明模块的工作方法。我们从extman登录后第一个页面开始,即overview.cgi
1、将extman/libs 目录加入到perl @INC 变量中。
[code]
BEGIN {
if ($ENV{SCRIPT_FILENAME} =~ m!(.*/)cgi!) { #取得脚本运行的目录
$DIR = $1;
}else {
$DIR = '../';
}
unshift @INC, $DIR . 'libs'; #加入到@INC 中。
#print "Content-type: text/html\n\n";
#$SIG{__DIE__} = $SIG{__WARN__} = sub { print "@_" };
}
[/code]
2、执行代码块,别看这里只有几行,其实大文章在后面。
这里new 方法在Ext.pm 里,run 方法在MgrApp.pm 中。
为什么这样呢?往下看
[code]
eval {
require Ext::MgrApp::OverView; #使用这个包
my $app = Ext::MgrApp::OverView->new( config => $DIR . 'webman.cf',
directory => $DIR ); #传递配置文件的路径,及目录
$app->run; #执行子程序(功能)
};
[/code]
3、打开libs/Ext/MgrApp/OverView.pm
我看到里面并没有new,run 这两个方法,不过跟据perl 的继承,他会跟据@ISA 里指定的父类,向上找,我们看看这个程序里定义了他的父类。
在Ext::MgrApp 里。
[code]
@ISA = qw(Exporter Ext::MgrApp);
[/code]
那么我们再打开MgrApp.pm 这个文件,里面也没有发现我们要找的new 方法,但我们看到了run ,先不管他,我们在这个包里
看到新的@ISA ,他是指明了上一级的父类。
[code]
@Ext::MgrApp::ISA=qw(Ext Ext::Template);
[/code]
他告诉我们,如果找不到方法,再去上面那两个包找。ok ,我们打开Ext.pm
我们终于看到了new 这个方法,收藏得太好了。
[code]
sub new {
# cache the object if we has been initialized
return $ctx if $ctx;
my $this = shift;
my %opt = @_; #取得传递的变量,即是刚才overview.cgi 里new(config=>...) 里这边参数。
$ctx = bless {@_}, ref $this || $this;
if (!$opt{config}) {
die "No config file specify!\n"; # 没指定就会出错
}
if ($opt{directory}) {
$ctx->{directory} = $opt{directory};
}
$ctx->{config} = $opt{config};
if ($ENV{FCGI_ROLE} || $ENV{FCGI_APACHE_ROLE}) {
require Ext::FCGI;
Ext::FCGI::register_cleanup(\&cleanup);
}
#下面三行跟据配置文件取得参数,并存入$ctx->{cfg} 中,意思即是,你任何时候都可以通过$self->{cfg}->{SYS_xxxx} 来取得系统变量。
my $config = Ext::Config->new(file => $opt{config});
%Cfg = %{$config->dump};
$ctx->{cfg} = \%Cfg;
#初始化其它变量,init 这个方法在这个包没有吧,那么要回到他的子类里找,我们可以用ref($ctx) 看看返回什么结果,是Ext::MgrApp::Overview 那么必需从Overview 这个包里找init 这个方法
# init everything now, must call method directly!
if ($ctx->can('init')) {
$ctx->init;
}
$ctx;
}
[/code]
打开overview.pm 找到init 子程序
[code]
sub init {
my $self = shift;
$self->SUPER::init(@_); #执行父类的init 即Ext::MgrApp 里的init 方法。
return unless($self->valid||$self->permit);
#下面为注册功能,即告诉系统这些方法是的子程序用什么子程,看看浏览器的信息就知道了。__mode=.... 就是这样调用的。
$self->add_methods(overview => \&overview); # overview domain
$self->add_methods(overview_user => \&overview_user);
$self->add_methods(overview_alias => \&overview_alias);
$self->add_methods(overview_manager => \&overview_manager);
$self->{default_mode} = 'overview';
if ($self->{query}->cgi('domain')) {
$self->{tpl}->assign(
CUR_DOMAIN => $self->{query}->cgi('domain')
);
}
初始overview.pm 这个包里的一些信息。
$self->_initme;
$self;
}
[/code]
下面我们看看Ext::MgrApp.pm 里的init ,他在上面句块中的下面部分被调用。
[code]
$self->SUPER::init(@_);
[/code]
[[i] 本帖最后由 fengyong 于 2007-12-20 14:14 编辑 [/i]] 错了,快给我权限修改呀。 我顶 老大 好东西啊!!! 老大,我在转发邮件时overview.cgi的代码全盘出现在了邮件里了,为什么呢?你能给分析一下吗?
额~
真不容易上来了,今天这个破网老调。回个帖试下~页:
[1]