第八章,引用:
[root@wx03 2]# cat a7.pl
@john = (47, "brown", 186);
@mary = (23, "hazel", 128);
@bill = (35, "blue", 157);
@vitals = ('john', 'mary', 'bill');
print $vitals[0][1];
print "\n";
[root@wx03 2]# perl a7.pl
brown
[root@wx03 2]# cat a8.pl
@vitals=([47,"brown",186],[23, "hazel", 128],[35, "blue", 157]);
print $vitals[0][1];
[root@wx03 2]# perl a8.pl
brown[root@wx03 2]#
[root@wx03 2]#
在本章的术语里,引用一个数值就是创建一个指向它的硬引用。
有两个内建的函
数,bless 和 block,它们都接受一个引用 作为自己的参数
8.2.1 反斜杠操作符
$scalarref = \$foo;
$constref = \186_282.42;
$arrayref = \@ARGV;
$hashref = \%ENV;
$coderef = \&handler;
$globref = \*STDOUT;
8.2.2.1 匿名数组组合器
你可以用方括弧创建一个创建一个指向匿名数组的引用:
[root@wx03 2]# cat a9.pl
$arrayref = [1, 2, ['a', 'b', 'c', 'd']];
print $arrayref->[2][1];
print "\n";
print $arrayref->[2]->[1];
print "\n";
[root@wx03 2]# perl a9.pl
b
b
[root@wx03 2]# perl a9.pl
b
b
8.2.2.2 匿名散列组合器
[root@wx03 3]# cat a1.pl
$table = {
"john" => [47, "brown", 186],
"mary" => [23, "hazel", 128],
"bill" => [35, "blue", 157],
};
print $table->{john}[1];
[root@wx03 3]# perl a1.pl
brown[root@wx03 3]#
8.2.2.3 匿名子过程组合器
[root@wx03 3]# cat a2.pl
$coderef = sub { print "Boink!\n" };
&$coderef ;
[root@wx03 3]# perl a2.pl
Boink!
8.2.3 对象构造器
特别是那些叫构造器的特殊子过程创建并返回指向对象的引用。对象 只是一种特殊的引用,
这些构造器是通过使用 bless 操作符,将一个普
通的引用物转换成一个对象实现的,所以我们可以 认为对象是一个赐过福的引用。
构造器可以用下列任何方法调用:
$objref = Doggie::->new(Tail => 'short', Ears => 'long'); #1
$objref = new Doggie:: Tail => 'short', Ears => 'long'; #2
$objref = Doggie->new(Tail => 'short', Ears => 'long'); #3
$objref = new Doggie Tail => 'short', Ears => 'long'; #4
8.3 使用硬引用
8.3.2 把一个 BLOCK 块当作变量名用
8.3.3 使用箭头操作符
对于指向数组,散列,或者子过程的引用,第三种解引用的方法涉及到使用-> 操作符
print $array[3]->{"English"}->[0];
@array 第4个元素的下表为English的第1个元素
[root@wx03 3]# cat a4.pl
$array=[1,2,3,{English=>['a','b','c','d9999']}];
print $array->[3]->{English}->[3]
[root@wx03 3]# perl a4.pl
d9999[root@wx03 3]#
请注意 $array[3] 和 $array->[3] 是不一样的。第一个东西讲的是 @array 里的第四个元素, 而第二个东西讲
的是一个保存在 $array 里的数组(可能是匿名的数组)引用的第四个元素。
perl 解引用自定义函数:
[root@wx03 3]# cat a3.pl
sub fun1() {
$a=shift;
$b=shift;
return $a + $b;
};
$ref=\&{fun1};
print $ref;
print "\n";
print &$ref(3,4);
print "\n";
print $ref->(3,4);
print "\n";
[root@wx03 3]# perl a3.pl
CODE(0x1aa2b30)
7
7
8.3.4 使用对象方法
8.3.5 伪散列
[root@wx03 3]# cat a5.pl
$john = [ {age => 1, eyes => 2, weight => 789}, 47, "brown", 186 ];
print $john->[0]->{weight};
print "\n";
[root@wx03 3]# perl a5.pl
789
8.3.7 闭合(闭包)
我们早些时候谈到过用一个没有名字的 sub {} 创建匿名子过程。
[root@wx03 3]# cat a6.pl
{
my $critter = "camel";
$critterref = \$critter;
};
print "\$critter is $critter\n";
print "\$critterref is $critterref\n";
print $$critterref."\n";
[root@wx03 3]# perl a6.pl
$critter is
$critterref is SCALAR(0x1b26ae8)
camel
$$critterref 的数值仍将是“camel”,即使在离开闭合的花括弧之后 $critter 消失了也如此。 但是 $critterref 也
可以指向一个指向了 $critter 的子过程:
[root@wx03 3]# cat a7.pl
{
my $critter = "camel";
$critterref = sub { return $critter };
};
print "\$critter is $critter \n";
print "\$critterref is $critterref \n";
print &$critterref;
[root@wx03 3]# perl a7.pl
$critter is
$critterref is CODE(0x19f9160)
camel[root@wx03 3]#
就意味着如果
你某一时刻在特定的词法范围定义了一个匿名函数,那么它就 假装自己是在那个范围里运行的,即使后面它又从该
范围之外调用。
Perl并不给对象方法提供引用,但是你可以使用闭合获取类似的效果。假设,你需要这么一个引用:
它不仅仅指向他代表的方法的子过程,而且它在调用的时候,还会在特定的对象上调用该方法。
8.5 花括弧,方括弧和引号
我们指出了 ${identifier} 是不被当作符号引用看待的。
8.5.2 垃圾收集,循环引用和弱引用