Mercurial > pub > Impl
diff lib/IMPL/Code/BasePropertyImplementor.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children | ee36115f6a34 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/IMPL/Code/BasePropertyImplementor.pm Fri Sep 04 19:40:23 2015 +0300 @@ -0,0 +1,149 @@ +package IMPL::Code::BasePropertyImplementor; +use strict; + +use IMPL::Const qw(:prop :access); +use Scalar::Util qw(looks_like_number); + +use constant { + CodeNoGetAccessor => 'die new IMPL::Exception(\'The property is write only\',$name,$class) unless $get;', + CodeNoSetAccessor => 'die new IMPL::Exception(\'The property is read only\',$name,$class) unless $set;', + CodeCustomGetAccessor => '$this->$get(@_);', + CodeCustomSetAccessor => '$this->$set(@_);', + CodeValidator => '$this->$validator(@_);', + CodeOwnerCheck => "die new IMPL::Exception('Set accessor is restricted to the owner',\$name,\$class,scalar caller) unless caller eq \$class;" +}; + +sub CodeSetAccessor { + die new IMPL::Exception("Standard accessors not supported",'Set'); +} + +sub CodeGetAccessor { + die new IMPL::Exception("Standard accessors not supported",'Get'); +} + +sub CodeGetListAccessor { + die new IMPL::Exception("Standard accessors not supported",'GetList'); +} + +sub CodeSetListAccessor { + die new IMPL::Exception("Standard accessors not supported",'SetList'); +} + +sub factoryParams { qw($class $name $set $get $validator) }; + +our %ACCESS_CODE = ( + ACCESS_PUBLIC , "", + ACCESS_PROTECTED, "die new IMPL::Exception('Can\\'t access the protected member',\$name,\$class,scalar caller) unless UNIVERSAL::isa(scalar caller,\$class);", + ACCESS_PRIVATE, "die new IMPL::Exception('Can\\'t access the private member',\$name,\$class,scalar caller) unless caller eq \$class;" +); + +sub NormalizeSpecification { + my ($this,$spec) = @_; + + return $spec if ref($spec); + + if (looks_like_number($spec)) { + return { + get => $spec & PROP_GET, + set => $spec & PROP_SET, + isList => $spec & PROP_LIST, + ownerSet => (($spec & PROP_OWNERSET) == PROP_OWNERSET), + direct => $spec & PROP_DIRECT + }; + } else { + return {}; + } +} + +sub CreateFactoryId { + my ($self, $spec) = @_; + + join( '', + map( + ($_ + ? ( _isCustom($_) + ? 'x' + : 's') + : '_'), + @$spec{qw(get set)} + ), + $spec->{access} || ACCESS_PUBLIC, + $spec->{validator} ? 'v' : '_', + $spec->{isList} ? 'l' : '_', + $spec->{ownerSet} ? 'o' : '_' + ); +} + +sub _isCustom { + ref($_[0]) eq 'CODE' || not(ref($_[0]) || looks_like_number($_[0])); +} + +sub CreateFactory { + my ($self,$spec) = @_; + + return $self->CreateFactoryImpl( + ($spec->{get} + ? ( _isCustom($spec->{get}) + ? $self->CodeCustomGetAccessor + : ($spec->{isList} + ? $self->CodeGetListAccessor + : $self->CodeGetAccessor + ) + ) + : $self->CodeNoGetAccessor + ), + ($spec->{set} + ? ( _isCustom($spec->{set}) + ? $self->CodeCustomSetAccessor + : ($spec->{isList} + ? $self->CodeSetListAccessor + : $self->CodeSetAccessor + ) + ) + : $self->CodeNoSetAccessor + ), + $ACCESS_CODE{$spec->{access} || ACCESS_PUBLIC} || '', + $spec->{validator} ? $self->CodeValidator : '', + $spec->{ownerSet} ? $self->CodeOwnerCheck : '' + ); +} + +sub CreateFactoryImpl { + my ($self,$codeGet,$codeSet,$codeAccessCheck,$codeValidator,$codeOwnerCheck) = @_; + + my $strParams = join(',',$self->factoryParams); + + my $factory = <<FACTORY; + +sub { + my ($strParams) = \@_; + return sub { + my \$this = shift; + $codeAccessCheck + if (\@_) { + $codeOwnerCheck + $codeValidator + $codeSet + } else { + $codeGet + } + } +} +FACTORY + + return ( eval $factory or die new IMPL::Exception("Syntax error due compiling the factory","$@") ); +} + + +1; + +__END__ + +=pod + +=head1 NAME + +C<IMPL::Code::BasePropertyImplementor> набор впомогательныйх статических методов +для генерации свойств. + +=cut \ No newline at end of file