加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Learning Perl 2

发布时间:2020-12-16 00:38:31 所属栏目:大数据 来源:网络整理
导读:1.子程序 ? 1).创建子程序:使用关键字sub sub marine { print "Hello,worldn"; } ? ? calling subroutines,使用号 marine (2).返回值:所有的子程序最后一个表达式的运算结果都当作返回值。所以子程序只有“”有用返回值“和无用返回值之分。所以让一个类

1.子程序

?

1).创建子程序:使用关键字sub

sub marine {

print "Hello,worldn";

}

? ? calling subroutines,使用&号

&marine

(2).返回值:所有的子程序最后一个表达式的运算结果都当作返回值。所以子程序只有“”有用返回值“和无用返回值之分。所以让一个类似print的函数的结果来充当返回值十分糟糕。比较合适的是最后一行有个if分支。

(3).参数

调用的时候加上列表表达式就行。例如&max(10,15)。多余的变量都会被忽略,超过数组@_边界的变量将会是undef。

Perl在子程序中用@_数组存储参数。第一个参数是$_[0],第二哥存储在$_[1]...

注意:这些变量仅是数组@_的一部分,与标量$_无关。这和任意变量$arr与@arr,$arr[0]无关的道理一样。

sub max {

if($_[0] > $_[1]) {

$_[0];

} else {

$_[1];

}

}

@_是子程序的私有变量,如果有了一个全局变量@_,调用前会先被存起来,并在子程序返回时恢复原本的值。

?

?

(4).Perl子程序的参数的传递是按引用传。

#!/usr/bin/perl -w
?
sub marine{
? ? ? ? $_[0]="sub1";
? ? ? ? $_[1]="sub2";
}
?
$m="out1";
$n="out2";
print marine($m,$n)."n";
print "$mn$n";
则会输出
sub2
sub1
sub2
(5).由于perl的子程序参数是可变长度的参数列表,可以用if来检查
if(@_ != 2) {
print "WARNING,this subroutine should get exactly two parameters!n"
}
? 块的最后一条语句可以省略;号。无论在控制结构的块还是在子程序的块中。
(6).return $_;立即返回某个值。
(7).何时可以省略调用子程序时的&:当定义在调用之前,或者用()来传递参数时就可以省略&
(8).返回非标量值,最后一行为列表即可
sub marine{
#...
reverse 1..10;
}
(9).采用高水位标记算法来处理任意数量参数的max
print &max(3,5,6,1,2,12);
#或者直接传入一个列表
#@numbers=(3,12);
#print &max(@numbers);
sub max {
? ? ? ? my($max_so_far)=shift @_;
? ? ? ? foreach (@_) {
? ? ? ? ? ? ? ? if($_ > $max_so_far) {
? ? ? ? ? ? ? ? ? ? ? ? $max_so_far=$_
? ? ? ? ? ? ? ? }
? ? ? ? }
? ? ? ? $max_so_far
}
2.perl范围声明
our,"把名字限于某个范围“,其实就是明确声明一个"全局变量",虽然是在某个模块或者函数里面定义的,外面的也可以访问,如果已经声明过了,再次用"our",表示此处用的是全局的那个,不是同名的私有或者局部变量
?our $PROGRAM_NAME = "waiter";
{
my ?$PROGRAM_NAME = "something";
our $PROGRAM_NAME = "server"; #这里的our和外面的相同,和前句不同。
# 这里调用的代码看到的是"server"
}
# 这里执行的代码看到的仍然是"server".
?
my,"把名字和值都限于限于某个范围",简单说,就是只能本层模块或者函数可以看到这个变量,高一层的或者低一层的都看不到的。
sub greeting1{
? ? my ($hello) = "How are you do?";
? ? greeting2();
}?
sub greeting2{
? ? print "$hellon";
}
$hello = "How are you doing?";
greeting2();
greeting1();
greeting2();
运行结果:
How are you doing?
How are you doing?
How are you doing?
--------------------------
一个 How are you do? 都没有,在greeting1中call greeting2时,greeting2看不到greeting1的私有 $hello变量,只能看到外面的全局变量$hello
?
local,"把值局限于某个范围",也有叫"动态词法范围",有点不好懂。我的理解,就是本层和本层下层的函数可以看到本层的变量,但是本层上一层的不可以。到底范围是多少,不仅取决于本层的函数,还要看下一层的程序长度和深度,所以叫"动态范围"。
sub greeting1{
? ? local ($hello) = "How are you do?";
? ? greeting2();
?}
sub greeting2{
? ? print "$hellon";
}
$hello = "How are you doing?";
greeting2();
greeting1();
greeting2();
运行结果:
How are you doing?
How are you do?
How are you doing?
-----------------------
跟用 my 时不一样了吧? 此时在greeting1调用greeting2时,greeting2可以看到greeting1的局部变量$hello,外部的全局变量当然就隐藏了。
?
范围操作符不会改变变量赋值时的上下文。
例如
my($num)=@_; #列表上下文,等同于($num)=@_,$num是第一个元素的值
my $num=@_; #标量上下文,等同于$num=@_,$num是列表的长度
?
3. 使用use strict;强制使用一些良好的程序规范,例如不能操作未初始化的变量。可以有效防止变量名打错的情况。
?
4. 钻石操作符
钻石操作符<>是perl的读取文件(文件名通过参数传入,即@ARGV数组。如果@ARGV为空,则改用标准输入流)每一行的操作符,让perl程序也能像cat,sed等应用程序直接处理文本文件。是一个整行输入操作符的特例。
#!/usr/bin/perl -w
?
while (defined ($line=<>)){
? ? ? ?chomp ($line);
? ? ? ?print "$linen";
}
或者简写成
while (<>) {
chomp;
print "$_n";
}
?
print <> ; ? cat 的perl实现,
print sort <> ; sort的perl实现
?
<>的另一个例子,通过打开的文件描述符
open(HANDLE,"c:/test.txt") ? or ? die ? "文件不能打开"; ? ?
while ? (<HANDLE>) ? ? ? ? ? ? #注:这就是对文件句柄读取一行并存入变量 ? $_ ??
{ ??
print; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #注:打印变量 ? $_ ??
}
?
5.输出至标准输出
print
注意:print (2+3)*4;会打印5,然后print的返回值1(成功)会被乘以4. 小心这种带括号的操作符用法。
printf和C语言的printf类似,%g是输出恰当的数值形式。自动输出整数,浮点数和指数形式。例如5/2, 51**17会输出2.5,1.0683e+29
生成格式字符串
my @items=qw(wilma dino pebbles)
my $format="The items are:n".("%10sn" x @items) #使用x来复制字符串,@items为3,即“%10sn”三遍
printf $format,@items
?
6.文件句柄
(1).打开文件句柄
通常文件句柄用大写标识。
Perl提供3种文件句柄:STDIN STDOUT STDERR由Perl的父进程(可能是Shell)提供。当使用其他的文件句柄时,使用open操作符告诉Perl。
例如: open CONFIG,"dino"
open CONFIG,"<dino" #同上即默认行为,表示这个文件是提供输入数据的。不能创建则返回失败0
open BEDROCK,">fred" #如果已经有一个文件存在,则清楚原有内容并以新内容取代之
open LOG,">>LogFile" #如果不存在,则创建。如果存在,则追加
检测文件句柄的有效性
my $success=open LOG,“>>logfile”
unless ($success) {
#open失败
}
比如可以直接使用die中止运行或者warning送出警告信息。perl程序的exit status:0成功,1语法错误,2处理某程序发生错误,3可能找不到某个细节配置文件等
if(!open LOG,">>logfile") {
warning "can not create file"
}
if(@ARGV < 2)
die "Not enough arguments.n"
另:open CONFIG,"logfile" or die "not such file";
关闭文件描述符: close LOG
?
(2).使用文件句柄
print LOG “...”;
printf STDERR "...";
open PASSWD,"/etc/passwd"
or die "cannot open passwd file"
while (<PASSWD>) {
chomp;
......
}
或者放到列表里
open PASSWD,'</etc/passwd';
@lines = <PASSWD>;
$line=shift @lines;
#print $line,"n";
foreach $temp (@lines) {
? ? ? ? print $temp;
}
?
(3).用select改变默认的输出文件句柄
select LOG;
print “<INFO>,....”; #就会输出到文件句柄LOG中而不是STDOUT
select STDOUT;
默认的情况,写出的文件都会经过缓冲处理。只要将变量$|设置为1,就会在每次输出操作后,立即清除缓冲区(flush)
?
(4).重新打开标准文件句柄
open STDERR, “>>/home/luffy/.error.log” #die和warn的信息会输送到STDERR中(默认是屏幕)
?
7.散列
(1).哈希是一种数据结构,类似数组。但是不像数组以数字下标进行检索,而是以检索的键(即唯一的字符串标识)进行检索。哈希相当于一些键/值队的集合,没有顺序。
键一定要是字符串,如果以50/20为键,则会被转换为一个含有三个字符的字符串”2.5”.
哈希没有大小上限,可以是任意大小。
相对于其他脚本语言的哈希(如awk),Perl的哈希不会因为变大而产生性能问题。
哈希的值可以是数字,字符串,undef或者这些类型的组合。
哈希中的元素,赋值时会自动增加。
当键的字符串严格符合变量定义要求,或者定义时使用=>来定义。就可以免去键的引号。例如$family_name{fred};
例如:
$family_name{“fred”}=”flintstone”;
foreach $person (qw <barney fred>) {
print “I‘ve heard of person $person $family_name{$person}”
}
(2).引用整个哈希,用%号
%myhash=("abc","bcd","cde",3); #以键,值,键,值,键,值存储为hash
%myhash=(%myhash,"def",4);
%myhash=(
"abc"=>1,
"bcd"=>2,
"cde"=>3
);
@myarr=%myhash; #展开为列表
%new_hash=%myhash; #哈希的赋值,注意这一行代码会让%myhash展开为列表,然后再复制给%new_hash
%new_hash=reverse %myhash; #同上,先展开为列表再做reverse运算。注意reverse操作不仅会使位置倒置,而且会使键/值互换 #这里注意一点:由于hash中不能有重复的键。如果展开的列表后面有重复的键,它的值会覆盖掉前面的!
(3). 散列函数
my $k = keys %myhash;
my $v = values %myhash;
if (%hash) { #直接作为bool判断
print “exists one kv pair”;
}
对散列进行迭代,可以使用each函数获得下一组kv队,直到所有元素被访问到。例如
while(($key,$value)=each %myhash) { #each会返回包含一组键值对的列表,直到each返回空列表,$key和$value都会是undef
? ? ? ? print "$key=>$value"."n";
}
if(exists $books{"Thinking in Java"}) #exists函数!
print "the book exists";
delete $book{"thinking in Java"} #delete函数!
}
哈希元素的内插,需要用循环来以此输出。不支持整个哈希列表的内插
my %hash = ("a"=>1,"b"=>2,"c"=>3,"d"=>4);
foreach $key (sort keys %hash)
{
? ? ? ? print "$key => $hash{$key}n";
}
?
参考:perl范围声明our,my,local ? ? ?http://blogold.chinaunix.net/u1/51156/showart_441696.html
Textbook:learning perl

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读