comparison Lib/IMPL/Class/Property/Direct.pm @ 55:609b59c9f03c

Web application rewrote prop_list implementation to support IMPL::Object::List
author wizard
date Wed, 03 Mar 2010 17:40:18 +0300
parents 15d720913562
children 0f3e369553bd
comparison
equal deleted inserted replaced
54:f4e045e47770 55:609b59c9f03c
2 use strict; 2 use strict;
3 3
4 use base qw(IMPL::Object::Accessor Exporter); 4 use base qw(IMPL::Object::Accessor Exporter);
5 our @EXPORT = qw(_direct); 5 our @EXPORT = qw(_direct);
6 6
7 require IMPL::Object::List;
7 use IMPL::Class::Property; 8 use IMPL::Class::Property;
8 require IMPL::Exception; 9 require IMPL::Exception;
9 10
10 __PACKAGE__->mk_accessors qw(ExportField); 11 __PACKAGE__->mk_accessors qw(ExportField);
11 12
20 21
21 my $accessor_get_no = 'die new IMPL::Exception(\'The property is write only\',$name,$class) unless $get;'; 22 my $accessor_get_no = 'die new IMPL::Exception(\'The property is write only\',$name,$class) unless $get;';
22 my $accessor_set_no = 'die new IMPL::Exception(\'The property is read only\',$name,$class) unless $set;'; 23 my $accessor_set_no = 'die new IMPL::Exception(\'The property is read only\',$name,$class) unless $set;';
23 my $accessor_set = 'return( $this->{$field} = @_ == 1 ? $_[0] : [@_] );'; 24 my $accessor_set = 'return( $this->{$field} = @_ == 1 ? $_[0] : [@_] );';
24 my $accessor_get = 'return( $this->{$field} );'; 25 my $accessor_get = 'return( $this->{$field} );';
25 my $list_accessor_set = 'return( @{ ($this->{$field} = IMPL::Object::List->new( ( (@_ == 1 and ref $_[0] eq \'ARRAY\') ? $_[0] : [@_] ) || [] ) } );'; 26 my $list_accessor_set = 'return(
26 my $list_accessor_get = 'return( @{ $this->{$field} ? $this->{$field} : $this->{$field} = IMPL::Object::List->new() } );'; 27 wantarray ?
28 @{ $this->{$field} = IMPL::Object::List->new(
29 (@_ == 1 and UNIVERSAL::isa($_[0], \'ARRAY\') ) ? $_[0] : [@_]
30 )} :
31 ($this->{$field} = IMPL::Object::List->new(
32 (@_ == 1 and UNIVERSAL::isa($_[0], \'ARRAY\') ) ? $_[0] : [@_]
33 ))
34 );';
35 my $list_accessor_get = 'return(
36 wantarray ?
37 @{ $this->{$field} ?
38 $this->{$field} :
39 ( $this->{$field} = IMPL::Object::List->new() )
40 } :
41 ( $this->{$field} ?
42 $this->{$field} :
43 ( $this->{$field} = IMPL::Object::List->new() )
44 )
45 );';
27 my $custom_accessor_get = 'unshift @_, $this and goto &$get;'; 46 my $custom_accessor_get = 'unshift @_, $this and goto &$get;';
28 my $custom_accessor_set = 'unshift @_, $this and goto &$set;'; 47 my $custom_accessor_set = 'unshift @_, $this and goto &$set;';
29 48
30 my %accessor_cache; 49 my %accessor_cache;
31 sub mk_acessor { 50 sub mk_acessor {
32 my ($virtual,$access,$class,$name,$mutators,$field) = @_; 51 my ($virtual,$access,$class,$name,$mutators,$field,$validator) = @_;
33 52
34 my ($get,$set) = ref $mutators ? ( $mutators->{get}, $mutators->{set}) : ($mutators & prop_get, $mutators & prop_set); 53 my ($get,$set) = ref $mutators ? ( $mutators->{get}, $mutators->{set}) : ($mutators & prop_get, $mutators & prop_set);
35 my $key = join '',$virtual,$access,$get ? 1 : 0,$set ? 1 : 0, (ref $mutators ? 'c' : ($mutators & prop_list() ? 'l' : 's')); 54 my $key = join '',$virtual,$access,$get ? 1 : 0,$set ? 1 : 0, (ref $mutators ? 'c' : ($mutators & prop_list() ? 'l' : 's')), $validator ? 1 : 0 ;
36 my $factory = $accessor_cache{$key}; 55 my $factory = $accessor_cache{$key};
37 if (not $factory) { 56 if (not $factory) {
38 my $code = 57 my $code =
39 <<BEGIN; 58 <<BEGIN;
40 sub { 59 sub {
45 BEGIN 64 BEGIN
46 $code .= <<VCALL if $virtual; 65 $code .= <<VCALL if $virtual;
47 my \$method = \$this->can(\$name); 66 my \$method = \$this->can(\$name);
48 return \$this->\$method(\@_) unless \$method == \$accessor or caller->isa(\$class); 67 return \$this->\$method(\@_) unless \$method == \$accessor or caller->isa(\$class);
49 VCALL 68 VCALL
50 $code .= "$access_private\n" if $access == IMPL::Class::Member::MOD_PRIVATE; 69 $code .= ' 'x8 . "$access_private\n" if $access == IMPL::Class::Member::MOD_PRIVATE;
51 $code .= "$access_protected\n" if $access == IMPL::Class::Member::MOD_PROTECTED; 70 $code .= ' 'x8 . "$access_protected\n" if $access == IMPL::Class::Member::MOD_PROTECTED;
71 $code .= ' 'x8 . '$this->$validator(@_);'."\n" if $validator;
72
52 my ($codeGet,$codeSet); 73 my ($codeGet,$codeSet);
53 if (ref $mutators) { 74 if (ref $mutators) {
54 $codeGet = $get ? $custom_accessor_get : $accessor_get_no; 75 $codeGet = $get ? $custom_accessor_get : $accessor_get_no;
55 $codeSet = $set ? $custom_accessor_set : $accessor_set_no; 76 $codeSet = $set ? $custom_accessor_set : $accessor_set_no;
56 } else { 77 } else {
70 $codeGet 91 $codeGet
71 } 92 }
72 } 93 }
73 } 94 }
74 END 95 END
75 $factory = eval $code or die new IMPL::Exception('Failed to generate the accessor',$@); 96 warn $code;
97 $factory = eval $code;
98 if (not $factory) {
99 my $err = $@;
100 die new IMPL::Exception('Failed to generate the accessor factory',$err);
101 }
76 $accessor_cache{$key} = $factory; 102 $accessor_cache{$key} = $factory;
77 } 103 }
78 return $factory->($class,$name,$set,$get, $field); 104
105 die new IMPL::Exception('Can\'t find the specified validator',$class,$validator) if $validator and ref $validator ne 'CODE' and not $class->can($validator);
106
107 return $factory->($class,$name,$set,$get, $field, $validator);
79 } 108 }
80 109
81 sub Make { 110 sub Make {
82 my ($self,$propInfo) = @_; 111 my ($self,$propInfo) = @_;
83 112
84 my $isExportField = ref $self ? ($self->ExportField || 0) : 0; 113 my $isExportField = ref $self ? ($self->ExportField || 0) : 0;
85 my ($class,$name,$virt,$access,$mutators) = $propInfo->get qw(Class Name Virtual Access Mutators); 114 my ($class,$name,$virt,$access,$mutators,$attr) = $propInfo->get qw(Class Name Virtual Access Mutators Attributes);
86 (my $field = "${class}_$name") =~ s/::/_/g; 115 (my $field = "${class}_$name") =~ s/::/_/g;
87 116
88 my $propGlob = $class.'::'.$name; 117 my $propGlob = $class.'::'.$name;
89 118
90 no strict 'refs'; 119 no strict 'refs';
91 *$propGlob = mk_acessor($virt,$access,$class,$name,$mutators,$field); 120 *$propGlob = mk_acessor($virt,$access,$class,$name,$mutators,$field,$attr->{validator});
92 *$propGlob = \$field if $isExportField; 121 *$propGlob = \$field if $isExportField;
93 122
94 if (ref $mutators) { 123 if (ref $mutators) {
95 $propInfo->canGet( $mutators->{get} ? 1 : 0); 124 $propInfo->canGet( $mutators->{get} ? 1 : 0);
96 $propInfo->canSet( $mutators->{set} ? 1 : 0); 125 $propInfo->canSet( $mutators->{set} ? 1 : 0);