perl闭包


看了《perl语言编程》里闭包那节,结合自己例子及参考网上,把自己的理解整理出来,有理解错误地方,请指正。

我喜欢看代码方式,来理解作者为什么想出closure(闭包)这个词。

closure.pl

#!/usr/bin/perl
USE warnings;
#use strict;
 
my $out="i out";
{
  my $count=10;
  my $out="you out";
  $f_ref=sub {RETURN $out;};  --this is closure
  $s_ref=sub {RETURN ++$count;} --this is closure
};
print "which \$out is used!\n";
print "$out\n";
print &{$f_ref}."\n";
print "the \$count is changed?\n";
print "$count\n";
print &{$s_ref}."\n";
[root@xxx luoxuan]# perl closure.pl 
1、Name "main::count" used only once: possible typo at closure.pl line 16.
2、which $out is used!
3、i out
4、you out
5、the $count is changed?
6、Use of uninitialized value $count in concatenation (.) or string at closure.pl line 16.
7、11

为了方便说时,在每行输出的地方,加了个行号

1、$count定义在匿名block内,print “$count\n”是访问不到,所以报错
2、print “which \$out is used!\n”;
3、打印了匿名block外的$out的值
4、打印了匿名block内的$out的值
5、print “the \$count is changed?\n”;
6、匿名block内的$count是访问不到的
7、匿名block内的$count加1后返回

我的理解:
1、闭包可以访问闭包本身作用域范围之外的变量
2、当匿名block内没有定义和匿名block外变量名相同的变量,闭包访问是匿名block外变量的值

看着闭包,让我想到OOP:
当定义类的时候,会定义各个方法及属性,当创建对象后,我们可以通过各个方法(闭包),来访问对象中的属性。

参考:http://www.perlmonks.org/?node_id=138195

backup mysql db with perl script(一)


在感冒状态下,写个mysqldump备份mysql db的脚本,并对基本功能测试通过。这次主要是用mysqldump对单库及多库的备份,难免有考虑不周的地方,麻烦大家指出,谢谢!

#!/usr/bin/perl
########################################
#author:luoxuan                                                                   #
#purpose:backup database with mysqldump                           #
#date:20110628                                                                  #
########################################
 
use warnings;
use strict;
use Getopt::Std;
#use File::Basename;
use vars qw($opt_d);
getopts('d:');
my $mysql="/usr/local/mysql/bin/mysql";
my $mysqldump = "/usr/local/mysql/bin/mysqldump";
#the backup path
my $back_dir="/backup/";
my $time=`perl -MPOSIX -e 'print strftime "%Y-%m-%d", localtime()'`;
my $back_file="$back_dir$time.sql";
my $db_name=lc($opt_d);
our $put_db;
our $option_db;
our @rbackup;
our @tmpbackup;
 
###########################################
# print usage
###########################################
sub print_usage {
	my $text = <<EOF;
 
 NAME:
    back_db.pl
 
 SYNTAX:
    eg:
   1   back_db.pl -d dbname(all)
   2   if you want to backup a part of db,the db name must split with comma
       back_db.pl --databases -d db1,db2
 
 FUNCTION:
    backup mysql db with mysqldump
 
 PARAMETER:
    dbname:you want to backup the database name
 
EOF
	print STDERR $text;
	exit 0;
}
my $len_db = rindex $db_name."\$","\$";
if($len_db==0){
	&print_usage;
}
 
#path exists
unless(-e $back_dir){
	system("mkdir $back_dir");
}
 
#backup database on slave and get port
my $is_slave=readpipe("$mysql -uroot -e \"show variables like 'read_only'\"|grep read_only|awk '{print \$2}'");
chomp($is_slave);
if($is_slave eq "OFF"){
	print "This is master,i hope you can backup db on slave!thank you!\n";
	exit 0;
}
 
my $port=readpipe("$mysql -uroot -e \"show variables like 'port'\"|grep port|awk '{print \$2}'");
chomp($port);
 
#mysqldump all databases or single database
 
if($db_name eq "all"){
	$option_db="--all-databases";
}
else{
#check db exist
	my @userdb=readpipe("$mysql -uroot -e \"show databases\"|grep -v 'test\\|Database\\|information_schema\\|mysql'");
	foreach my $my_db(@userdb){
		chomp($my_db);
		$my_db.="|";
		$put_db.=$my_db; 
	}
	my @backup_db=split(/,/,$db_name);
	foreach my $single_db(@backup_db){
		$single_db=~s/^\s*|\s*$//g;
		if($put_db=~$single_db){
			chomp($single_db);
			$single_db.=" ";
			$option_db.=$single_db;
		}
		else{
			print "The db which you want to backup doesn\'t exists!!!\n";
			&print_usage;
		}
	}
}
 
sub dump_db{
	@tmpbackup=@_;
	@rbackup=@_;
	if(shift @tmpbackup eq "all"){    
		my $issucc = system("$mysqldump -uroot -P$port --single-transaction -q -e @rbackup>$back_file");
		if ($issucc==0){
			print "the backup is successful!\n";
		}
	}
	else{
		my $issucc = system("$mysqldump -uroot -P$port --single-transaction -q -e --databases @rbackup>$back_file");
		if ($issucc==0){
			print "the backup is successful!\n";
		}
	}   
}
 
eval{&dump_db($option_db);}

如何生成perl安装包


http://mathforum.org/~ken/perl_modules.html

innotop的Query segment fault


上次在公共的机器上安装了innotop,今天却跑不起来了,报错如下:

[RO] Query List (? for help) localhost, 12+23:52:22.049, 0.39 QPS, 18/1/3 con/run/cac thds, 5.1.48-log
 
When   Load  QPS   Slow   Se/In/Up/De%   QCacheHit  KCacheHit  BpsIn  BpsOut
Total  0.00  0.39  6.33k  59/1228/10/27      0.00%     72.73%  54.48   53.12
 
Cmd    ID      State  User   Host           DB      Time   Query段错误

google中找到如下信息:

I reproduced the error with :
#!/usr/bin/perl
#use Term::ReadKey qw(ReadMode ReadKey);
use Term::ReadKey;
ReadKey(10);

I fixed by upgrading to :
perl-TermReadKey-2.30-4.el5

查一下模块及版本号:

[root@xxx ~]# perl mod_ver.pl
......
Term::ReadKey --    2.14
......

mod_ver.pl脚本:

#!/usr/bin/perl    
use strict;
use ExtUtils::Installed;
 
my $inst= ExtUtils::Installed->new();    
my @modules = $inst->modules();    
 
foreach(@modules)
{
                my $ver = $inst->version($_) || "???";    
                printf("%-12s --    %s\n", $_, $ver);
}
exit 0;

重新安装Term::ReadKey,使用2.30版本,问题解决。

perl模块操作


删除模块:把*.pm文件删除,但删除不是很干净,所以不建议那么做

一、查询模块安装路径,确认*.pm文件位置(不建议做法)
1、找到模块安装路径

perl -e 'print join "\n",@INC'

2、

rm *.pm

这种方式删除后,还是能查到模块的信息。
查询已安装的模块:perl -MExtUtils::Installed -le ‘print foreach ExtUtils::Installed->new->modules’

二、脚本删除,很干净(建议使用)

#!/usr/local/bin/perl -w 
 
use ExtUtils::Packlist; 
use ExtUtils::Installed; 
 
$ARGV[0] or die "Usage: $0 Module::Name\n"; 
 
my $mod = $ARGV[0]; 
 
my $inst = ExtUtils::Installed->new(); 
 
    foreach my $item (sort($inst->files($mod))) { 
             print "removing $item\n"; 
             unlink $item; 
          } 
 
     my $packfile = $inst->packlist($mod)->packlist_file(); 
          print "removing $packfile\n"; 
          unlink $packfile;

查询模块:查询模块的方法有很多种,看各人喜好了

perl -MTime::HiRes -e 'print 0';

机器装那些模块:

perl -MExtUtils::Installed -le 'print foreach ExtUtils::Installed->new->modules'

看Perl内置安装了哪些模块:

perl -MModule::CoreList -le 'print foreach Module::CoreList::find_modules

如何知道自己装了哪些PERL的模块:

find `perl -e 'print "@INC"'` -name '*.pm' -print

查询当前使用的模块的版本

1、$perl -MTime::HiRes -e 'print $Module::VERSION;'
2、
#!/usr/bin/perl    
use strict;
use ExtUtils::Installed;
 
my $inst= ExtUtils::Installed->new();    
my @modules = $inst->modules();    
 
foreach(@modules)
{
                my $ver = $inst->version($_) || "???";    
                printf("%-12s --    %s\n", $_, $ver);
}
exit 0;

安装模块:

一、cpan
二、perl -MCPAN -e 'install 模块名'
三、
perl Makefile.PL
make
make install
四、cpanm

参考:http://www.php-oa.com/2008/11/15/perl-note.html