package Test; sub new{ my $class = shift; bless {},$class; } sub test{ my $self = shift; print "this is test: ",%$self,"\n"; } use Data::Dumper; use Devel::Peek; my $x = new Test(); # test 1 $x->test(); print Dumper $x; Dump $x; # test 2 $x->{one}=1; $x->test(); print $x->{one}; print Dumper $x; Dump $x;执行test 1这部分,可以看到实例化的对象本质还是一个PVHV,不过它的FLAGS多了一个OBJECT,而且STASH指向Test,表明所有的函数调用都是从包Test中查找。
SV = RV(0x182a868) at 0x182a85c REFCNT = 1 FLAGS = (PADMY,ROK) RV = 0x298ee4 SV = PVHV(0x29e85c) at 0x298ee4 REFCNT = 1 FLAGS = (OBJECT,OOK,SHAREKEYS) STASH = 0x182a70c "Test" ARRAY = 0x18246cc KEYS = 0 FILL = 0 MAX = 7 RITER = -1 EITER = 0x0 $VAR1 = bless( {}, 'Test' );执行test 2这部分,把对象只当作一个引用对待,可以看到同样有效。对于Perl的OO来说,通过这种方法还可以hack它的对象。
SV = RV(0x182a868) at 0x182a85c REFCNT = 1 FLAGS = (PADMY,ROK) RV = 0x298ee4 SV = PVHV(0x29e85c) at 0x298ee4 REFCNT = 1 FLAGS = (OBJECT,OOK,SHAREKEYS) STASH = 0x182a70c "Test" ARRAY = 0x18246cc (0:7, 1:1) hash quality = 100.0% KEYS = 1 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 Elt "one" HASH = 0x7f17f79a SV = IV(0x298f30) at 0x298f34 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1 $VAR1 = bless( { 'one' => 1 }, 'Test' );
因为OO只是绑定变量和包,我们同样可以用下边的方法来实例化对象并调用函数:
my $a = {one => 1, two => 2}; bless $a,Test; $a->test();同样,我们也可以绑定变量到一个未定义的包,只不过调用过程的时候会出错。
my $a = {one => 1, two => 2}; bless $a,Testing; $a->test(); Output: Can't locate object method "test" via package "Testing" at 005.pl line 33.
perldoc -f bless
perldoc perlobj