Perl object/bless

Perl object实际上就是一个数据结构的引用,只不过用bless把它和包绑定在一起,像类一样调用函数的过程只是从bless绑定的包中调用相应函数的过程。看下边的例子:

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

你可能感兴趣的:(Perl object/bless)