??xml version="1.0" encoding="utf-8" standalone="yes"?>
Perl 作ؓ一U脚本语a可以实时地生成和执行代码。这U特性可以把代码的编译推q到q行Ӟ所以又UCؓ“动态代码”。另外, Perl 也如 Java ?/span> C++ 一h供了异常处理机制。本文将初步探讨 Perl 中实现动态代码和异常处理机制的函敎ͼ eval 。如有错误不IƢ迎讨论和批评指正?/span>
eval 函数可以看作?/span> Perl 虚拟机,它的参数是一D?/span> Perl 代码。利?/span> ’perldoc –f eval?/font> 可以获取 eval 函数使用帮助Q其中介l了它的两种使用方式Q?/span>
l
eval EXPR
EXPR 是一个的表达式,例如Q?/span>
eval
"print $a"
;
eval
'print $a'
.
', $b'
;
eval
1
+
3
;
eval
'print '
.
'$a + $b, "\n"'
;
eval
$command;#$command = ‘print “hello Perl”?/span>
eval
$ARGV[0];
在执行时Q?/span> Perl 解释器会首先解析表达式的|然后表辑ּgZ?/span> Perl 语句插入当前执行上下文。所以,新生成的语句?/span> eval 语句本nh相同的上下文环境。这U方式中Q每ơ执?/span> eval 语句Q表辑ּ都会被解析。所以,如果 eval EXPR 如果出现在@环中Q表辑ּ可能会被解析多次?/span> eval 的这U方式?/span> Perl 脚本E序能实时生成和执行代码Q从而实C“动态代码”?/span>
l
eval BLOCK
BLOCK 是一个代码块Q例如:
eval {print $a};
eval {$a = 1, $b = 2, $c = $a + $b};
与第一U方式不同, BLOCK 只会被解析一ơ,然后整个插入当前 eval 函数所在的执行上下文。由于解析上的性能的优势,以及可以在编译时q行代码语法查,q种方式通常被作?/span> Perl 用来ZD代码提供异常捕捉机Ӟ虽然前一U方式也可以?/span>
按帮助的名称Q称 eval 的参数程序ؓ“小E序?/span> (mini-proggram) 。在两种方式中, eval 函数的返回值都是小E序的最后一条语句的|如果遇到 return 语句Q与子例E相同?/span>
Script1:
#!/usr/bin/perl -w
push
(
@program,'$i = 1;');
push
(
@program,'$i = 3; $j = 2; $k = $i + $j');
push
(
@program, '$i = 3; return 24; $k = $i + $j');
foreach
$exp (@program)
{
$rtn =eval($exp);
print
$rtn,"\n";
}
Output:
1
5
24
|
如果程序中有语法错误、运行时错误遇到 die 语句Q?/span> eval 返?/span> undef 。错误码被保存在 $@ 中?/span>
Script2:
#!/usr/bin/perl -w
push
(
@program, '$i = 3; die "error message"; $k = $i + $j');
foreach
$exp (@program)
{
$rtn =eval($exp);
if
(
!
defined
(
$rtn))
{
print
"Exception: "
,
$@,"\n";
}
else
{
print
$rtn,"\n";
}
}
;
Output:
Exception: error message at (eval 1) line 1.
|
Script3:
#!/usr/bin/perl -w
# a run-time error
eval
'$answer ='
;
# sets $@
warn
$@ if$@;
Output:
syntax error at (eval 1) line 2, at EOF
|
使用php的程序员没有这个烦|因ؓphp默认会将错误都打印到面上。CGIE序里如何才能做到这一点呢Q?/p>
CGI::Carpq个模块支持q个功能Q以下是例子Q?/p>
use CGI::Carp qw(fatalsToBrowser);
die "Bad error here";
详细请参?a >CGI::Crap的在U手?/p>
那如果是自己写的单CGIE序Q不使用CGI.pm怎么办?以下是简单的Ҏ......
BEGIN {
# fatal handler setting.
$SIG{__DIE__} = $SIG{__WARN__} = \&some_func;
}
#!/usr/bin/perl -wuse strict
BEGIN {
# fatal handler setting.
$SIG{__DIE__} = $SIG{__WARN__} = \&handler_fatal;
}
# some perl code goes here
......
sub handler_fatal {
print "Content-type: text/html\n\n";
print "@_";
}
上面q段perlE序中,如果调用一个名UCؓabc();的子例程Q浏览器看到如下的错误信息Q?/p>
Undefined subroutine &main::abc called at /home/hzqbbc/cgi-bin/fatal.cgi line 8.
通过q个Ҏ可以很便的q行E序调试了。Extmail中的CGI.pm是使用cM的方法,可以捕捉die(), warn() {函C生的错误及系l的错误提示?br />
from: http://www.hzqbbc.com/blog/arch/2005/05/aecgicexception.html
首先通过 new 来初始化一?ForkManager 对象Q同时必L明最大进E数。如果?0 的话可以避?fork 来达到调试程序的作用?/p>
然后使用 $pm->start 来开?fork?$pm 在子q程时返?0 ,父进E时q回子进E的q程P具体请参?Perl ?fork 文档Q。“and next?用来跌父进E。注意:如果 fork p|的话Q?$pm->start 提C错误,E序l束?/p>
$pm->finish l束子程序(假设我们一开始用了 start ?forkQ?/p>
注意Q在子进E中不能使用 $pm->start?如果你想在子q程中用另外一l子q程Q你必须再初始化一?Parallel::ForkManager 对象?br />
from: http://www.perlchina.org/archive/archive.php?action=archive&page=44
几个主要?CPAN 站点有:
安装Ҏ
我在q里介绍一下各U^C perl 模块的安装方法。以安装DBI模块Z?/p>
Linux/Unix下的安装ҎQ?/strong>
Linux/Unix 下安?Perl 模块有两U方法:手工安装和自动安装。第一U方法是?CPAN 上下载您需要的模块Q手工编译、安装。第二种Ҏ是?CPAN 模块自动完成下蝲、编译、安装的全过E?/p>
cd /usr/local/src
tar xvzf DBI-1.13.tar.gz
cd DBI-1.13
make test
make install
$>perl -MDBI -e1
perl -MCPAN -e shell
cpan>help
cpan>m
cpan>install DBI
cpan>quit
Win32下的安装ҎQ?/strong>
?Win32 下,使用 Active State ?Perl for Win32Q即Active Perl。Active Perl 的主在Q?br />http://www.activestate.com/ ?br />?Win32 下,比较Ҏ的是使用专门?Active Perl? 定制?Perl 模块。类g CPAN 模块Q?span class="newWikiWord">Active State也开发了一个自动安装工具叫?/span>PPMQPerl Package ManagerQ?/p>
ppm
PPM>h
cpan>query DBI
cpan>search DBI
PPM>install DBI
PPM>q
C: \ > set HTTP_proxy=http://proxy:8080
perl -e "print join ' ' @INC"
昄?perl 的库路径?>ppm install http://theoryx5.uwinnipeg.ca/ppms/GD.ppd
>ppm install http://theoryx5.uwinnipeg.ca/ppmpackages/GD.ppd
以上较ؓ详细地描qC各种q_?Perl 模块的安装方法。希望能够帮助国?Perl 爱好者们通过使用现有大量优秀?Perl 模块Q避免重复劳动,提高效率Q更好发?Perl 语言的强大威力?br />
from: http://www.perlchina.org/archive/archive.php?action=archive&page=51
Now you can type in any legal Perl code, and it will be immediately evaluated. You can also examine the symbol table, get stack backtraces, check variable values, and if you want to, set breakpoints and do the other things you can do in a symbolic debugger.
from: http://www.perl.com/doc/FAQs/FAQ/oldfaq-html/Q3.1.html
SCALAR
ARRAY
HASH
CODE
REF
GLOB
LVALUE
If the referenced object has been blessed into a package, then
that package name is returned instead. You can think of "ref" as
a "typeof" operator.
if (ref($r) eq "HASH") {
print "r is a reference to a hash.\n";
}
unless (ref($r)) {
print "r is not a reference at all.\n";
}
if (UNIVERSAL::isa($r, "HASH")) { # for subclassing
print "r is a reference to something that isa hash.\n";
}
See also perlref.