Mercurial > pub > Impl
view Lib/IMPL/TypeKeyedCollection.pm @ 379:a471e8b77544
sync
author | cin |
---|---|
date | Thu, 16 Jan 2014 18:10:50 +0400 |
parents | 96a522aeb359 |
children | de1f875e8875 |
line wrap: on
line source
package IMPL::TypeKeyedCollection; use strict; use IMPL::Const qw(:prop); use IMPL::declare { require => { ArgException => '-IMPL::InvalidArgumentException' }, base => [ 'IMPL::Object' => undef ], props => [ _items => PROP_RW | PROP_DIRECT, _cache => PROP_RW | PROP_DIRECT ] }; sub CTOR { my ($this,$items) = @_; $items = {} unless ref($items) eq 'HASH'; $this->{$_items} = $items; } sub Get { my ($this,$type) = @_; die ArgException->new(type => 'Invalid type', $type) if not $type or ref($type); if(my $val = $this->{$_cache}{$type}) { return $val; } else { no strict 'refs'; my @isa = $type; while (@isa) { my $sclass = shift @isa; $val = $this->{$_items}{$sclass}; return($this->{$_cache}{$type} = $val) if defined $val; # zeroes and empty strings are also valid push @isa, @{"${sclass}::ISA"}; } return; } } sub Set { my ($this,$type,$value) = @_; die ArgException->new(type => 'Invalid type', $type) if not $type or ref($type); $this->{$_items}{$type} = $value; delete $this->{$_cache}; return $value; } sub Delete { my ($this,$type) = @_; if(defined delete $this->{$_items}{$type} ) { delete $this->{$_cache}; return 1; } return; } 1; __END__ =pod =head1 NAME C<IMPL::TypeKeyedCollection> - коллекция, ключами которой являются типы. =head1 SYNOPSIS =begin code package Foo; package Bar; our @ISA = qw(Foo); package Baz; our @ISA = qw(Foo); package main; use IMPL::require { TypeKeyedCollection => 'IMPL::TypeKeyedCollection' }; my $col = TypeKeyedCollection->new({ Foo => 'base', Bar => 'BAAAR' }); print $col->Get('Foo'); # 'base' print $col->Get('Bar'); # 'BAAAR' print $col->Get('Baz'); # 'base' =end code =head1 DESCRIPTION Использует иерархию классов для определения наиболее подходяжего значения в коллекции. =cut