▶︎
all
running…
strict和warnings,以规范编写的perl代码,如:
#!/usr/local/bin/perl use strict; use warnings;use 5.014use v5.14.2use 5.14.2perldoc来阅读模块文档,Unix则用man也可以,如:
perldoc File::Basename # On Unix man File::Basenameuse File::Spec;
my $filespec = File::Spec->catfile( $homedir{homqyy}, 'web_docs', 'photos', 'USS_Minnow.gif');Module::CoreList是一个数据结构和接口库,该模块把很多关于Perl 5版本的模块历史信息聚合在一起,并且提供一个可编程的方式以访问它们:
use Module::CoreList; # 查看在perlv5.01400中的CPAN版本 print $Module::CoreList::version{5.01400}{CPAN};corelist:% corelist Module::Build
cpan工具安装:% cpan Perl::Criticcpanp(CPAN Plus):% cpanp -i Perl::Tidycpanm(CPAN Minus):% cpanm DBI WWW::Mechanize % wget <URL> (该URL可以从CPAN站点中获取)% tar -xzf <MODULE.tar.gz>% cd <MODULE>% perl Makefile.PL INSTALL_BASE参数来指定安装的路径:perl Makefile.PL INSTALL_BASE=/home/homqyy/% make% make test% make install% wget <URL> (该URL可以从CPAN站点中获取)% tar -xzf <MODULE.tar.gz>% cd <MODULE>% perl Build.PL --install_base参数来指定安装路径:% perl Build.PL --install_base /home/homqyy/% perl Build% perl Build test% perl Build install@INC数组里的路径去搜索模块的,可以通过以下两种方式获取@INC的值:
% perl -V% perl -le "print for @INCuse lib,它是在编译执行,行为等效于首个例子:将参数给的路径加入到@INC数组的开头。use constant可以设置常量,也是在编译时运行。PERL5LIB:% export PER5LIB=/home/homqyy/lib:/usr/local/lib/perl5PERL5LIB 环境变量的目的是为了给非管理员用户也能够扩展Perl的安装路径,如果管理员想增加额外的安装目录,只需要重新编译并安装Perl即可。-I 选项来扩展安装路径:% perl -I/home/homqyy/lib test.pllocal::lib。
cpan 下载:% cpan local::lib% perl -Mlocal::lib:
cpan :% cpan -I Set::Crossproductcpanm :% cpanm --local-lib HTML::Parser@INC 中:
use local::lib;print:打印sort:正序排列reverse:反序排列push:添加元素() 来表示此次结果不记录到列表中,即删除列表中的某个元素
my @result = map { my @digits = split //, $_; if ($digits[-1] == 4) { @digits; } else { # 不处理非4结尾的数据 (); } } @input_numbers;
map 来代替 grepeval 语句块后的分号是必须的,因为它是一个术语,语句块是真实的语句块,而不是像if和while。
eval 语句块中可以包含 my 等任意语句。
eval 语句块不能捕获最严重的错误:使perl自己中断的错误。
do 将一组语句汇聚成单个表达式,其执行结果为最后一个表达式的值。do 非常适合创建一个操作的作用域:
my $file_contents = do { local $/; local @ARGV = ( $filename ); <> };do还支持字符串参数的形式:
do $filename;
do 语句查找文件并读取该文件,然后切换内容为 eval 语句块的字符串形式,以执行它。do 将忽视文件中的任何错误,程序将继续执行。use 也可以用 require 来加载模块,实际 use 等效于以下代码:
BEGIN { require List::Util; List::Util->import(...); }
require 实际上是在运行程序时执行的,不过 require 可以记录所加载的文件,避免重复加载同样的文件。check_required_items,如果值大量的话势必会造成大规模的复制数据,浪费空间并损耗性能。
$crew[0]->{'name'}eval来检查:
sub is_hash_ref { my $hash_ref = shift; return eval { keys %$ref_type; 1 }; }@data1和@data2结束生命周期后,两个列表的引用计数都还为1。
[]创建,匿名散列由{}创建:
# 匿名数组 my $array_ref = ['one', 'two']; # 匿名散列 my $hash_ref = { one => '1', two => '2', };+来显示的告诉Perl这是一个匿名散列,在左括号后面加入一个;来显示表示是一个代码块:
+{ 'one' => 1, 'two' => 2, } # 这是一个匿名散列 {; push @array, '1'; } # 这是一个代码块-d参数来启动调试模式,类似于C程序的gdb:% perl -d ./test.plperldebug,或则在通过-d启动后输入h来查看帮助。use Data::Dumper;
my %total_bytes;
while (<>)
{
my ($source, $destination, $bytes) = split;
$total_bytes{$source}{$destination} += $bytes;
}
print Dumper(\%total_bytes)professor.hut gilligan.crew.hut 1250
professor.hut lovey.howell.hut 910
thurston.howell.hut lovey.howell.hut 1250
professor.hut lovey.howell.hut 450
ginger.girl.hut professor.hut 1218
ginger.girl.hut maryann.girl.hut 199$VAR1 = {
'thurston.howell.hut' => {
'lovey.howell.hut' => 1250
},
'professor.hut' => {
'lovey.howell.hut' => 1360,
'gilligan.crew.hut' => 1250
},
'ginger.girl.hut' => {
'maryann.girl.hut' => 199,
'professor.hut' => 1218
}
};Data::Dump:
use Data::Dump qw(dump); dump( \%total_bytes );Data::Printer
use Data::Printer; p( %total_bytes );Data::Dumper可以将复杂的数据结构转化为字节流,这样可以供另一个程序使用。
Data::Dumper输出的符号将变成普通的VAR符号,这样会影响阅读,因此可以利用Dump接口来实现符号的定义:
print Data::Dumper->Dump( [\@data1, \@data2], [qw(*data1, *data2)] );Storable:原因是其生成的更短小并且易于处理的文件:
use Storable qw(freeze thaw);
use Data::Dumper;
my @data1 = qw(one won);
my @data2 = qw(two too to);
push @data2, \@data1;
push @data1, \@data2;
# 将'[\@data1, \@data2]'冻结到'$frozen'中
my $frozen = freeze [\@data1, \@data2];
# 解冻(恢复)
my $array_all_ref = thaw($frozen);
print Dumper($array_all_ref);▶︎
all
running…
use Storable qw(nstore retrieve);
use Data::Dumper;
my @data1 = qw(one won);
my @data2 = qw(two too to);
push @data2, \@data1;
push @data1, \@data2;
# 将'[\@data1, \@data2]'冻结到文件中
nstore [\@data1, \@data2], './output/array.db';
# 从文件中恢复
my $array_all_ref = retrieve './output/array.db';
print Dumper($array_all_ref);▶︎
all
running…
my @d1 = @d2是浅拷贝,而Storable提供了深拷贝的方法:my @d1 = @{ dclone \@d2 }
Data::Dumper编组后的数据可读性更强
\进行引用,比如:
my $ref_to_greeter = \&skipper_greets; # '&'是函数sub { ...body of subroutine };,结果是创建了一个匿名函数的引用,比如:
my $ginger = sub { my $person = shift; print "Ginger: (in a sultry voice) Well hello, $person!\n" }; $ginger->('Skipper');
▶︎
all
running…
Data::Dump::Streamer模块可以将代码引用和闭包的内容展示出来
use Data::Dump::Streamer; my @luxuries = qw(Diamonds Furs Caviar); my $hash = { gilligan => sub { say 'Howdy Skipper!' }, Skipper => sub { say 'Gilligan!!!!' }, 'Mr. Howell' => sub { say 'Money money money!' }, Ginger => sub { say $luxuries[rand @luxuries] }, }; Dump $hash;
▶︎
all
running…
open支持打开匿名的临时文件:
# 文件名设置为'undef' open my $fh, '+>', undef or die "Could not open temp file: $!";undef
IO::Scalar来实现。
teeqr//
'作为分隔符(qr''),则Perl解释器就不会做任何双引号插入操作:qr'$var'
flags): m/pattern/flags或s/pattern/flagsqr/pattern/flags?flags:pattern qr/abc(?x-i:G i l l i g a n)def/i,使用了x,移除了iRegexp::Common模块来直接获取某个pattern。
egexp::Assemble模块帮助我们建立高效的择一匹配
use Data::Dumper;
sub data_for_path {
my $path = shift;
if (-f $path or -l $path) # files or symbolic links
{
return undef;
}
if (-d $path)
{
my %directory;
opendir PATH, $path or die "Cannot opendir $path: $!";
my @names = readdir PATH;
closedir PATH;
for my $name (@names)
{
next if $name eq '.' or $name eq '..';
$directory{$name} = data_for_path("$path/$name");
}
return \%directory;
}
warn "$path is neither a file nor a directory\n";
return undef;
}
print Dumper(&data_for_path('../'));▶︎
all
running…
my $arg = shift:作者更喜欢这种(my $arg) = @_:与lua风格相似.pm扩展名是“Perl模块”的意思
.pm的文件,在文件开头增加命名空间:package Navigation;。
perlmodlib文档)
::(双冒号)分隔多个名称:Name1::Name2
main
make,使用ExtUtils::Maker构建Module::Build构建% module-starter --module=Animal --author="yourName" --email="yourEmail" --verbose --mb% perl Build.PL% ./Build% ./Build test% ./Build disttest% ./Build dist% module-starter --module=Animal --author="homqyy" --email="youEmail" --verbose --builder="ExtUtils::Makemaker"% perl Makefile.PL% make% make test% make disttest% make distModule::Starter::AddModulemodule-starter --moudle=addon_module --dist=.MANIFEST:记录检查的结果META.*文件描述了发行版本的信息,其中客户端最关系_require相关字段。perldoc podpodcheckerperldoc module.pmpod2html, pod2man, pod2text, pod2usage=head n
# 1级标题 =head1 NAME # 2级标题 =head2 DESCRIPTION # 3级标题 =head3 Functions # 返回代码模式 =cut<和>括住所需的内容
<和>的个数,只要成对就行:B<<< 粗体文本 >>>
Class::method(Class, @args)# 包名 use Cow; Cow->speek; # 变量 my $beast = 'Cow'; $beast->speek;
Class->method(@args)等效@ISA注意事项:
@ISA中查找都是递归的,深度优先,并且从左到右进行。Test::MoreTest::*Test::Turorial
Test::Number::Delta
RELEASE_TESTING:作者自行的测试,为发行前的准备AUTOMATED_TESTING:自动测试,在用户侧进行的测试BEGIN中使用use_ok()
#!perl -T use Test::More; plan tests => 1; BEGIN { use_ok( 'Animal' ) || print "Bail out!\n"; }perl -T),因此PERL5LIB这个环境变量会被忽略,需要自行指定搜索路径:
-I指定:perl -Iblib/lib -T t/00-load.tblib模块搜索:perl -Mblib -T t/00-load.tTODO标注那些期望测试失败的用例,类似于备忘,该用例失败后不会作为失败处理。其中,$TODO作为测试的标签:
TODO: { local $TODO = "Need to replace the boilerplate text"; ... }Test::Pos和Test::Pos::Coverage时,./Build test会对Pod进行测试。
Devel::Cover% ./Build testcover来进行覆盖率测量% cover: 分隔多个搜索路径; 分隔多个搜索路径File::Basename,但是是面向对象的。
IO::Handler模块的对象。IO::Handle模块用于操作文件的子集。属于标准发型版本。
IO::Handle模块的前端,只要提供一条命令,就自动处理fork和exec命令,有点类似于C语言的popen
/dev/null
≡ var sidebarTOCBtn = document.getElementById('sidebar-toc-btn') sidebarTOCBtn.addEventListener('click', function(event) { event.stopPropagation() if (document.body.hasAttribute('html-show-sidebar-toc')) { document.body.removeAttribute('html-show-sidebar-toc') } else { document.body.setAttribute('html-show-sidebar-toc', true) } })