Mercurial > pub > Impl
comparison Lib/IMPL/TypeKeyedCollection.pm @ 390:de1f875e8875
added reverse matching lookup to TypeKeyedCollection (find closest descendant)
author | cin |
---|---|
date | Wed, 12 Feb 2014 18:02:03 +0400 |
parents | 96a522aeb359 |
children | 69a1f1508696 |
comparison
equal
deleted
inserted
replaced
389:5aff94ba842f | 390:de1f875e8875 |
---|---|
9 base => [ | 9 base => [ |
10 'IMPL::Object' => undef | 10 'IMPL::Object' => undef |
11 ], | 11 ], |
12 props => [ | 12 props => [ |
13 _items => PROP_RW | PROP_DIRECT, | 13 _items => PROP_RW | PROP_DIRECT, |
14 _cache => PROP_RW | PROP_DIRECT | 14 _cache => PROP_RW | PROP_DIRECT, |
15 _reverse => PROP_RW | PROP_DIRECT | |
15 ] | 16 ] |
16 }; | 17 }; |
17 | 18 |
18 sub CTOR { | 19 sub CTOR { |
19 my ($this,$items) = @_; | 20 my ($this,$items,$reverse) = @_; |
20 | 21 |
21 $items = {} | 22 $items = {} |
22 unless ref($items) eq 'HASH'; | 23 unless ref($items) eq 'HASH'; |
23 | 24 |
24 $this->{$_items} = $items; | 25 $this->{$_items} = $items; |
26 $this->{$_reverse} = $reverse; | |
25 } | 27 } |
26 | 28 |
27 sub Get { | 29 sub Get { |
28 my ($this,$type) = @_; | 30 my ($this,$type) = @_; |
29 | 31 |
31 if not $type or ref($type); | 33 if not $type or ref($type); |
32 | 34 |
33 if(my $val = $this->{$_cache}{$type}) { | 35 if(my $val = $this->{$_cache}{$type}) { |
34 return $val; | 36 return $val; |
35 } else { | 37 } else { |
36 no strict 'refs'; | 38 if ($this->_reverse) { |
37 | 39 my $val = $this->{$_items}{$type}; |
38 my @isa = $type; | 40 |
39 | 41 unless(defined $val) { |
40 while (@isa) { | 42 my $matching; |
41 my $sclass = shift @isa; | 43 while ( my ($k,$v) = each %{$this->{$_items}}) { |
42 | 44 if (isclass($k,$type) && (not($matching) || isclass($k,$matching)) ) { |
43 $val = $this->{$_items}{$sclass}; | 45 $matching = $k; |
46 $val = $v; | |
47 } | |
48 } | |
49 } | |
50 | |
51 return $this->{$_cache}{$type} = $val; | |
52 | |
53 } else { | |
54 no strict 'refs'; | |
55 | |
56 my @isa = $type; | |
44 | 57 |
45 return($this->{$_cache}{$type} = $val) | 58 while (@isa) { |
46 if defined $val; # zeroes and empty strings are also valid | 59 my $sclass = shift @isa; |
47 | 60 |
48 push @isa, @{"${sclass}::ISA"}; | 61 $val = $this->{$_items}{$sclass}; |
49 } | 62 |
50 return; | 63 return($this->{$_cache}{$type} = $val) |
64 if defined $val; # zeroes and empty strings are also valid | |
65 | |
66 push @isa, @{"${sclass}::ISA"}; | |
67 } | |
68 return; | |
69 } | |
51 } | 70 } |
52 } | 71 } |
53 | 72 |
54 sub Set { | 73 sub Set { |
55 my ($this,$type,$value) = @_; | 74 my ($this,$type,$value) = @_; |