perl随记

来源:互联网 发布:lelo sona 知乎 编辑:程序博客网 时间:2024/05/16 13:00
 #!/usr/bin/perl use strict;use warnings;use v5.14;=pod  检查所携带的的供应物品=cut#必带品my @require=qw(prescer sunscreen water_bottle jacket);#查检gilligan所带的物品my %gilligan = map {$_,1}qw(red_shirt hat lucky_socks water_botter);foreach my $item (@require){    #not in list    say "Gilligan is missing $item" unless $gilligan{$item};}print '-' x 80,">\n";#检查professor所带物品my %professor = map {$_,1}qw(sunscreen water_bottle slide_rule batteries radio);foreach my $item (@require){  say "Professor is missing $item" unless $professor{$item};}=pod   如果这样编写代码,就会现有太多的重复的代码,下面的列子将考虑代码重构=cutprint '-' x 80,">\n";sub check_requrie_item{   my $who = shift;   my %who_item = map {$_,1}@_; #the reset are the person's item   my @require=qw(prescer sunscreen water_bottle jacket);   foreach my $item (@require)   {      say "$who is missing $item" unless $who_item{$item};   }}=pod  通过参数列表,也就是@_,向子例程传入5项=cutmy @Gilligan_new=qw(red_shirt hat lucky_socks water_botter);&check_requrie_item("Gilligan_new",@Gilligan_new);#!/usr/bin/perl use strict;use warnings;=pod  通常情况下,变量的所有引用在变量销毁之前都销毁了但是如果其中一个引用比变量名存在的更久会怎么样?例如,考虑运行下代码将会得的输出=cutmy $ref;{   #//该作用结束后,@skipper被销毁   my @skipper =qw(blue_shirt hat jacket preserver sunscreen); #ref cont 1   $ref = \@skipper; #ref count 2   &sp();   print "\@skipper : @skipper\n";   print "$ref->[2]\n"; #result is jacket   &sp();}=pod这些一直存在,直到我们销毁了最后指向这些数据的引用$ref = undef;=cutprint "$ref->[2]\n"; #result still is jacket  #ref count 1#@skipper变量被销毁,但是数据仍然可以访问,是因这数据在内存中,这些元素存在一个匿名数组中push @$ref,'newtest';print "\$ref : @$ref\n";=pod 引用计数和嵌套数据结构=cut#想象一下中间变量是所有子例子程一部分my @all_names;sub initialize_provisions_list{   my @Skipper=qw(blue_shirt hat jacket preserver sunsreen);   my @Skipper_name=("Skipper",\@Skipper);   my @Professor=qw(sunscreen water_bottle slide_rule batteries radio);   my @Professor_name=('Professor',\@Professor);   my @Gilligan=qw(red_shirt hat lucky_socks water_bottle);   my @Gilligan_name=('Gilligan',\@Gilligan);   @all_names=(  #set globle                 \@Skipper_name,                 \@Professor_name,                 \@Gilligan_name   );}&initialize_provisions_list();#//设定@all_names数组包含了三个引用.在该子例程内部,先将命名数组引用放入其他命名数组中.最终,所有值都#//放置于全局数组@all_names中.然而,一旦子例程返回,6个数组将被销毁,因为每个数组有另一个指向它们的引用,#//所以将引用计数临时设置为2,但是当数组名称销毁之后,引用计数将变为1。因为计数不为零,所以该数据将继续#//存在,尽管它现在只是被@all_names数组的元素所引用。#与其对全局变量赋值,还不如按照下列方式不用@all_names数组重写代码,并且直接返回列表:my @all_names2;sub initialize_provisions_list2{   my @Skipper=qw(blue_shirt hat jacket preserver sunsreen);   my @Skipper_name=("Skipper",\@Skipper);   my @Professor=qw(sunscreen water_bottle slide_rule batteries radio);   my @Professor_name=('Professor',\@Professor);   my @Gilligan=qw(red_shirt hat lucky_socks water_bottle);   my @Gilligan_name=('Gilligan',\@Gilligan);   return (               \@Skipper_name,             \@Professor_name,             \@Gilligan_name   );}@all_names2 = &initialize_provisions_list2();=pod  删除数据顶端的节点通常意味着删除该数据树包含的所有数据。例外情况是当对嵌套数据的引用添加额外的副本时,数据就不会丢失。例如下面的,如果复制Gilligan的供应列表:=cutmy $gilligan_stuff = $all_names2[2][1];@all_names2 = undef;print "@$gilligan_stuff\n";&sp();sub sp{   print '-' x 80,">\n";}=pod 直接创建匿名数组=cut#临时语句块my @skipper_with_names;{   my @skipper=qw(blue_shirt hat jacket preserver sunscreen);   @skipper_with_names=('The Skipper',\@skipper);}#直接使用匿名数组构造函数my $ref_to_skipper_provisions= [qw(blue_shirt hat jacket preserver sunscreen)];#访问数组元素print "@$ref_to_skipper_provisions\n";&sp();my $ref_new_skipper;{  my @temporay_name=(qw(blue_shirt hat jacket preserver sunscreen));  $ref_new_skipper=\@temporay_name;}#构建更大的列表my $ref_new_test = [qw(blue_shirt hat jacket preserver sunscreen)];my @new_skipper_name = ('The skipper',$ref_new_test);print "$new_skipper_name[1]->[0]\n";print "@{$new_skipper_name[1]}\n";&sp();#代码重构my @skipper_new=(   'The Skipper',    [qw(blue_shirt hat jacket preserver sunscreen)]);#在列表中嵌套sub get_list{  return (  ['The Skipper',[qw(blue_shirt hat jacket preserver sunscreen)]],  ['The Professor',[qw(sunscreen water_bottle slide_rule batteries radio)]],  ['The Gilligan',[qw(red_shirt hat lucky_sockes water_bottle)]],  );}my @new_list=\&get_list();print "@{@{${$new_list[0]}}[1]}\n";&sp();=pod  创建匿名散例=cutmy %gilligan_name=(    name     => 'Gilligan',    hat      => 'White',    shirt    => 'Red',    postion  => 'First Mate',   );my %skipper_name=(    name     => 'Skipper',    hat      => 'Black',    shirt    => 'Blue',    postion  => 'Captain',   );my  @crew_name=(\%gilligan_name,\%skipper_name);foreach my $value (@crew_name){   print "====> $value\n";   foreach my $key (sort keys %{$value})   {        print "$key ${$value}{$key}\n";   }}&sp();#使用匿名构造函数直接构造引用,而匿名散例构造函数也是大括号的另一层含义my $ref_to_gilligan;{   my %gilligan_info=(      name       => 'Gilligan',      hat        => 'White',      shirt      => 'Red',      postion    => 'First Mate',      );      $ref_to_gilligan=\%gilligan_info;}#单个步骤my $gilligan_new_info={      name       => 'Gilligan',      hat        => 'White',      shirt      => 'Red',      postion    => 'First Mate',   };my $skipper_new_info={      name       => 'Skipper',      hat        => 'Black',      shirt      => 'Blue',      postion    => 'Caption',   };my @new_crew_name=($gilligan_new_info,$skipper_new_info);foreach my $arrary (@new_crew_name){   print "=====> $arrary\n";   foreach my $key (sort keys %{$arrary})   {       print "$key => ${$arrary}{$key}\n";   }}&sp();#避免临时变量my @new_arrary=(   {      name       => 'Skipper',      hat        => 'Black',      shirt      => 'Blue',      postion    => 'Caption',   },   {      name       => 'Gilligan',      hat        => 'White',      shirt      => 'Red',      postion    => 'First Mate',   }, );foreach my $value (@new_arrary){   print "=======> $value\n";   foreach my $key (sort keys %{$value})   {       print "$key =>", $value->{$key},"\n";   }}&sp();=pod   自动带入从文件读取数据,下面是数据格式The Skipper  blue_shirt  hat  preserver  sunscreenProfessor  sunscreen  water_bottle  slide_ruleGillgian  red_shirt  hat  lucky_sockes  water_bottle=cutmy %provisions;my $person;open(FL,'<','./data') or die "Cant open './data':$!\n";while(<FL>){  if(/^(\S.*)/)  {    #a person's name (no leading whitspace)    $person=$1;    $provisions{$person}=[] unless $provisions{$person};  }elsif(/^\s+(\S.*)/)  {    die "No persopn" unless defined $person;    push @{$provisions{$person}},$1;  }else  {    die "I don't unerstand:$_\n";  }}=pod  上述代码的结构my %provisions=(    'The Skipper'    => [qw(blue_shirt hat preserver sunscreen)],    'Professor'      => [qw(sunscreen water_bottle slide_rule)],    'Gilligan'       => [qw(red_shirt hat lucky_sockes water_bottle)]   );=cut#修改或增加值push @{$provisions{'The Skipper'}},"test";#增加一key and vlauepush @{$provisions{'new'}},qw(test1 test2 test3 test4);#对上述解引用foreach my $key (sort keys %provisions){    print "====> $key\n";    foreach my $val (@{$provisions{$key}})    {        print "$val ";    }    print "\n";}&sp();=pod  自动带入和散列src file:professor.hut gilligan.crew 1250professor.hut love.howell.hut 910thurston.howell.ut lovey.howell.hut 1250professor.hut lovey.howell.hut 450ginger.girl.hut laser3.copyroom.hut 1218ginger.girl.hut maryann.girl.hut 99=cutmy %total_bytes;open(DFL,'<','./data1') or die "Cannt open file './data1':$!\n";while(<DFL>){   my ($source,$destionation,$bytes)=split;   $total_bytes{$source}{$destionation} +=$bytes;  }=pod 上述代码数据结构(hash键是唯一的):%total_bytes=(  'professor.hut' =>{i       'gilligan.crew'    => '1250',       'love.howell.hut'  => '910',       'lovey.howell.hut' => '450',    },    'thurston.howell.ut' => {       'lovey.howell.hut' => '1250',    },   'ginger.girl.hut'    => {       'laser3.copyroom.hut'  => '1218',       'maryann.girl.hut'     => '99',    },)=cut#hash嵌套数据解引用foreach my $key1 (sort keys %total_bytes){   print "key1 =====> $key1\n";   foreach my $key2 (sort keys %{$total_bytes{$key1}})   {      print "$key2 => $total_bytes{$key1}{$key2}\n";   }}&sp();
0 0