Mercurial > pub > Impl
annotate Lib/IMPL/lang.pm @ 278:4ddb27ff4a0b
core refactoring
| author | cin |
|---|---|
| date | Mon, 04 Feb 2013 02:10:37 +0400 |
| parents | 6253872024a4 |
| children | c6d0f889ef87 |
| rev | line source |
|---|---|
| 164 | 1 package IMPL::lang; |
| 2 use strict; | |
| 3 use warnings; | |
| 4 | |
| 165 | 5 use parent qw(Exporter); |
| 164 | 6 use IMPL::_core::version; |
| 173 | 7 use IMPL::clone qw(clone); |
| 274 | 8 use Scalar::Util qw(blessed); |
| 164 | 9 |
| 274 | 10 our @EXPORT = qw(&is &isclass &typeof); |
| 167 | 11 our %EXPORT_TAGS = ( |
| 194 | 12 base => [ |
| 13 qw( | |
| 14 &is | |
| 15 &clone | |
|
271
56364d0c4b4f
+IMPL::SQL::Schema::MySQL: added basic support for MySQL
cin
parents:
241
diff
changeset
|
16 &isclass |
| 274 | 17 &typeof |
| 194 | 18 ) |
| 19 ], | |
| 167 | 20 |
| 194 | 21 declare => [ |
| 22 qw( | |
| 23 &public | |
| 24 &protected | |
| 25 &private | |
| 26 &property | |
| 27 &static | |
| 28 &property | |
| 278 | 29 &_direct |
| 213 | 30 &ACCESS_PUBLIC |
| 31 &ACCESS_PROTECTED | |
| 32 &ACCESS_PRIVATE | |
| 33 &PROP_GET | |
| 34 &PROP_SET | |
| 35 &PROP_OWNERSET | |
| 36 &PROP_LIST | |
| 37 &PROP_ALL | |
| 230 | 38 &PROP_RO |
| 39 &PROP_RW | |
| 278 | 40 &PROP_DIRECT |
| 194 | 41 ) |
| 42 ], | |
| 43 compare => [ | |
| 44 qw( | |
| 45 &equals | |
| 46 &equals_s | |
| 47 &hashCompare | |
| 48 ) | |
| 49 ], | |
| 50 hash => [ | |
| 51 qw( | |
| 52 &hashApply | |
| 53 &hashMerge | |
| 54 &hashDiff | |
| 55 &hashCompare | |
| 56 &hashParse | |
| 57 &hashSave | |
| 58 ) | |
| 59 ] | |
| 167 | 60 ); |
| 61 | |
| 62 our @EXPORT_OK = keys %{ { map (($_,1) , map (@{$_}, values %EXPORT_TAGS) ) } }; | |
| 63 | |
| 230 | 64 use IMPL::Const qw(:all); |
| 164 | 65 |
| 66 sub is($$) { | |
|
271
56364d0c4b4f
+IMPL::SQL::Schema::MySQL: added basic support for MySQL
cin
parents:
241
diff
changeset
|
67 eval {ref $_[0] and $_[0]->isa( $_[1] ) }; |
|
56364d0c4b4f
+IMPL::SQL::Schema::MySQL: added basic support for MySQL
cin
parents:
241
diff
changeset
|
68 } |
|
56364d0c4b4f
+IMPL::SQL::Schema::MySQL: added basic support for MySQL
cin
parents:
241
diff
changeset
|
69 |
|
56364d0c4b4f
+IMPL::SQL::Schema::MySQL: added basic support for MySQL
cin
parents:
241
diff
changeset
|
70 sub isclass { |
|
56364d0c4b4f
+IMPL::SQL::Schema::MySQL: added basic support for MySQL
cin
parents:
241
diff
changeset
|
71 eval {not ref $_[0] and $_[0]->isa( $_[1] ) }; |
| 167 | 72 } |
| 73 | |
| 274 | 74 sub typeof(*) { |
| 75 eval { $_[0]->typeof } || blessed($_[0]); | |
| 76 } | |
| 77 | |
| 167 | 78 sub public($) { |
| 278 | 79 my $info = shift; |
| 80 $info->{access} = ACCESS_PUBLIC; | |
| 81 my $implementor = delete $info->{implementor}; | |
| 82 $implementor->Implement($info); | |
| 167 | 83 } |
| 84 | |
| 85 sub private($) { | |
| 278 | 86 my $info = shift; |
| 87 $info->{access} = ACCESS_PRIVATE; | |
| 88 my $implementor = delete $info->{implementor}; | |
| 89 $implementor->Implement($info); | |
| 167 | 90 } |
| 91 | |
| 92 sub protected($) { | |
| 278 | 93 my $info = shift; |
| 94 $info->{access} = ACCESS_PROTECTED; | |
| 95 my $implementor = delete $info->{implementor}; | |
| 96 $implementor->Implement($info); | |
| 97 } | |
| 98 | |
| 99 sub _direct ($) { | |
| 100 my $info = shift; | |
| 101 $info->{direct} = 1; | |
| 102 return $info; | |
| 164 | 103 } |
| 104 | |
| 278 | 105 sub property($$) { |
| 106 my ($propName,$attributes) = @_; | |
| 107 | |
| 108 $attributes = { | |
| 109 get => $attributes & PROP_GET, | |
| 110 set => $attributes & PROP_SET, | |
| 111 isList => $attributes & PROP_LIST | |
| 112 } unless ref $attributes; | |
| 113 | |
| 114 my $class = caller; | |
| 115 | |
| 116 return hashMerge ( | |
| 117 $attributes, | |
| 194 | 118 { |
| 278 | 119 implementor => $class->ClassPropertyImplementor, |
| 120 name => $propName, | |
| 121 class => scalar(caller), | |
| 194 | 122 } |
| 123 ); | |
| 167 | 124 } |
| 125 | |
| 126 sub static($$) { | |
| 194 | 127 my ( $name, $value ) = @_; |
| 128 my $class = caller; | |
| 129 $class->static_accessor( $name, $value ); | |
| 167 | 130 } |
| 131 | |
| 132 sub equals { | |
| 194 | 133 if (defined $_[0]) { |
| 134 return 0 if (not defined $_[1]); | |
| 135 | |
| 136 return $_[0] == $_[1]; | |
| 137 } else { | |
| 138 return 0 if defined $_[1]; | |
| 139 | |
| 140 return 1; | |
| 141 } | |
| 167 | 142 } |
| 143 | |
| 144 sub equals_s { | |
| 194 | 145 if (defined $_[0]) { |
| 146 return 0 if (not defined $_[1]); | |
| 147 | |
| 148 return $_[0] eq $_[1]; | |
| 149 } else { | |
| 150 return 0 if defined $_[1]; | |
| 151 | |
| 152 return 1; | |
| 153 } | |
| 167 | 154 } |
| 155 | |
| 168 | 156 sub hashDiff { |
| 194 | 157 my ($src,$dst) = @_; |
| 158 | |
| 159 $dst = $dst ? { %$dst } : {} ; | |
| 160 $src ||= {}; | |
| 161 | |
| 162 my %result; | |
| 163 | |
| 164 foreach my $key ( keys %$src ) { | |
| 165 if (exists $dst->{$key}) { | |
| 166 $result{"+$key"} = $dst->{$key} unless equals_s($dst->{$key}, $src->{$key}); | |
| 167 delete $dst->{$key}; | |
| 168 } else { | |
| 169 $result{"-$key"} = 1; | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 $result{"+$_"} = $dst->{$_} foreach keys %$dst; | |
| 174 | |
| 175 return \%result; | |
| 168 | 176 } |
| 177 | |
| 178 sub hashMerge { | |
| 210 | 179 return hashApply( { %{$_[0] || {}} }, $_[1] ); |
| 168 | 180 } |
| 181 | |
| 182 sub hashApply { | |
| 194 | 183 my ($target,$diff) = @_; |
| 184 | |
|
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
230
diff
changeset
|
185 return $target unless ref $diff eq 'HASH'; |
|
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
230
diff
changeset
|
186 |
| 194 | 187 while ( my ($key,$value) = each %$diff) { |
| 188 $key =~ /^(\+|-)?(.*)$/; | |
| 189 my $op = $1 || '+'; | |
| 190 $key = $2; | |
| 191 | |
| 192 if ($op eq '-') { | |
| 193 delete $target->{$key}; | |
| 194 } else { | |
| 195 $target->{$key} = $value; | |
| 196 } | |
| 197 } | |
| 198 | |
| 199 return $target; | |
| 168 | 200 } |
| 201 | |
| 202 sub hashCompare { | |
| 194 | 203 my ($l,$r,$cmp) = @_; |
| 204 | |
| 205 $cmp ||= \&equals_s; | |
| 206 | |
| 207 return 0 unless scalar keys %$l == scalar keys %$r; | |
| 208 &$cmp($l->{$_},$r->{$_}) || return 0 foreach keys %$l; | |
| 209 | |
| 210 return 1; | |
| 168 | 211 } |
| 212 | |
| 174 | 213 sub hashParse { |
| 194 | 214 my ($s,$p,$d) = @_; |
| 215 | |
| 216 $p = $p ? qr/$p/ : qr/\n+/; | |
| 217 $d = $d ? qr/$d/ : qr/\s*=\s*/; | |
| 218 | |
| 219 return { | |
| 220 map split($d,$_,2), split($p,$s) | |
| 221 }; | |
| 174 | 222 } |
| 223 | |
| 224 sub hashSave { | |
| 194 | 225 my ($hash,$p,$d) = @_; |
| 226 | |
| 227 return "" unless ref $hash eq 'HASH'; | |
| 228 | |
| 229 $p ||= "\n"; | |
| 230 $d ||= " = "; | |
| 231 | |
| 232 return | |
| 233 join( | |
| 234 $p, | |
| 235 map( | |
| 236 join( | |
| 237 $d, | |
| 238 $_, | |
| 239 $hash->{$_} | |
| 240 ), | |
| 241 keys %$hash | |
| 242 ) | |
| 243 ); | |
| 174 | 244 } |
| 245 | |
| 167 | 246 1; |
