[root@node01 8]# cat a1.pl
@john = (47,"brown",186);
@mary = (23,"hazel",128);
@bill=(35,"blue",157);
@vitals=('john','mary','bill');
${$vitals[0]}[1]="red";
print @john;
[root@node01 8]# perl a1.pl
47red186[root@node01 8]#
8.1 什么是引用?
在我们的例子里,$vitals[0]的值是"john"
8.2.1 反斜杠操作符:
你可以用一个反斜杠创建一个指向任何命名变量或子过程的引用(
[root@node01 8]# cat a2.pl
$foo="123321";
$scalarref=$foo;
print $$scalarref."
";
[root@node01 8]# perl a2.pl
123321
8.2.2 匿名数据
8.2.2.1 匿名数组组合器:
你可以用方括弧创建一个指向匿名数组的引用
[root@node01 8]# cat a4.pl
use Data::Dumper;
$arrayref=[1,2,['a','b','c','d']];
print $arrayref;
print "
";
print Dumper($arrayref);
print "
";
[root@node01 8]# perl a4.pl
ARRAY(0x2608498)
$VAR1 = [
1,
2,
[
'a',
'b',
'c',
'd'
]
];
[root@node01 8]# cat a4.pl
use Data::Dumper;
$arrayref=[1,2,['a','b','c','d']];
print $arrayref;
print "
";
print Dumper($arrayref);
print "
";
print $arrayref->[2];
print "
";
print @{$arrayref->[2]};
print "
";
[root@node01 8]# perl a4.pl
ARRAY(0x1b6a498)
$VAR1 = [
1,
2,
[
'a',
'b',
'c',
'd'
]
];
ARRAY(0x1b56160)
abcd
现在我们有一个方法来表示我们本章开头的表:
8.2.2.2 匿名散列组合器:
你可以用花括弧创建一个指向匿名散列的引用:
[root@node01 8]# cat a5.pl
use Data::Dumper;
$hashref = {
'Adam' =>'Eve',
'Clyde' =>'xxdd',
'Autony' =>'Celo'.'patr'
};
print $hashref;
print "
";
print Dumper($hashref);
print "
";
[root@node01 8]# perl a5.pl
HASH(0x1d41160)
$VAR1 = {
'Adam' => 'Eve',
'Clyde' => 'xxdd',
'Autony' => 'Celopatr'
};
8.2.2.3 匿名子过程组合器:
你可以通过不带字过程名字的sub创建一个匿名子过程:
[root@node01 8]# cat a6.pl
$coderef = sub {print "Block!
";};
print $coderef;
print "
";
print &{$coderef};
print "
";
[root@node01 8]# perl a6.pl
CODE(0xb83c00)
Block!
1
[root@node01 8]# cat a6.pl
$coderef = sub {return "Block!";};
print $coderef;
print "
";
print &{$coderef};
print "
";
[root@node01 8]# perl a6.pl
CODE(0xf99c00)
Block!
请注意分号的位置,在这里要求用分号是为了终止该表达式。
(在最常见的声明和定义命名子过程的用法sub NAME{}里面是不需要这个分号)
一个没有名字的sub{}并不像是立即执行的。
它只是生成一个指向那些代码的引用.
8.2.3 对象构造器:
子过程也可以返回引用。
但是有时候别人要求你用一个子过程来创建引用而不是由你自己创建引用。
特别是那些叫构造器的特殊子过程创建并返回指向对象的引用。
对象只是一种特殊的引用,它知道自己是和哪个类关联在一起的,
而构造器知道如何创建那种关联关系。
所以我们可以认为对象是一种赐过福的引用。
构造器通常叫做new 特别是C++程序员更是如此看待。
[root@node01 8]# cat Doggie.pm
package Doggie;
sub new {
my $class=shift;
my %p=@_;
my $self={
Version=>"1.0",
a=> $p{'a'},
b=> $p{'b'},
c=> $p{'c'}
};
bless $self,$class;
return $self;
};
1;
[root@node01 8]# cat a1.pl
@john = (47,"brown",186);
@mary = (23,"hazel",128);
@bill=(35,"blue",157);
@vitals=('john','mary','bill');
${$vitals[0]}[1]="red";
print @john;
[root@node01 8]# perl t1.pl
$VAR1 = bless( {
'a' => '123',
'c' => '789',
'b' => '456',
'Version' => '1.0'
}, 'Doggie' );
[root@node01 8]#
8.2.4 句柄引用:
你可以通过引用同名的类型团来创建指向文件句柄或者目录句柄:
8.3 使用硬引用:
就像我们有无数的方法创建引用一样,我们也有几种方法使用引用(或者称之为解引用)
8.3.2 把一个BLOCK 块当作变量名用:
8.3.4 使用对象方法:
如果一个引用碰巧是一个指向一个对象的引用,那么定义该对象的类可能提供了访问该对象内部的方法,
8.3.7 闭合(闭包):
我们早些时候谈到过用一个没有名字的sub{}创建匿名子过程。
你可以把那些子过程看作是在运行时定义,这就意味着它们有一个生成的事件和一个定义的地点。
先让我们暂时忘掉子过程,先看看一个指向一个词法变量的引用:
[root@node01 8]# cat t3.pl
{
my $critter = "camel";
$critterref = $critter;
};
print "$critter=$critter
";
print $critterref;
print "
";
print $$critterref;
print "
";
[root@node01 8]# perl t3.pl
$critter=
SCALAR(0x1b4fbb8)
camel
##定义下拉菜单
my %section = (
"1-系统信息查询" => ["日志查询","权限管理"],
"2-综合查询" => [1,2,3,4,5,6],
"3-收起菜单" =>undef,
);
my (@frames,@button);
my %sub_of = (
"日志查询" => &push_button2 ,
"权限管理" => sub{ print "log log log" } ,
"VIEW DISK" => &push_button3 ,
1 => sub{ print "program 1" },
2 => sub{ print "program 2" },
3 => sub{ print "program 3" },
4 => sub{ print "program 4" },
5 => sub{ print "program 5" },
6 => sub{ print "program 6" },
);
闭合的另外一个用途就是函数生成器,也就是说,创建和返回全新函数的函数。
下面是一个用闭合实现的函数生成器的例子:
[root@node01 8]# cat t4.pl
sub make_saying {
my $salute = shift;
my $newfunc = sub {
my $target = shift;
print "$salute, $target!
";
};
return $newfunc; # 返回一个闭合
};
$f=make_saying("Howdy");
print $f->("world");
[root@node01 8]# perl t4.pl
Howdy, world!
1[root@node01 8]#