Mercurial > pub > Impl
comparison Lib/IMPL/Object.pm @ 0:03e58a454b20
Создан репозитарий
author | Sergey |
---|---|
date | Tue, 14 Jul 2009 12:54:37 +0400 |
parents | |
children | 78cd38551534 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:03e58a454b20 |
---|---|
1 package IMPL::Object; | |
2 use strict; | |
3 | |
4 use base qw(IMPL::Class::Meta); | |
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 | |
66 sub surrogate { | |
67 bless {}, ref $_[0] || $_[0]; | |
68 } | |
69 | |
70 sub superCTOR { | |
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; | |
100 $class = ref $class || $class; | |
101 no strict 'refs'; | |
102 no warnings 'once'; | |
103 ${"${class}::CTOR"}{$_} = \&_pass_throgh_mapper foreach @{"${class}::ISA"}; | |
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 } | |
122 | |
123 =pod | |
124 =h1 SYNOPSIS | |
125 | |
126 package Foo; | |
127 use base qw(IMPL::Object); | |
128 | |
129 sub CTOR { | |
130 my ($this,$arg) = @_; | |
131 print "Foo: $arg\n"; | |
132 } | |
133 | |
134 package Bar; | |
135 use base qw(IMPL::Object); | |
136 | |
137 sub CTOR { | |
138 my ($this,$arg) = @_; | |
139 print "Bar: $arg\n"; | |
140 } | |
141 | |
142 package Baz; | |
143 use base qw(Foo Bar); | |
144 | |
145 our %CTOR = ( | |
146 Foo => sub { my %args = @_; $args{Mazzi}; }, | |
147 Bar => sub { my %args = @_; $args{Fugi}; } | |
148 ); | |
149 | |
150 package Composite; | |
151 use base qw(Baz Foo Bar); | |
152 | |
153 our %CTOR = ( | |
154 Foo => undef, | |
155 Bar => undef | |
156 ); | |
157 | |
158 sub CTOR { | |
159 my ($this,%args) = @_; | |
160 | |
161 print "Composite: $args{Text}\n"; | |
162 } | |
163 | |
164 package main; | |
165 | |
166 my $obj = new Composite( | |
167 Text => 'Hello World!', | |
168 Mazzi => 'Mazzi', | |
169 Fugi => 'Fugi' | |
170 ); | |
171 | |
172 # will print | |
173 # | |
174 # Foo: Mazzi | |
175 # Bar: Fugi | |
176 # Foo: | |
177 # Bar: | |
178 # Composite: Hello World! | |
179 | |
180 =h1 Description | |
181 Áàçîâûé êëàññ äëÿ îáúåêòîâ. Ðåàëèçóåò ìíîæåñòâåííîå íàñëåäîâàíèå | |
182 | |
183 | |
184 =h1 Members | |
185 =cut | |
186 | |
187 1; |