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"
}elseprint '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";

 

 

 

posted @ 2020-07-01 18:42  Pent°  阅读(396)  评论(0编辑  收藏  举报