Perl object/bless

2102 ワード

Perl objectは実際にはデータ構造の参照であり、ケーブルでそれをパケットと結びつけるだけで、クラスのように関数を呼び出すプロセスは、ケーブルで縛られたカバンから該当関数を呼び出すだけです.下の例を見てください.
package Test;

sub new{
	my $class = shift;
	bless {},$class;
}

sub test{
	my $self = shift;
	print "this is test: ",%$self,"
"; } 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