Mercurial > pub > Impl
comparison Lib/IMPL/Object.pm @ 2:78cd38551534
in develop
author | Sergey |
---|---|
date | Mon, 10 Aug 2009 17:39:08 +0400 |
parents | 03e58a454b20 |
children | e59f44f75f20 |
comparison
equal
deleted
inserted
replaced
1:3b418b134d8c | 2:78cd38551534 |
---|---|
1 package IMPL::Object; | 1 package IMPL::Object; |
2 use strict; | 2 use strict; |
3 | 3 |
4 use base qw(IMPL::Class::Meta); | 4 use base qw(IMPL::Object::Abstract); |
5 | |
6 our $MemoryLeakProtection; | |
7 my $Cleanup = 0; | |
8 our $Debug; | |
9 our %leaked_objects; | |
10 | |
11 my %cacheCTOR; | |
12 | |
13 | |
14 sub new { | |
15 my $class = shift; | |
16 my $self = bless {}, ref($class) || $class; | |
17 | |
18 $self->$_(@_) foreach @{$cacheCTOR{ref $self} || cache_ctor(ref $self)}; | |
19 | |
20 $self; | |
21 } | |
22 my $t = 0; | |
23 sub cache_ctor { | |
24 my $class = shift; | |
25 | |
26 no strict 'refs'; | |
27 my @sequence; | |
28 | |
29 my $refCTORS = *{"${class}::CTOR"}{HASH}; | |
30 | |
31 foreach my $super ( @{"${class}::ISA"} ) { | |
32 my $superSequence = $cacheCTOR{$super} || cache_ctor($super); | |
33 | |
34 my $mapper = $refCTORS ? $refCTORS->{$super} : undef; | |
35 if (ref $mapper eq 'CODE') { | |
36 if ($mapper == *_pass_throgh_mapper{CODE}) { | |
37 push @sequence,@$superSequence; | |
38 } else { | |
39 push @sequence, sub { | |
40 my $this = shift; | |
41 $this->$_($mapper->(@_)) foreach @$superSequence; | |
42 }; | |
43 } | |
44 } else { | |
45 warn "Unsupported mapper type, in '$class' for the super class '$super'" if $mapper; | |
46 push @sequence, sub { | |
47 my $this = shift; | |
48 $this->$_() foreach @$superSequence; | |
49 }; | |
50 } | |
51 } | |
52 | |
53 push @sequence, *{"${class}::CTOR"}{CODE} if *{"${class}::CTOR"}{CODE}; | |
54 | |
55 $cacheCTOR{$class} = \@sequence; | |
56 return \@sequence; | |
57 } | |
58 | |
59 sub callCTOR { | |
60 my $self = shift; | |
61 my $class = ref $self; | |
62 | |
63 $self->$_(@_) foreach @{$cacheCTOR{$class} || cache_ctor($class)}; | |
64 } | |
65 | 5 |
66 sub surrogate { | 6 sub surrogate { |
67 bless {}, ref $_[0] || $_[0]; | 7 bless {}, ref $_[0] || $_[0]; |
68 } | 8 } |
69 | 9 |
70 sub superCTOR { | 10 sub new { |
71 my $this = shift; | |
72 | |
73 warn "The mehod is deprecated, at " . caller; | |
74 } | |
75 | |
76 sub toString { | |
77 my $self = shift; | |
78 | |
79 return (ref $self || $self); | |
80 } | |
81 | |
82 sub DESTROY { | |
83 if ($MemoryLeakProtection and $Cleanup) { | |
84 my $this = shift; | |
85 warn sprintf("Object leaks: %s of type %s %s",$this->can('ToString') ? $this->ToString : $this,ref $this,UNIVERSAL::can($this,'_dump') ? $this->_dump : ''); | |
86 } | |
87 } | |
88 | |
89 sub END { | |
90 $Cleanup = 1; | |
91 $MemoryLeakProtection = 0 unless $Debug; | |
92 } | |
93 | |
94 sub _pass_throgh_mapper { | |
95 @_; | |
96 } | |
97 | |
98 sub PassThroughArgs { | |
99 my $class = shift; | 11 my $class = shift; |
100 $class = ref $class || $class; | 12 my $self = bless {}, ref($class) || $class; |
101 no strict 'refs'; | 13 $self->callCTOR(@_); |
102 no warnings 'once'; | 14 |
103 ${"${class}::CTOR"}{$_} = \&_pass_throgh_mapper foreach @{"${class}::ISA"}; | 15 $self; |
104 } | |
105 | |
106 package self; | |
107 | |
108 our $AUTOLOAD; | |
109 sub AUTOLOAD { | |
110 goto &{caller(). substr $AUTOLOAD,4}; | |
111 } | |
112 | |
113 package supercall; | |
114 | |
115 our $AUTOLOAD; | |
116 sub AUTOLOAD { | |
117 my $sub; | |
118 my $methodName = substr $AUTOLOAD,11; | |
119 no strict 'refs'; | |
120 $sub = $_->can($methodName) and $sub->(@_) foreach @{caller().'::ISA'}; | |
121 } | 16 } |
122 | 17 |
123 =pod | 18 =pod |
124 =h1 SYNOPSIS | 19 =h1 SYNOPSIS |
125 | 20 |
171 | 66 |
172 # will print | 67 # will print |
173 # | 68 # |
174 # Foo: Mazzi | 69 # Foo: Mazzi |
175 # Bar: Fugi | 70 # Bar: Fugi |
176 # Foo: | |
177 # Bar: | 71 # Bar: |
178 # Composite: Hello World! | 72 # Composite: Hello World! |
179 | 73 |
180 =h1 Description | 74 =h1 Description |
181 Базовый класс для объектов. Реализует множественное наследование | 75 Базовый класс для объектов, основанных на хеше. |
182 | |
183 | 76 |
184 =h1 Members | 77 =h1 Members |
78 | |
79 =level 4 | |
80 | |
81 =item operator C<new>(@args) | |
82 | |
83 Создает экземпляр объекта и вызывает конструктор с параметрами @args. | |
84 | |
85 =item operator C<surrogate>() | |
86 | |
87 Создает неинициализированный экземпляр объекта. | |
88 | |
89 =back | |
90 | |
91 =р1 Cavearts | |
92 | |
93 Нужно заметить, что директива C<use base> работает не совсем прозрачно, если в нашем примере | |
94 класс C<Composite> наследуется от C<Baz>, а затем C<Foo>, то наследование от | |
95 C<Foo> не произойдет поскольку он уже имеется в C<Baz>. Вот не задача:) | |
96 | |
185 =cut | 97 =cut |
186 | 98 |
187 1; | 99 1; |