Perl object/bless
Perl object实际上就是一个数据结构的引用,只不过用bless把它和包绑定在一起,像类一样调用函数的过程只是从bless绑定的包中调用相应函数的过程。看下边的例子:
[plain]
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中查找。
[plain]
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它的对象。
[plain]
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只是绑定变量和包,我们同样可以用下边的方法来实例化对象并调用函数:
[plain] view plaincopy
my $a = {one => 1, two => 2};
bless $a,Test;
$a->test();
同样,我们也可以绑定变量到一个未定义的包,只不过调用过程的时候会出错。
[plain]
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.
补充:综合编程 , 其他综合 ,