Chinaunix首页 | 论坛 | 博客
  • 博客访问: 564361
  • 博文数量: 201
  • 博客积分: 7734
  • 博客等级: 少将
  • 技术积分: 1994
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-09 19:18
文章分类

全部博文(201)

文章存档

2011年(28)

2010年(173)

分类:

2010-08-23 21:48:14

关于词法(my)变量:
事实上,词法可以不仅仅可以使用在子程序中,也可以在if、while、foreach当中。
 

foreach (1..10) {
    my($square) = $_ * $_;
    print "$_ squared is $square.\n";
}
results:
1 squared is 1.
2 squared is 4.
3 squared is 9.
4 squared is 16.
5 squared is 25.
6 squared is 36.
7 squared is 49.
8 squared is 64.
9 squared is 81.
10 squared is 100.

my($num) = @_;    
#列表上下文,和($num) = @_;相同,$num会被设为第一个参数

my $num = @_;    
#标量上下文,和$num = @_;相同,$num会被设为参数个数


my $fred, $barney     
#$barney没有被声明

my($fred,$barney);    
#两个都声明了


my @phone_number;    

use strict 编译命令:
Perl通常是一相当宽容的语言。但是,也许你会想要Perl更严格一些,这时只要使用use strict编译命令就行了。
编译命令(pragma),就是对编译器指示,告诉它关于程序代码的一些信息。use strict会让Perl语法编译强制执行
一些严格的、确保良好程序设计的规则。

$bamm_bamm = 3; #Perl会自动创建这个变量
$bammbamm += 1; #糟了!
因为Perl看到了一个新的变量名(变量名中的下划线是有意义的),它会创建一个新的变量。然后增加它的值。
如果你有先见之明,已经启用了warning的警告功能。那么Perl就会警告你这两个全局变量在程序中只出现过一次。

如果开启了use strict这个编译命令放在程序开头,Perl要求你一定要用my来声明每一个新的变量。
my $bamm_bamm = 3; #新的词法变量
现在,如果你再像之前那样拼错变量名,Perl就会抗议,说你从未声明$bammbamm这个变量,因此,错误在编译阶段就会被
找出来
$bammbamm += 1; #没有这个变量,这会是编译时严重错误(fatal error)

此限制只适用于新创建的变量;Perl的内置变量(如$_和@_)则完全不用事先声明。如果你在程序已经写完之后再加use strict,通常会得到一大堆警告信息,所以如果有需要,最好在一开始写程序时就使用它。

根据大部分人的建议,比整个屏幕长的程序都应该加上use strict。

return 操作符:
return操作符会从子程序中立即返回某个值:

my @names = qw/ fred barney betty dino wilma pebbles bamm-bamm /;
my $result = &which_element_is ("dino", @names);

sub which_element_is {
  my ($what, @array) = @_;
  foreach (0..$
#array) {    #数组@array 中所有元素的下标

    if ($what eq $array[$_]) {
     return $_;    
#一发现就提前返回

     }
     }
     -1;            
#没找到符合条件的元素(return在这里可有可无)

    }


上面程序里,&which_element_is子程序被用来找出"dino"在数组@names中的下标值。首先,我们会用my声明参数名:我们要找的$what,以及供程序搜索的数组@array。本例中,@array将会是数组@names的拷贝。foreach循环将会利用下标值逐项处理@array(第一个下标值是0,最后一个下标值是$#array)

省略”与号“
如果编译器在调用子程序之前看到了子程序的定义,或者Perl可以从语法识别它是子程序调用,那么该子程序就可以像内置
函数那样,在调用时省略”与号“。
假如Perl单从语法上便能看出它是省略了”与号“的子程序调用,通常就不会有什么问题。也就是说你只要将参数列表放进括号里,它就一定是函数。

 

my @cards = shuffle(@deck_of_cards);    #shuffle前没必要用&


sub division {
    $_[0] /$_[1];
    }
    
    my $quotient = division 355, 113;    
#使用&division

    
    假如子程序和Perl内置函数同名,就必须使用"与号"来调用。配合”与号“,才可以正确调用子程序。
    
    sub chomp {
        print "Munch, much!\n";
        }
        &chomp;        
#这里必须使用&,绝对不能省略!

        
        
非标量返回值:
子程序不仅可以返回标量值,如果你在列表上下文中调用它,它就能返回列表值。
假设你想取出某段范围的数字(如同范围操作符..的递增序列)只是你不但想递增,还想要递减序列。虽然范围操作符只能产生递增序列,不过要反过来取也不是什么难事:

sub list_from_fred_to_barney {
  if ($fred < $barney) {
  
#从$fred 数到$barney

    $fred..$barney;
    } else {
    
#从$fred倒数回$barney

    reverse $barney..$fred;
    }
  }
  $fred = 11;
  $barney = 6 ;
  @c = &list_from_fred_to_barney;    
#@c的值为(11,10,9,8,7,6)

  
持久性私有变量:
在子程序中可以使用my操作符来创建私有变量,但每次调用这个子程序的时候,这个私有变量都会被得新定义。使用state操作符来声明变量,便可以在子程序的多次调用间保留变量的值。

use 5.010;
sub marine {
   state $n = 0;    
#持久性私有变量 $n

  $n += 1;    
#全局变量$n

  print "Hello, sailor number $n!\n";
  }
  
==================================================
use 5.010;

running_sum( 5, 6);
running_sum( 1..3);
running_sum ( 4 );

sub running_sum {
    state $sum = 0;
    state @number;
    
    foreach my $number ( @_ ) {
        push @numbers, $number;
        $sum += $number;
        }
        
    say "The sum of (@numbers) is $sum";
    }
    
每次我们调用这个子程序的时候,它都会将新的参数与之前的参数相加,因些每次都会输出一个新的总和:
The sum of (5 6) is 11
The sum of (5 6 1 2 3) is 17
The sum of (5 6 1 2 3 4) is 21

state @array = qw( a b c );
#错误!


习题:
my @fred = qw{1 3 5 7 9};
my $fred_total = total(@fred);
print "The total of \@fred is $fred_total.\n";
print "Enter some numbers on separate lines: ";
my $user_total = total(<STDIN>);
print "The total of those numbers is $user_total.\n";

sub total {
  my $sum;    
#私有变量

  foreach (@_) {
    $sum += $_;
  }
  $sum;
  }
  


阅读(690) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~