▶︎
all
running…
strict
和warnings
,以规范编写的perl代码,如:
#!/usr/local/bin/perl use strict; use warnings;use 5.014
use v5.14.2
use 5.14.2
perldoc
来阅读模块文档,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::Critic
cpanp
(CPAN Plus):% cpanp -i Perl::Tidy
cpanm
(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 @INC
use lib
,它是在编译执行,行为等效于首个例子:将参数给的路径加入到@INC
数组的开头。use constant
可以设置常量,也是在编译时运行。PERL5LIB
:% export PER5LIB=/home/homqyy/lib:/usr/local/lib/perl5
PERL5LIB
环境变量的目的是为了给非管理员用户也能够扩展Perl的安装路径,如果管理员想增加额外的安装目录,只需要重新编译并安装Perl即可。-I
选项来扩展安装路径:% perl -I/home/homqyy/lib test.pl
local::lib
。
cpan
下载:% cpan local::lib
% perl -Mlocal::lib
:
cpan
:% cpan -I Set::Crossproduct
cpanm
:% 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
来代替 grep
eval
语句块后的分号是必须的,因为它是一个术语,语句块是真实的语句块,而不是像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.pl
perldebug
,或则在通过-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
来实现。
tee
qr//
'
作为分隔符(qr''
),则Perl解释器就不会做任何双引号插入操作:qr'$var'
flags
): m/pattern/flags
或s/pattern/flags
qr/pattern/flags
?flags:pattern
qr/abc(?x-i:G i l l i g a n)def/i
,使用了x
,移除了i
Regexp::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 dist
Module::Starter::AddModule
module-starter --moudle=addon_module --dist=.
MANIFEST
:记录检查的结果META.*
文件描述了发行版本的信息,其中客户端最关系_require
相关字段。perldoc pod
podchecker
perldoc module.pm
pod2html
, 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::More
Test::*
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.t
blib
模块搜索:perl -Mblib -T t/00-load.t
TODO
标注那些期望测试失败的用例,类似于备忘,该用例失败后不会作为失败处理。其中,$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) } })