Perl(一)——不严谨教程
前言:
刚开始学Perl,学到哪记录到哪。
脚本编译与执行方式
1、在linux下使用terminal命令行执行perl代码:
特点:交互式,
perl -e 'perl code' #命令行中执行时-e和单引号不能少。-e是执行代码的命令行参数,命令行参数还包含其他命令
2、写成.pl文件后,通过命令行来执行文件
#xx.pl or xx.PL
#!/usr/bin/perl # 目录为perl解释器的路径(大概)
use strict; # 有机会再说作用
use warnings;
my $var = 5;
$var = 'abc';
...
chmod 0755 xx.pl #给xx.pl可执行权限,否则脚本无法运行
perl xx.pl #在shell中执行
注释
1、单行注释
#在注释语句前使用#
print "hello world\n"; #单行注释
2、多行注释
#多行注释
print "hello world\n";
=pod 只能放在一行的开头
多行注释
这种据说是最常见的(也就是说还有别种的)
叫plain old documentations
=cut
数据类型/变量
特点
perl解释器会根据上下文自动选择匹配数据的类型,不需要为变量指定类型。
perl有三种基本的数据类型:标量(整型和浮点型)、数组、哈希(python中的字典?);
不同类型的变量可以使用相同的名字。
标量
# 标量可以是整型、浮点数和字符串的任意一个
# 标量的定义使用$符号
# 数值的比较使用==,<=,>=,<,>
# 字符的比较使用eq(equal)和ne(not equal)
$var1 = 123; #整型,也存放在浮点寄存器中,实际上也是浮点数
$var2 = 1.23; #浮点数
$var3 = 9.21e+21; #浮点数,e的范围在-309到308
$var4 = "123"; #字符串,使用''可以实现多行字符串
数组
# 数组定义时在变量名前使用@符号;
# 可以直接输出
@names = ("Lisa", "Bob", "Andy"); # 使用(),use strict后字符要带引号
print "names[0] = $names[0]\n"; # 访问数组中的变量时,使用 $数组名[下标] 进行访问
print "names[1] = $names[1]\n";
print "names[2] = $names[2]\n";
特殊数组@_
哈希
显式定义
# 哈希的定义使用%
# 不能直接输出
%name_age = ('Bob',12,'Andy',32,"Lisa",29);
# key的引号没有要求,不知道key可不可以是数字;
# 哈希使用()
print "$name_age{'Bob'}\n"; #访问时哈希值使用$哈希名{key}
print "$name_age{'Andy'}\n";
print "$name_age{'Lisa'}\n";
隐性定义
# 不太熟悉,但是还挺有意思的
$my_hash = {
'chip_name' =>'ga100',
'tree_path' => {
'current' =>'home/abc',
'old' => 'home/xyz',
},
};
print $my_hash->{'chip_name'},"\n";
print $my_hash->{'tree_path'}->{'old'}, "\n";
变量上下文(变量之间的赋值?)
变量上下文由左边的变量类型决定,与右边的变量类型无关。
perl解释器会根据上下文来决定变量的类型(?内容吧)
@names = ('Bob', 'Andy', 'Lisa');
@copy = @names; # 复制数组
$len = @names; # 数组赋值给标量,返回数组元素个数
print "名字为 : @copy\n"; #名字是: Bob Andy Lisa
print "长度为 : $len\n"; # 长度为3
die/unless
# die 强制异常退出, 并作为error msg
die ("error happend");
#还可以配合unless实现python中assertion的作用
die ("file $file_path is not found.") unless(-e $file_path);
# -e用于确定文件是否存在,-d用于确定文件夹是否存在
# 如果$file_path存在则不抛出error
条件语句
if-else
if($var==1){
print "scalar";
}elsif{$var eq 'abc'}{ #使用elsif,而不是elseif
print "string"
}else{
print 'other';
}
三目运算符?:
# 和verilog的三目运算符一致
my $name = 'Lisa';
my $age = '20';
my $status = ($age > 40) ? "is me" : "not me";
print "$name - $status\n";
循环(foreach)
# foreach用于遍历数组和哈希的元素(暂时这么理解)
my @word = ('d', 's', 'q');
foreach my $elem (@word){
# $elem的作用域仅在foreach block中
# ()是标准格式
# $elem首次定义需要使用my
print " current elem is $elem \n";
}
# 使用$_, 可以避免定义$elem
foreach (@word){
print "current elem is $_ \n" #可以不使用分号影响不大
}
foreach与hash搭配使用(常见的使用场景)
# 定义隐性hash
my $hash_config = {
'a' => 'no1',
'b' => 'no2',
'c' => 'no3',
};
foreach my $rank (keys %{$hash_config}){
# keys是perl的内建命令,用于返回参数hash的所有key name
# %{}将隐性定义的hash强制转换为显性
# 这是因为keys只应用于显性hash
print "$rank states: $hash_config->{$rank} \n";
}
子程序/函数
要求:
Perl定义是全局的,函数可以在任意位置定义,并在任何位置进行调用;
所有子程序都有一个返回值;
定义相同名称的子程序会导致前面的子程序被覆盖;
定义子程序关键词sub,定义方式,sub 子程序名{}
my $n = 1;
sub marine{
$n += 1; #这里不应该用my
print "Hello sailor number is $n!\n";
}
&marine; #调用子程序,5.0以上可以不使用&
返回值:
# perl的子程序必有返回值,但是返回值不一定有用
# 返回值为子程序"最后执行的表达式"结果
sub sum{
print "Hey, called the sum subroutine! \n";
$fred + $barrney; #返回值
}
# 若最后subroutine最后一次执行的不是表达式,则会输出奇怪的东西
# 下式中返回“1”,表示输出成功
sub sum{
print "Hey, called the sum subroutine! \n";
$fred + $barrney; #返回值
print "I am returning a value!\n"
}
# subroutine返回值是最后执行的表达式,并非一定要求是运算
# 下式中返回最大的一个变量
sub reutrn_max{
if($fred >$ barrney){
$fred;
} else {
$barrney;
}
}
参数
私有变量
通常情况下,Perl中所有变量都是全局变量,
如果要在subroutine中设计私有变量(局部变量),可以使用my进行创建,
该私有变量的作用域从声明开始到闭合作用域为止;
闭合作用域可以是一对花括号中的区域,可以是一个文件,也可以是if,while,for,foreach,eval字符串内部
#!/usr/bin/perl
$string = "Global variables!"; # 全局变量
sub PrintOut{
my $string;
$string = "Local variables!"; # 局部变量
print "函数内部变量为:$string \n";
}
PrintOut(); # Local variables!
print "函数外部变量为:$string \n" # Global variables
变量的临时赋值
# 临时变量使用local而非my # 临时变量允许在作用域范围内为全局变量提供临时的值 # 待到作用域结束后,全局变量恢复原有值 $string = "Global variables!"; sub PrintTemp{ local $string; $string = "Temporary variables!"; PrintIntra(); print "PrintTemp的值为:$string\n"; }; sub PrintIntra{ print "PrintIntra的值为:$string\n"; } sub PrintInter{ print "PrintInter的值为:$string\n"; } PrintTemp(); # local的作用域为sub PrintTemp的花括号内,因此string全为Temporary variables # PrintTemp的值为:Temporary variables! # PrintIntra的值为: Temporary variables! PrintInter(); # 在local的作用域外,string恢复为Global variables # PrintInter的值为: Global variables! print "函数外部的值为:$string\n"; # 函数外部的值为: Global variables!
子程序调用上下文
# 将subroutine赋值给变量时,会根据变量类型返回相应的值
# 标量上下文
my $datestring = localtime( time );
print $datestring; # Sun Jun 12 15:58:09 2016
print "\n";
# 列表上下文
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
printf("%d-%d-%d %d:%d:%d",$year+1990,$mon+1,$mday,$hour,$min,$sec); # 2106-6-12 15:58:9
# printf 可以整理信息的格式,可以输出到文件里
print "\n";