第八章,引用

第八章,引用:

[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 垃圾收集,循环引用和弱引用












posted @ 2016-05-16 17:16  czcb  阅读(78)  评论(0编辑  收藏  举报