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;