存档

‘Perl’ 分类的存档

Perl模块推荐-Smart::Comments

2009年6月17日 Johnny Woo 1 条评论

调试有两种方法
一种是使用调试器.从内存里面抓出你感兴趣的变量
观察变量和过程调用
这个方法不会干扰到代码
但是一般大家都不太喜欢用这个
因为各种调试器需要学习
而且太底层了
更多的情况下面,我们只要把变量的内容输出就可以了
这个时候我们一般选择在代码的各个地方插入print或者printf
缺点就是会弄乱代码
而且调试好要删掉,下次需要的时候又要加上.
改进一点的方法就是加上条件判断
如果设定的debug变量为真时就输出
缺点就是每个print的地方都会变成判断,一句变三句.

那么,有没有更方便的方法呢
如果你用Perl
那么恭喜你,你拥有庞大的CPAN,并且里面有我今天要推荐的主角
Smart::Comments
简单来说,就是会把特定的注释变成调试语句
例如简单的程序

下载: code.txt
  1. #!perl -w
  2. use Smart::Comments;
  3. $a{'a'}[0]=20;
  4. #debug info
  5. ### %a
  6. $a{'a'}[0]++;
  7. ### %a
  8. print $a{'a'}[0];

现在我们可以发现在###注释的地方
程序把%a哈希输出了
这样只要通过简单的是否use Smart::Comments就可以在调试模式下切换了
还有从命令行调用的方式.这样连第一句use也不用了
perl -MSmart::Comments test.pl
搞定~
你只要通过加上参数就能获取调试信息
是不是特别方便?

分类: Perl 标签: , ,

Perl解析APACHE日志

2009年6月5日 Johnny Woo 5 条评论
下载: access.log
10.1.1.95 - e800 [18/Mar/2005:12:21:42 +0800] "GET /stats/awstats.pl?config=e800 HTTP/1.1" 200 899 "http://10.1.1.1/pv/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Maxthon)"

以上是APACHE日志的格式,有时候我们直接使用Perl来分析日志文件并且获取所需要的内容则更加高效

下载: log.pl.perl
#!perl -w
open(FILE,"<log.txt");
while(<file>)
{
 
m/([0-9.]+?) [\w-]+? [\w-]+? \[(.*?)\] "(.*?)" (\d+?) (\d+?) "(.*?)" "(.*?)"/;
 
$IP{$1}++;
 
$TIME{$2}++;
 
$REQUEST{$3}++;
 
$CODE{$4}++;
 
$BYTES{$5}++;
 
$REFER{$6}++;
 
$CLIENT{$7}++;
}
print keys %IP;
print keys %TIME;
print keys %REQUEST;
print keys %CODE;
print keys %BYTES;
print keys %REFER;
print keys %CLIENT;
分类: Perl 标签: , ,

Win32下Perl移植版汇总

2009年2月20日 Johnny Woo 没有评论
Name Perl Versions Installer ActivePerl PPM CPAN PAR Maturity Support
Strawberry Perl 5.10.0 or 5.8.8 exe/zip no console yes yes stable community
Cygwin Perl 5.10.0 bundled no no yes no stable community
Vanilla Perl 5.10.0 exe no no yes no experimental none
ActivePerl 5.10.0 or 5.8.8 msi yes gui no yes stable commercial
Indigo Perl “5.8.10″ ??? zip no yes no ??? stable author
Camelbox 5.10.0 exe no no yes yes experimental community
SiePerl 5.8.8 exe no no ??? ??? stable ???
XAMPP + Perl 5.10.0 exe/zip plugin plugin same as AS from PPM stable community
CamelPack 5.8.7 exe yes gui yes ??? stable author
PXPerl 5.8.7 exe yes no yes no abandoned none
DeveloperSite.Net 5.8.7 exe no no no no stable community
Apache Perl 5.8.7 exe yes yes no yes stable author
Randy Kobes 5.8.7 exe yes yes no yes abandoned? none
nsPerl 5.005_03 zip no no no no abandoned none
Chocolate Perl TBA exe maybe no yes yes concept n/a
分类: Perl 标签:

通过Perl使用ntp更新linux时间

2009年2月12日 Johnny Woo 3 条评论
下载: ntp.pl
#!/usr/bin/perl -w
use Net::NTP;
my %response = get_ntp_response("时间服务器地址");
my $time = localtime( $response{'Receive Timestamp'});
#print $time."\n";
system("date -s '$time'");

注意两点
1.需要安装Net::NTP模块
2.此脚本需要有足够权限(因为调用date来设置系统时间)

分类: Perl 标签: , ,

Perl面向对象编程初探-1

2009年2月4日 Johnny Woo 2 条评论

由于Perl的面向对象编程是后来加入的.
所以其语法以及其他元素都显得比较不自然.
下面是这两天来对于Perl的OO编程的初步的一些探索
首先是类的建立
Perl的原则是不引入过多的保留字
所以Perl的类没有引入新的例如class之类的关键词,
而是使用了原来的包的概念.也就是一个类就是一个包.
包之内的函数就是类的function,包之类经过bless的数据结构,就是类的数据结构以及类本身
我们先来看一个例子

下载: perl1.pl
#!/usr/bin/perl -w
package Person;
#使用包来创建Person类
$data = {};
#在包内创建包变量(全局变量)
#类的函数,初始函数可以是任意名称,不是一定需要用new
#但是new一般是约定俗成的名字
sub new() {
    
my ( $class, @args ) = @_;
#注意,类的所有函数的参数都会传入一个隐含参数
#隐含参数是第一个参数,其值就是类的名称,这里就是Person
    
my ( $name$age )  = @args;
    
( $data->{name}, $data->{age} ) = @args;
#我们将后续的参数放入类的数据中,对类进行初始化
    
bless $data, $class;
#这一步是Perl和所有其他语言的不同之处
#bless的含义是将变量上绑定类信息,这样对于这个数据就可以
#调用类的函数
    
return $data;
#将帮定了类信息的数据结构返回,这样其他程序就可以通过new
#函数的调用之后的返回值来调用Person类里面的函数
}
 
sub printname() {
    
print $data->{name} . "\n";
}
 
package main;
#切换到主包
$pack = Person->new( "code_tin", 29 );
#创建一个Person类的对象,并且用参数进行初始化
#这里再提示一次,所有类的函数的调用.其第一个传入的参数都是
#隐含的类的名称,这点在后面分析其他创建类的方法中很有用
#除了上面所用的方法外,创建类还有2种方式
# $pack = Person::new( "code_tin", 29 ); 以及
# $pack = new Person( "code_tin", 29 );
$pack->printname();
#结果将是输出code_tin

这个例子和外面的很多Perl OO教程内的例子不一样.
而这个例子比外面的要简单.外面的很多例子太过于拘泥语法,有些太过于矫情
下面就是一般外面的OO所用的方法.在注释中我会标出区别

下载: perl2.pl
#!/usr/bin/perl -w
package Person;
sub new() {
    
my $data = {};
#将类的数据结构放在初始化函数中,作为局部变量,增加了安全性
    
my ( $class, @args ) = @_;
    
my ( $name$age )  = @args;
    
bless $data, $class;
    
( $data->{name}, $data->{age} ) = @args;
    
return $data;
}
 
sub printname() {
    
my ($localdata)=@_;
#这里多了一个创建局部变量,由于前面$data位于new()中
#所以这里访问利用到了隐含参数,将类的引用重新复制一份在此函数中使用
#类中的其他函数也需要作这一步.
    
print $localdata->{name} . "\n";
}
 
package main;
$pack = Person->new( "code_tin", 29 );
$pack->printname();

这里有几个区别的地方

1.数据结构放入了new函数内.这样增强了访问控制
有人前面可能就有疑问.将$data作为全局变量会不会别的类也用到
这里要提的是全局变量也就是包变量,他虽然在全局可视,但是别的包要
使用$data,则会默认是其本身包的$data,而不会是这个.
在其他包中要调用这个$data,需要指定包名称$Person::data
所以我还是推荐前面一种方法

2.由于类的数据放在了new函数内,
导致每个类的函数中都需要创建一个局部变量来指向这个数据结构
比较麻烦,个人觉得没有为了所谓的访问控制来作这种操作.
因为Perl的OO的理念本来就不是强访问控制的.

还有几个值得注意的地方

1.在package中不要以为使用my变量就是作用范围在包中,
my变量确实作用范围在代码块中,但是如果你在package后面跟着my变量
那么这个变量的作用域将会是全局.
因为package不是代码块
而大括号之间的内容才属于一个代码块
所以在package后面的my变量将不是由你所希望的那样变成package的私有变量

2.构建函数最后要return经过bless的变量.
在上面代码中如果你把new函数中最后的return删除
你会发现代码依然工作正常
因为Perl的特性就是会默认return最后操作的变量回去
而new里面一般可能最后是一个bless操作.而正好就把bless之后的内容返回回去了
但是如果你在new函数最后一句是操作的其他参数
你就会发现去掉return之后
在main::里面调用Person的函数会报错说找不到Person::函数名这个东西.
因为你没有把包含类信息的东西返回回去.

3.类的函数传入的第一个变量是类名
这点不要忽略掉.如果直接拿参数当成以前那样做法.将会导致参数错位

分类: Perl 标签: , ,

Perl使用GD生成曲线图

2009年1月14日 Johnny Woo 1 条评论
下载: code.txt
#!/usr/bin/perl -w
use GD::Graph::lines;
 
@data=(
[(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26)],
[(6,7,10,14,20,26,32,38,46,54,62,70,76,80,84,86,88,90,92,93,94,95,96,96,96,96,96)],
);
 
$my_graph = new GD::Graph::lines(800,300);
$my_graph->set(
x_label => 'weeks',
y_label => 'visitors',
itle => 'Title',
transparent => 0,
);
$my_graph->plot(\@data);
save_chart($my_graph, 'edit1');
sub save_chart
{
    
my $chart = shift or die "Need a chart!";
    
my $name = shift or die "Need a name!";
    
local(*OUT);
    
my $ext = $chart->export_format;
    
open(OUT, ">$name.$ext") or
    
die "Cannot open $name.$ext for write: $!";
    
binmode OUT;
    
print OUT $chart->gd->$ext();
    
close OUT;
}
分类: Perl 标签:

perl建立N x N层级目录

2008年10月8日 Johnny Woo 6 条评论
下载: code.txt
#!/usr/bin/perl -t
for $a (0..255)
{
      
mkdir $a;
      
for $b (0..255)
      
{
            
mkdir "$a/$b";
      
}
}
分类: Perl 标签:

PHP与Perl操作Memcached速度差异比较

2008年9月26日 Johnny Woo 6 条评论

由于最近在进行memcached方面的工作
在性能测试中
使用了php以及perl对memcached进行操作
结果发现php与perl对memcached操作的性能
差异大约在40~50%之间
以下是测试脚本
所作的操作一样.使用1k的数据重复512000次.
总共插入memcached 500M的数据

php操作脚本

下载: code.txt
<?php
ini_set("memcache.hash_function","crc32");
$memcache = new Memcache;
$memcache->addServer('localhost', 30001);
$memcache->flush();
for($i=0;$i<512000;$i++){
        
$memcache->set($i,
"共1k的填充数据",0,1000);
}
?>

接着是perl脚本

下载: code.txt
#!/usr/bin/perl
use Cache::Memcached();
$memcache=new Cache::Memcached{'servers'=>["localhost:30001"]};
$memcache->flush_all();
for($i=0;$i<512000;$i++){
    
$memcache->set($i,
"共1k的填充数据");
}
$memcache->disconnect_all();

从代码行数上来看.两者也几近一致
但是测试结果却是大相径庭
我们在linux下使用time对执行进行计时
3次执行结果如下

下载: code.txt
[root@lenovo5 ~]# time ./test1k.pl
real    1m2.265s
user    0m36.427s
sys     0m17.114s
[root@lenovo5 ~]# time ./test1k.pl
real    1m2.814s
user    0m36.380s
sys     0m17.463s
[root@lenovo5 ~]# time ./test1k.pl
real    1m13.684s
user    0m44.603s
sys     0m18.366s
[root@lenovo5 ~]# time php ./test1k.php
real    0m38.055s
user    0m11.768s
sys     0m13.891s
[root@lenovo5 ~]# time php ./test1k.php
real    0m38.892s
user    0m12.416s
sys     0m14.044s
[root@lenovo5 ~]# time php ./test1k.php
real    0m38.955s
user    0m12.430s
sys     0m13.088s

差异很明显.perl执行需要1分左右而php只需要40秒不到
就是php的执行比perl的大约快40%
分析之后有几个因素的可能
1.perl的字串处理速度较慢.我们看到perl版本的set中不需要加入长度参数.这样每次插入可能都会需要set函数去判断传入的字串长度.这样可能较慢.但是随后我们发现php的set虽然有长度参数.但是这个参数并非是强制性的.比如我参数写了1000,实际字串有1200.结果将会是插入1200长度的字串,而并没有截断.所以这一点不是非常站得住脚
2.perl的扩展与php扩展实现方式不同.php的memcache客户端是PECL.也就是C扩展,而perl的扩展实现很有可能还是perl.所以会有性能差异.

分类: PHP, Perl, memcached 标签:

PERL正则 思维导图

2008年7月29日 Johnny Woo 1 条评论

虽然不是很全.但是使用其中的内容
有80%的工作可以处理了

preg