Mercurial > pub > Impl
annotate Lib/IMPL/TypeKeyedCollection.pm @ 403:7171a8e2e2ba
dirty fix for url encoding
| author | sergey |
|---|---|
| date | Tue, 20 May 2014 01:26:45 +0400 |
| parents | 69a1f1508696 |
| children |
| rev | line source |
|---|---|
| 316 | 1 package IMPL::TypeKeyedCollection; |
| 2 use strict; | |
| 3 | |
| 4 use IMPL::Const qw(:prop); | |
| 393 | 5 use IMPL::lang; |
| 316 | 6 use IMPL::declare { |
| 7 require => { | |
| 8 ArgException => '-IMPL::InvalidArgumentException' | |
| 9 }, | |
| 10 base => [ | |
| 11 'IMPL::Object' => undef | |
| 12 ], | |
| 13 props => [ | |
| 14 _items => PROP_RW | PROP_DIRECT, | |
|
390
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
15 _cache => PROP_RW | PROP_DIRECT, |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
16 _reverse => PROP_RW | PROP_DIRECT |
| 316 | 17 ] |
| 18 }; | |
| 19 | |
| 20 sub CTOR { | |
|
390
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
21 my ($this,$items,$reverse) = @_; |
| 316 | 22 |
| 23 $items = {} | |
| 24 unless ref($items) eq 'HASH'; | |
| 25 | |
| 26 $this->{$_items} = $items; | |
|
390
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
27 $this->{$_reverse} = $reverse; |
| 316 | 28 } |
| 29 | |
| 30 sub Get { | |
| 31 my ($this,$type) = @_; | |
| 32 | |
| 317 | 33 die ArgException->new(type => 'Invalid type', $type) |
| 34 if not $type or ref($type); | |
| 316 | 35 |
| 36 if(my $val = $this->{$_cache}{$type}) { | |
| 37 return $val; | |
| 38 } else { | |
|
390
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
39 if ($this->_reverse) { |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
40 my $val = $this->{$_items}{$type}; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
41 |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
42 unless(defined $val) { |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
43 my $matching; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
44 while ( my ($k,$v) = each %{$this->{$_items}}) { |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
45 if (isclass($k,$type) && (not($matching) || isclass($k,$matching)) ) { |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
46 $matching = $k; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
47 $val = $v; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
48 } |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
49 } |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
50 } |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
51 |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
52 return $this->{$_cache}{$type} = $val; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
53 |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
54 } else { |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
55 no strict 'refs'; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
56 |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
57 my @isa = $type; |
| 316 | 58 |
|
390
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
59 while (@isa) { |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
60 my $sclass = shift @isa; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
61 |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
62 $val = $this->{$_items}{$sclass}; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
63 |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
64 return($this->{$_cache}{$type} = $val) |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
65 if defined $val; # zeroes and empty strings are also valid |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
66 |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
67 push @isa, @{"${sclass}::ISA"}; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
68 } |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
69 return; |
|
de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
cin
parents:
317
diff
changeset
|
70 } |
| 316 | 71 } |
| 72 } | |
| 73 | |
| 74 sub Set { | |
| 75 my ($this,$type,$value) = @_; | |
| 76 | |
| 317 | 77 die ArgException->new(type => 'Invalid type', $type) |
| 78 if not $type or ref($type); | |
| 316 | 79 |
| 80 $this->{$_items}{$type} = $value; | |
| 81 | |
| 82 delete $this->{$_cache}; | |
| 83 | |
| 84 return $value; | |
| 85 } | |
| 86 | |
| 87 sub Delete { | |
| 88 my ($this,$type) = @_; | |
| 89 | |
| 90 if(defined delete $this->{$_items}{$type} ) { | |
| 91 delete $this->{$_cache}; | |
| 92 return 1; | |
| 93 } | |
| 94 return; | |
| 95 } | |
| 96 | |
| 97 1; | |
| 98 | |
| 99 __END__ | |
| 100 | |
| 101 =pod | |
| 102 | |
| 103 =head1 NAME | |
| 104 | |
| 105 C<IMPL::TypeKeyedCollection> - коллекция, ключами которой являются типы. | |
| 106 | |
| 107 =head1 SYNOPSIS | |
| 108 | |
| 109 =begin code | |
| 110 | |
| 111 package Foo; | |
| 112 | |
| 113 package Bar; | |
| 114 our @ISA = qw(Foo); | |
| 115 | |
| 116 package Baz; | |
| 117 our @ISA = qw(Foo); | |
| 118 | |
| 119 package main; | |
| 120 use IMPL::require { | |
| 121 TypeKeyedCollection => 'IMPL::TypeKeyedCollection' | |
| 122 }; | |
| 123 | |
| 124 my $col = TypeKeyedCollection->new({ | |
| 125 Foo => 'base', | |
| 126 Bar => 'BAAAR' | |
| 127 }); | |
| 128 | |
| 129 print $col->Get('Foo'); # 'base' | |
| 130 print $col->Get('Bar'); # 'BAAAR' | |
| 131 print $col->Get('Baz'); # 'base' | |
| 132 | |
| 133 =end code | |
| 134 | |
| 135 =head1 DESCRIPTION | |
| 136 | |
| 137 Использует иерархию классов для определения наиболее подходяжего значения в | |
| 138 коллекции. | |
| 139 | |
| 140 =cut |
