Mercurial > pub > Impl
comparison Lib/IMPL/Class/Meta.pm @ 194:4d0e1962161c
Replaced tabs with spaces
IMPL::Web::View - fixed document model, new features (control classes, document constructor parameters)
| author | cin |
|---|---|
| date | Tue, 10 Apr 2012 20:08:29 +0400 |
| parents | d1676be8afcc |
| children | a8db61d0ed33 |
comparison
equal
deleted
inserted
replaced
| 193:8e8401c0aea4 | 194:4d0e1962161c |
|---|---|
| 34 } | 34 } |
| 35 wantarray ? @result : \@result; | 35 wantarray ? @result : \@result; |
| 36 } | 36 } |
| 37 | 37 |
| 38 sub class_data { | 38 sub class_data { |
| 39 my $class = shift; | 39 my $class = shift; |
| 40 $class = ref $class || $class; | 40 $class = ref $class || $class; |
| 41 | 41 |
| 42 if (@_ > 1) { | 42 if (@_ > 1) { |
| 43 my ($name,$value) = @_; | 43 my ($name,$value) = @_; |
| 44 return $class_data{$class}{$name} = $value; | 44 return $class_data{$class}{$name} = $value; |
| 45 } else { | 45 } else { |
| 46 my ($name) = @_; | 46 my ($name) = @_; |
| 47 | 47 |
| 48 if( exists $class_data{$class}{$name} ) { | 48 if( exists $class_data{$class}{$name} ) { |
| 49 $class_data{$class}{$name}; | 49 $class_data{$class}{$name}; |
| 50 } else { | 50 } else { |
| 51 if ( my $value = $class->_find_class_data($name) ) { | 51 if ( my $value = $class->_find_class_data($name) ) { |
| 52 $class_data{$class}{$name} = clone($value); | 52 $class_data{$class}{$name} = clone($value); |
| 53 } else { | 53 } else { |
| 54 undef; | 54 undef; |
| 55 } | 55 } |
| 56 } | 56 } |
| 57 } | 57 } |
| 58 } | 58 } |
| 59 | 59 |
| 60 sub static_accessor { | 60 sub static_accessor { |
| 61 my ($class,$name,$value) = @_; | 61 my ($class,$name,$value) = @_; |
| 62 $class = ref $class || $class; | 62 $class = ref $class || $class; |
| 63 | 63 |
| 64 no strict 'refs'; | 64 no strict 'refs'; |
| 65 | 65 |
| 66 *{"${class}::${name}"} = sub { | 66 *{"${class}::${name}"} = sub { |
| 67 if (@_ > 1) { | 67 if (@_ > 1) { |
| 68 my $self = shift; | 68 my $self = shift; |
| 69 $self = ref $self || $self; | 69 $self = ref $self || $self; |
| 70 | 70 |
| 71 if ($class ne $self) { | 71 if ($class ne $self) { |
| 72 $self->static_accessor( $name => $_[0]); # define own class data | 72 $self->static_accessor( $name => $_[0]); # define own class data |
| 73 } else { | 73 } else { |
| 74 $value = $_[0]; | 74 $value = $_[0]; |
| 75 } | 75 } |
| 76 } else { | 76 } else { |
| 77 $value; | 77 $value; |
| 78 } | 78 } |
| 79 }; | 79 }; |
| 80 $value | 80 $value |
| 81 }; | 81 }; |
| 82 | 82 |
| 83 sub _find_class_data { | 83 sub _find_class_data { |
| 84 my ($class,$name) = @_; | 84 my ($class,$name) = @_; |
| 85 | 85 |
| 86 no strict 'refs'; | 86 no strict 'refs'; |
| 87 | 87 |
| 88 exists $class_data{$_}{$name} and return $class_data{$_}{$name} foreach @{"${class}::ISA"}; | 88 exists $class_data{$_}{$name} and return $class_data{$_}{$name} foreach @{"${class}::ISA"}; |
| 89 | 89 |
| 90 my $val; | 90 my $val; |
| 91 $val = $_->can('_find_class_data') ? $_->_find_class_data($name) : undef and return $val foreach @{"${class}::ISA"}; | 91 $val = $_->can('_find_class_data') ? $_->_find_class_data($name) : undef and return $val foreach @{"${class}::ISA"}; |
| 92 } | 92 } |
| 93 | 93 |
| 94 1; | 94 1; |
| 95 | 95 |
| 96 __END__ | 96 __END__ |
| 111 use IMPL::Class::Property; | 111 use IMPL::Class::Property; |
| 112 | 112 |
| 113 __PACKAGE__->PassThroughArgs; | 113 __PACKAGE__->PassThroughArgs; |
| 114 | 114 |
| 115 BEGIN { | 115 BEGIN { |
| 116 public property name => prop_get | owner_set; | 116 public property name => prop_get | owner_set; |
| 117 } | 117 } |
| 118 | 118 |
| 119 package InfoExMeta; | 119 package InfoExMeta; |
| 120 use parent qw(InfoMeta); | 120 use parent qw(InfoMeta); |
| 121 | 121 |
| 122 __PACKAGE__->PassThroughArgs; | 122 __PACKAGE__->PassThroughArgs; |
| 123 | 123 |
| 124 BEGIN { | 124 BEGIN { |
| 125 public property description => prop_all; | 125 public property description => prop_all; |
| 126 } | 126 } |
| 127 | 127 |
| 128 package Foo; | 128 package Foo; |
| 129 | 129 |
| 130 __PACKAGE__->set_meta(new InfoMeta(name => 'info')); | 130 __PACKAGE__->set_meta(new InfoMeta(name => 'info')); |
| 177 метаданные как не подходящие. Также переменная C<$_> ссылается на текущий объект с метаданными. | 177 метаданные как не подходящие. Также переменная C<$_> ссылается на текущий объект с метаданными. |
| 178 | 178 |
| 179 =begin code | 179 =begin code |
| 180 | 180 |
| 181 my @info = Foo->get_meta( | 181 my @info = Foo->get_meta( |
| 182 'InfoMeta', | 182 'InfoMeta', |
| 183 sub { ref $_ eq 'InfoMeta'}, # exclude subclasses ('InfoExMeta') | 183 sub { ref $_ eq 'InfoMeta'}, # exclude subclasses ('InfoExMeta') |
| 184 1 # deep search | 184 1 # deep search |
| 185 ); | 185 ); |
| 186 | 186 |
| 187 my @info = Foo->get_meta( | 187 my @info = Foo->get_meta( |
| 188 'InfoMeta', | 188 'InfoMeta', |
| 189 sub { | 189 sub { |
| 190 my $item = shift; | 190 my $item = shift; |
| 191 ref $item eq 'InfoMeta' # exclude subclasses ('InfoExMeta') | 191 ref $item eq 'InfoMeta' # exclude subclasses ('InfoExMeta') |
| 192 }, | 192 }, |
| 193 1 # deep search | 193 1 # deep search |
| 194 ); | 194 ); |
| 195 | 195 |
| 196 =end code | 196 =end code |
| 197 | 197 |
| 198 =item C<$deep> | 198 =item C<$deep> |
| 218 use parent qw(IMPL::Class::Meta); | 218 use parent qw(IMPL::Class::Meta); |
| 219 | 219 |
| 220 __PACKAGE__->class_data( info => { version => 1 } ); # will be default for all subclasses | 220 __PACKAGE__->class_data( info => { version => 1 } ); # will be default for all subclasses |
| 221 | 221 |
| 222 sub say_version { | 222 sub say_version { |
| 223 my ($self) = @_; | 223 my ($self) = @_; |
| 224 | 224 |
| 225 print $self->class_data('info')->{version}; | 225 print $self->class_data('info')->{version}; |
| 226 } | 226 } |
| 227 | 227 |
| 228 package Bar; | 228 package Bar; |
| 229 use parent qw(Foo); | 229 use parent qw(Foo); |
| 230 | 230 |
