comparison lib/IMPL/Object/Abstract.pm @ 407:c6e90e02dd17 ref20150831

renamed Lib->lib
author cin
date Fri, 04 Sep 2015 19:40:23 +0300
parents
children ee36115f6a34
comparison
equal deleted inserted replaced
406:f23fcb19d3c1 407:c6e90e02dd17
1 package IMPL::Object::Abstract;
2 use strict;
3 use warnings;
4
5 use parent qw(IMPL::Class::Meta);
6 use Carp qw(croak);
7
8 our $MemoryLeakProtection;
9 my $Cleanup = 0;
10
11 my %cacheCTOR;
12
13 my $t = 0;
14 sub cache_ctor {
15 my $class = shift;
16
17 no strict 'refs';
18 my @sequence;
19
20 my $refCTORS = *{"${class}::CTOR"}{HASH};
21
22 foreach my $super ( @{"${class}::ISA"} ) {
23 my $superSequence = $cacheCTOR{$super} || cache_ctor($super);
24
25 my $mapper = $refCTORS ? $refCTORS->{$super} : undef;
26 if (ref $mapper eq 'CODE') {
27 if ($mapper == *_pass_through_mapper{CODE}) {
28 push @sequence,@$superSequence;
29 } else {
30 push @sequence, sub {
31 my $this = shift;
32 $this->$_($mapper->(@_)) foreach @$superSequence;
33 } if @$superSequence;
34 }
35 } elsif ($mapper and not ref $mapper and $mapper eq '@_') {
36 push @sequence,@$superSequence;
37 } else {
38 warn "Unsupported mapper type, in '$class' for the super class '$super'" if $mapper;
39 push @sequence, sub {
40 my $this = shift;
41 $this->$_() foreach @$superSequence;
42 } if @$superSequence;
43 }
44 }
45
46 push @sequence, *{"${class}::CTOR"}{CODE} if *{"${class}::CTOR"}{CODE};
47
48 $cacheCTOR{$class} = \@sequence;
49 return \@sequence;
50 }
51
52 sub dump_ctor {
53 my ($self) = @_;
54 $self = ref $self || $self;
55
56 warn "dumping $self .ctor";
57 warn "$_" foreach @{$cacheCTOR{$self}||[]};
58 }
59
60 sub callCTOR {
61 my $self = shift;
62 my $class = ref $self;
63
64 $self->$_(@_) foreach @{$cacheCTOR{$class} || cache_ctor($class)};
65 }
66
67 sub _init_dtor {
68 my ($class) = @_;
69
70 no strict 'refs';
71
72 # avoid warnings for classes without destructors
73 no warnings 'once';
74
75 my @dtors;
76
77 my @hierarchy = ($class);
78 my %visited;
79
80 while(my $subclass = shift @hierarchy) {
81 if(*{"${subclass}::DTOR"}{CODE}) {
82 push @dtors, *{"${subclass}::DTOR"}{CODE};
83 }
84
85 push @hierarchy, @{"${subclass}::ISA"};
86 }
87
88 if (@dtors) {
89
90 return *{"${class}::callDTOR"} = sub {
91 my ($self) = @_;
92 my $selfClass = ref $self;
93 if ($selfClass ne $class) {
94 goto &{$selfClass->_init_dtor()};
95 } else {
96 map $_->($self), @dtors;
97 }
98 }
99
100 } else {
101 return *{"${class}::callDTOR"} = sub {
102 my $self = ref $_[0];
103
104 goto &{$self->_init_dtor()} unless $self eq $class;
105 }
106 }
107 }
108
109 __PACKAGE__->_init_dtor();
110
111 sub toString {
112 my $self = shift;
113
114 return (ref $self || $self);
115 }
116
117 sub _typeof {
118 ref $_[0] || $_[0];
119 }
120
121 sub isDisposed {
122 0;
123 }
124
125 sub DESTROY {
126 shift->callDTOR();
127 }
128
129 sub END {
130 $Cleanup = 1;
131 }
132
133 sub _pass_through_mapper {
134 @_;
135 }
136
137 sub PassArgs {
138 \&_pass_through_mapper;
139 }
140
141 sub PassThroughArgs {
142 my $class = shift;
143 $class = ref $class || $class;
144 no strict 'refs';
145 no warnings 'once';
146 ${"${class}::CTOR"}{$_} = \&_pass_through_mapper foreach @{"${class}::ISA"};
147 }
148
149 package self;
150
151 our $AUTOLOAD;
152 sub AUTOLOAD {
153 goto &{caller(). substr $AUTOLOAD,4};
154 }
155
156 package supercall;
157
158 our $AUTOLOAD;
159 sub AUTOLOAD {
160 my $sub;
161 my $methodName = substr $AUTOLOAD,9;
162 no strict 'refs';
163 $sub = $_->can($methodName) and $sub->(@_) foreach @{caller().'::ISA'};
164 }
165
166 1;
167
168 __END__
169
170 =pod
171 =head1 SYNOPSIS
172
173 package MyBaseObject;
174 use parent qw(IMPL::Object::Abstract);
175
176 sub new {
177 # own implementation of the new opeator
178 }
179
180 sub surrogate {
181 # own implementation of the surrogate operator
182 }
183
184 =head1 DESCRIPTION
185
186 Реализация механизма вызова конструкторов и других вспомогательных вещей, кроме операторов
187 создания экземпляров.
188
189 =cut