comparison Lib/IMPL/Class/Meta.pm @ 229:47f77e6409f7

heavily reworked the resource model of the web application: *some ResourcesContraact functionality moved to Resource +Added CustomResource *Corrected action handlers
author sergey
date Sat, 29 Sep 2012 02:34:47 +0400
parents a8db61d0ed33
children 6d8092d8ce1b
comparison
equal deleted inserted replaced
228:431db7034a88 229:47f77e6409f7
67 } 67 }
68 } 68 }
69 } 69 }
70 70
71 sub static_accessor { 71 sub static_accessor {
72 my ($class,$name,$value,$clone) = @_; 72 my ($class,$name,$value,$inherit) = @_;
73
74 $inherit ||= 'inherit';
75
76 my $method = "static_accessor_$inherit";
77
78 return $class->$method($name,$value);
79 }
80
81 sub static_accessor_clone {
82 my ($class,$name,$value) = @_;
73 $class = ref $class || $class; 83 $class = ref $class || $class;
74 84
75 no strict 'refs'; 85 no strict 'refs';
76 86
77 *{"${class}::${name}"} = sub { 87 *{"${class}::${name}"} = sub {
79 89
80 if (@_ > 0) { 90 if (@_ > 0) {
81 $self = ref $self || $self; 91 $self = ref $self || $self;
82 92
83 if ($class ne $self) { 93 if ($class ne $self) {
84 $self->static_accessor( $name => $_[0] ); # define own class data 94 $self->static_accessor_clone( $name => $_[0] ); # define own class data
85 } else { 95 } else {
86 $value = $_[0]; 96 $value = $_[0];
87 } 97 }
88 } else { 98 } else {
89 ($clone and $class ne $self) 99 $self->static_accessor_clone($name => clone($value));
90 ? $self->static_accessor($name => clone($value),$clone)
91 : $value and $value ;
92 } 100 }
93 }; 101 };
94 $value 102 $value
95 }; 103 };
104
105 sub static_accessor_inherit {
106 my ($class,$name,$value) = @_;
107
108 no strict 'refs';
109
110 *{"${class}::$name"} = sub {
111 my $self = shift;
112
113 if (@_ > 0) {
114 $self = ref $self || $self;
115
116 if ($class ne $self) {
117 $self->static_accessor_inherit( $name => $_[0] ); # define own class data
118 } else {
119 $value = $_[0];
120 }
121 } else {
122 $value ;
123 }
124 }
125 }
126
127 sub static_accessor_own {
128 my ($class,$name,$value) = @_;
129
130 no strict 'refs';
131
132 *{"${class}::$name"} = sub {
133 my $self = shift;
134
135 if ($class ne $self) {
136 if (@_ > 0) {
137 $self->static_accessor_own( $name => $_[0] ); # define own class data
138 } else {
139 return;
140 }
141 } else {
142 if ( @_ > 0 ) {
143 $value = $_[0];
144 } else {
145 return $value;
146 }
147 }
148 }
149 }
96 150
97 sub _find_class_data { 151 sub _find_class_data {
98 my ($class,$name) = @_; 152 my ($class,$name) = @_;
99 153
100 no strict 'refs'; 154 no strict 'refs';
211 265
212 Осуществлять поиск по базовым классам. 266 Осуществлять поиск по базовым классам.
213 267
214 =back 268 =back
215 269
216 =head2 C<static_accessor($name[,$value[,$clone]])> 270 =head2 C<static_accessor($name[,$value[,$inherit]])>
217 271
218 Создает статическое свойство с именем C<$name> и начальным значением C<$value>. 272 Создает статическое свойство с именем C<$name> и начальным значением C<$value>.
219 273
220 Параметр C<$clone> контролирует то, как наследуются значения, если требуется каждому классу обеспечить 274 Параметр C<$inherit> контролирует то, как наследуются значения.
221 свое уникальное значение, то при первом обращении оно будет клонировано, по умолчанию клонирование не 275
222 происходит. 276 =over
277
278 =item * C<inherit>
279
280 По умолчанию. Означает, что если для класса не определено значение, оно будет
281 получено от родителя.
282
283 =item * C<clone>
284
285 Если для класса не определено значение, то оно будет клонировано из
286 родительского значения при первом обращении. Полезно, когда родитель задает
287 значение по-умолчанию, которое разделяется между несколькими потомками,
288 которые модифицирю само значение (например значением является ссылка на хеш,
289 а потомки добавляют или меняют значения в этом хеше).
290
291 =item * C<own>
292
293 Каждый класс имеет свое собственное значение не зависящее от того, что было
294 у предка. Начальное значение для этого статического свойства C<undef>.
295
296 =back
297
298 Данный метод является заглушкой, он передает управление
299 C<static_accessor_inherit>, C<static_accessor_clone>, C<static_accessor_own>
300 соответственно. Эти методы можно вызывать явно
301 C<static_accessor_*($name[,$value])>.
302
223 303
224 =begin code 304 =begin code
225 305
226 package Foo; 306 package Foo;
227 use parent qw(IMPL::Class::Meta); 307 use parent qw(IMPL::Class::Meta);
228 308
229 __PACKAGE__->static_accessor( info => { version => 1 } ); 309 __PACKAGE__->static_accessor( info => { version => 1 } );
310 __PACKAGE__->static_accessor( mappings => { toString => \&ToString }, 'clone' );
311 __PACKAGE__->static_accessor( _instance => undef, 'own' );
312
313 sub ToString {
314 "[object Foo]";
315 }
316
317 sub default {
318 my ($self) = @_;
319
320 $self = ref $self || $self;
321 return $self->_instance ? $self->_instance : $self->_instance($self->new());
322 }
230 323
231 package Bar; 324 package Bar;
232 use parent qw(Foo); 325 use parent qw(Foo);
233 326
234 __PACKAGE__->info->{language} = 'English'; # Foo->info->{language} will become 'English' to!!! 327 __PACKAGE__->info({language => 'English', version => 2}); # will define own 'info' but will loose original data.
235 __PACKAGE__->info({language => 'English'}); # will define own 'info' but will loose original data. 328 __PACKAGE__->mappings->{sayHello} = \&SayHello; # will not affect Foo->mappings;
329
330 package main;
331
332 my $foo = Foo->default; # will be a Foo object
333 my $bar = Bar->default; # will be a Bar object
236 334
237 =end code 335 =end code
238 336
239 =cut 337 =cut