| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Hash::AutoHash; |
|
2
|
|
|
|
|
|
|
our $VERSION='1.17_01'; |
|
3
|
|
|
|
|
|
|
$VERSION=eval $VERSION; # I think this is the accepted idiom.. |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
################################################################################# |
|
6
|
|
|
|
|
|
|
# |
|
7
|
|
|
|
|
|
|
# Author: Nat Goodman |
|
8
|
|
|
|
|
|
|
# Created: 09-02-24 |
|
9
|
|
|
|
|
|
|
# $Id: |
|
10
|
|
|
|
|
|
|
# |
|
11
|
|
|
|
|
|
|
# Wrapper that provides accessor and mutator methods for hashes (real or tied) |
|
12
|
|
|
|
|
|
|
# Hash can be externally supplied or this object itself |
|
13
|
|
|
|
|
|
|
# Tying of hash can be done by application or by this class |
|
14
|
|
|
|
|
|
|
# Can also wrap object tied to hash |
|
15
|
|
|
|
|
|
|
# (actually, any object with suitable FETCH and STORE methods) |
|
16
|
|
|
|
|
|
|
# |
|
17
|
|
|
|
|
|
|
################################################################################# |
|
18
|
|
|
|
|
|
|
|
|
19
|
30
|
|
|
30
|
|
1260309
|
use strict; |
|
|
30
|
|
|
|
|
52
|
|
|
|
30
|
|
|
|
|
897
|
|
|
20
|
30
|
|
|
30
|
|
128
|
use Carp; |
|
|
30
|
|
|
|
|
37
|
|
|
|
30
|
|
|
|
|
2050
|
|
|
21
|
30
|
|
|
30
|
|
142
|
use vars qw($AUTOLOAD); |
|
|
30
|
|
|
|
|
46
|
|
|
|
30
|
|
|
|
|
13626
|
|
|
22
|
|
|
|
|
|
|
our @CONSTRUCTORS_EXPORT_OK= |
|
23
|
|
|
|
|
|
|
qw(autohash_new autohash_hash autohash_tie autohash_wrap autohash_wrapobj autohash_wraptie); |
|
24
|
|
|
|
|
|
|
our @SUBCLASS_EXPORT_OK= |
|
25
|
|
|
|
|
|
|
qw(autohash_clear autohash_delete autohash_each autohash_exists autohash_keys autohash_values |
|
26
|
|
|
|
|
|
|
autohash_get autohash_set autohash_count autohash_empty autohash_notempty |
|
27
|
|
|
|
|
|
|
autohash_alias autohash_tied |
|
28
|
|
|
|
|
|
|
autohash_destroy autohash_untie); |
|
29
|
|
|
|
|
|
|
our @EXPORT_OK=(@CONSTRUCTORS_EXPORT_OK,@SUBCLASS_EXPORT_OK); |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# following are used by subclasses |
|
32
|
|
|
|
|
|
|
our @RENAME_EXPORT_OK=(); |
|
33
|
|
|
|
|
|
|
our %RENAME_EXPORT_OK=(); |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# our @EXPORT_OK=qw(autohash_new autohash_tie |
|
36
|
|
|
|
|
|
|
# autohash_wraphash autohash_wraptie autohash_wrapobject |
|
37
|
|
|
|
|
|
|
# autohash2hash autohash2object |
|
38
|
|
|
|
|
|
|
# autohash_clear autohash_delete autohash_exists autohash_keys autohash_values |
|
39
|
|
|
|
|
|
|
# autohash_count autohash_empty autohash_notempty |
|
40
|
|
|
|
|
|
|
# autohash_destroy autohash_untie |
|
41
|
|
|
|
|
|
|
# autohash_get autohash_set); |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub import { |
|
44
|
142
|
|
|
142
|
|
103207
|
my $class_or_self=shift; |
|
45
|
142
|
100
|
|
|
|
407
|
if (ref $class_or_self) { |
|
46
|
|
|
|
|
|
|
# called as object method. access hash slot via AUTOLOAD |
|
47
|
11
|
|
|
|
|
67
|
$AUTOLOAD='import'; |
|
48
|
11
|
|
|
|
|
25
|
return $class_or_self->AUTOLOAD(@_); |
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
# called as class method. do regular 'import' |
|
51
|
131
|
|
|
|
|
233
|
my $caller=caller; |
|
52
|
131
|
|
|
|
|
288
|
my $helper_class=$class_or_self.'::helper'; |
|
53
|
131
|
|
|
|
|
484
|
$helper_class->_import($class_or_self,$caller,@_); |
|
54
|
|
|
|
|
|
|
} |
|
55
|
|
|
|
|
|
|
sub new { |
|
56
|
79
|
|
|
79
|
1
|
90851
|
my $class_or_self=shift; |
|
57
|
79
|
100
|
|
|
|
227
|
if (ref $class_or_self) { |
|
58
|
|
|
|
|
|
|
# called as object method. access hash slot via AUTOLOAD |
|
59
|
12
|
|
|
|
|
16
|
$AUTOLOAD='new'; |
|
60
|
12
|
|
|
|
|
25
|
return $class_or_self->AUTOLOAD(@_); |
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
# called as class method. do regular 'new' via helper class |
|
63
|
67
|
|
|
|
|
144
|
my $helper_class=$class_or_self.'::helper'; |
|
64
|
67
|
|
|
|
|
280
|
$helper_class->_new($class_or_self,@_); |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
# NG 12-09-02: no longer possible to use method notation for keys with same names as methods |
|
67
|
|
|
|
|
|
|
# inherited from UNIVERSAL. 'Cuz as of Perl 5.9.3, calling UNIVERSAL methods as |
|
68
|
|
|
|
|
|
|
# functions is deprecated and developers encouraged to use method form instead. |
|
69
|
|
|
|
|
|
|
# sub can { |
|
70
|
|
|
|
|
|
|
# my $class_or_self=shift; |
|
71
|
|
|
|
|
|
|
# if (ref $class_or_self) { |
|
72
|
|
|
|
|
|
|
# # called as object method. access hash slot via AUTOLOAD |
|
73
|
|
|
|
|
|
|
# $AUTOLOAD='can'; |
|
74
|
|
|
|
|
|
|
# return $class_or_self->AUTOLOAD(@_); |
|
75
|
|
|
|
|
|
|
# } |
|
76
|
|
|
|
|
|
|
# # called as class method. do regular 'can' via base class |
|
77
|
|
|
|
|
|
|
# return $class_or_self->SUPER::can(@_); |
|
78
|
|
|
|
|
|
|
# } |
|
79
|
|
|
|
|
|
|
# sub isa { |
|
80
|
|
|
|
|
|
|
# my $class_or_self=shift; |
|
81
|
|
|
|
|
|
|
# if (ref $class_or_self) { |
|
82
|
|
|
|
|
|
|
# # called as object method. access hash slot via AUTOLOAD |
|
83
|
|
|
|
|
|
|
# $AUTOLOAD='isa'; |
|
84
|
|
|
|
|
|
|
# return $class_or_self->AUTOLOAD(@_); |
|
85
|
|
|
|
|
|
|
# } |
|
86
|
|
|
|
|
|
|
# # called as function or class method. do regular 'isa' via base class |
|
87
|
|
|
|
|
|
|
# return $class_or_self->SUPER::isa(@_); |
|
88
|
|
|
|
|
|
|
# } |
|
89
|
|
|
|
|
|
|
# sub DOES { # in perl 5.10, UNIVERSAL provides this |
|
90
|
|
|
|
|
|
|
# my $class_or_self=shift; |
|
91
|
|
|
|
|
|
|
# if (ref $class_or_self) { |
|
92
|
|
|
|
|
|
|
# # called as object method. access hash slot via AUTOLOAD |
|
93
|
|
|
|
|
|
|
# $AUTOLOAD='DOES'; |
|
94
|
|
|
|
|
|
|
# return $class_or_self->AUTOLOAD(@_); |
|
95
|
|
|
|
|
|
|
# } |
|
96
|
|
|
|
|
|
|
# # called as function or class method. do regular 'DOES' via base class |
|
97
|
|
|
|
|
|
|
# # illegal and will die in perls < 5.10 |
|
98
|
|
|
|
|
|
|
# return $class_or_self->SUPER::DOES(@_); |
|
99
|
|
|
|
|
|
|
# } |
|
100
|
|
|
|
|
|
|
# sub VERSION { |
|
101
|
|
|
|
|
|
|
# my $class_or_self=shift; |
|
102
|
|
|
|
|
|
|
# if (ref $class_or_self) { |
|
103
|
|
|
|
|
|
|
# # called as object method. access hash slot via AUTOLOAD |
|
104
|
|
|
|
|
|
|
# $AUTOLOAD='VERSION'; |
|
105
|
|
|
|
|
|
|
# return $class_or_self->AUTOLOAD(@_); |
|
106
|
|
|
|
|
|
|
# } |
|
107
|
|
|
|
|
|
|
# # called as function or class method. do regular 'VERSION' via base class |
|
108
|
|
|
|
|
|
|
# return $class_or_self->SUPER::VERSION(@_); |
|
109
|
|
|
|
|
|
|
# } |
|
110
|
|
|
|
|
|
|
sub DESTROY { |
|
111
|
|
|
|
|
|
|
# CAUTION: do NOT shift - need $_[0] intact |
|
112
|
772
|
50
|
|
772
|
|
1843525
|
if (ref($_[0])) { |
|
113
|
|
|
|
|
|
|
# called as object method. inish up in helper class where namespace more complete |
|
114
|
772
|
|
|
|
|
1894
|
my $helper_class=ref($_[0]).'::helper'; |
|
115
|
772
|
|
|
|
|
1084
|
my $helper_function=__PACKAGE__.'::helper::_destroy'; |
|
116
|
772
|
|
|
|
|
3387
|
return $helper_class->$helper_function(@_); |
|
117
|
|
|
|
|
|
|
} |
|
118
|
|
|
|
|
|
|
# called as class method. pass to base class. not sure this ever happens... |
|
119
|
0
|
|
|
|
|
0
|
my $class_or_self=shift; |
|
120
|
0
|
|
|
|
|
0
|
return $class_or_self->SUPER::DESTROY(@_); |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
# my $self=$_[0]; # CAUTION: do NOT shift - need $_[0] intact |
|
124
|
|
|
|
|
|
|
# return unless ref $self; # shouldn't happen, but... |
|
125
|
|
|
|
|
|
|
# if (@_==1) { # called as destructor or accessor |
|
126
|
|
|
|
|
|
|
# # perlobj says that $_[0] is read-only when DESTROY called as destructor |
|
127
|
|
|
|
|
|
|
# local $@=undef; |
|
128
|
|
|
|
|
|
|
# eval { $_[0]=undef }; |
|
129
|
|
|
|
|
|
|
# return if $@; # eval failed, so it's destructor. |
|
130
|
|
|
|
|
|
|
# $_[0]=$self; # not destructor. restore $_[0] |
|
131
|
|
|
|
|
|
|
# } |
|
132
|
|
|
|
|
|
|
# # not destructor. access hash slot via AUTOLOAD |
|
133
|
|
|
|
|
|
|
# shift; # now shift $self out of @_ |
|
134
|
|
|
|
|
|
|
# $AUTOLOAD='DESTROY'; |
|
135
|
|
|
|
|
|
|
# $self->AUTOLOAD(@_) |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub AUTOLOAD { |
|
138
|
1785
|
|
|
1785
|
|
1646976
|
my $self=shift; |
|
139
|
1785
|
|
|
|
|
7773
|
$AUTOLOAD=~s/^.*:://; # strip class qualification |
|
140
|
|
|
|
|
|
|
# return if $AUTOLOAD eq 'DESTROY'; # the books say you should do this |
|
141
|
1785
|
|
|
|
|
2212
|
my $key=$AUTOLOAD; |
|
142
|
1785
|
100
|
|
|
|
3498
|
defined $key or $key='AUTOLOAD'; |
|
143
|
1785
|
|
|
|
|
1577
|
$AUTOLOAD=undef; # reset for next time |
|
144
|
|
|
|
|
|
|
# finish up in helper class where namespace more complete |
|
145
|
1785
|
|
|
|
|
1783
|
my $helper_function=__PACKAGE__.'::helper::_autoload'; |
|
146
|
1785
|
|
|
|
|
4366
|
$self->$helper_function($key,@_); |
|
147
|
|
|
|
|
|
|
} |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
################################################################################# |
|
150
|
|
|
|
|
|
|
# helper package exists to avoid polluting Hash::AutoHash namespace with |
|
151
|
|
|
|
|
|
|
# subs that would mask accessor/mutator AUTOLOADs |
|
152
|
|
|
|
|
|
|
# functions herein (except _new, _autoload) are exportable by Hash::AutoHash |
|
153
|
|
|
|
|
|
|
################################################################################# |
|
154
|
|
|
|
|
|
|
package Hash::AutoHash::helper; |
|
155
|
|
|
|
|
|
|
our $VERSION=$Hash::AutoHash::VERSION; |
|
156
|
30
|
|
|
30
|
|
174
|
use strict; |
|
|
30
|
|
|
|
|
62
|
|
|
|
30
|
|
|
|
|
793
|
|
|
157
|
30
|
|
|
30
|
|
130
|
use Carp; |
|
|
30
|
|
|
|
|
44
|
|
|
|
30
|
|
|
|
|
1698
|
|
|
158
|
30
|
|
|
30
|
|
147
|
use Scalar::Util qw(blessed readonly reftype); |
|
|
30
|
|
|
|
|
43
|
|
|
|
30
|
|
|
|
|
1812
|
|
|
159
|
30
|
|
|
30
|
|
1695
|
use List::MoreUtils qw(uniq); |
|
|
30
|
|
|
|
|
32268
|
|
|
|
30
|
|
|
|
|
230
|
|
|
160
|
30
|
|
|
30
|
|
26877
|
use Tie::ToObject; |
|
|
30
|
|
|
|
|
9496
|
|
|
|
30
|
|
|
|
|
1006
|
|
|
161
|
30
|
|
|
30
|
|
154
|
use vars qw(%SELF2HASH %SELF2OBJECT %SELF2EACH %CLASS2ANCESTORS %EXPORT_OK); |
|
|
30
|
|
|
|
|
56
|
|
|
|
30
|
|
|
|
|
3034
|
|
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub _import { |
|
164
|
131
|
|
|
131
|
|
288
|
my($helper_class,$class,$caller,@want)=@_; |
|
165
|
131
|
|
|
|
|
303
|
$helper_class->EXPORT_OK; # initializes %EXPORT_OK if necessary |
|
166
|
30
|
|
|
30
|
|
369
|
no strict 'refs'; |
|
|
30
|
|
|
|
|
42
|
|
|
|
30
|
|
|
|
|
3300
|
|
|
167
|
131
|
|
|
|
|
119
|
my %caller2export=%{$class.'::EXPORT_OK'}; |
|
|
131
|
|
|
|
|
1390
|
|
|
168
|
|
|
|
|
|
|
# my @export_ok=keys %caller2export; |
|
169
|
131
|
|
|
|
|
60322
|
for my $want (@want) { |
|
170
|
231
|
100
|
|
|
|
1949
|
confess("\"$want\" not exported by $class module") unless exists $caller2export{$want}; |
|
171
|
224
|
100
|
|
|
|
647
|
confess("\"$want\" not defined by $class module") unless defined $caller2export{$want}; |
|
172
|
222
|
|
|
|
|
293
|
my $caller_sym=$caller.'::'.$want; |
|
173
|
222
|
|
|
|
|
211
|
my $export_sym=$caller2export{$want}; |
|
174
|
30
|
|
|
30
|
|
136
|
no strict 'refs'; |
|
|
30
|
|
|
|
|
33
|
|
|
|
30
|
|
|
|
|
9715
|
|
|
175
|
222
|
|
|
|
|
174
|
*{$caller_sym}=\&{$export_sym}; |
|
|
222
|
|
|
|
|
44824
|
|
|
|
222
|
|
|
|
|
450
|
|
|
176
|
|
|
|
|
|
|
} |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
# front-end to autohash_new constructor function, which in turn is front-end |
|
180
|
|
|
|
|
|
|
# to other constructor functions. |
|
181
|
|
|
|
|
|
|
sub _new { |
|
182
|
57
|
|
|
57
|
|
131
|
my($helper_class,$class)=splice @_,0,2; |
|
183
|
57
|
|
|
|
|
148
|
my $self=autohash_new(@_); |
|
184
|
57
|
|
|
|
|
208
|
bless $self,$class; # re-bless in case called via subclass |
|
185
|
|
|
|
|
|
|
} |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub _destroy { |
|
188
|
772
|
|
|
772
|
|
1061
|
my $helper_class=shift; |
|
189
|
|
|
|
|
|
|
# $_[0] is now original object. |
|
190
|
|
|
|
|
|
|
# CAUTION: do NOT shift further - need $_[0] intact |
|
191
|
|
|
|
|
|
|
# perlobj says that $_[0] is read-only when DESTROY called as destructor |
|
192
|
772
|
100
|
100
|
|
|
8341
|
return if @_==1 && readonly($_[0]); # destructor. nothing to do. |
|
193
|
|
|
|
|
|
|
# not destructor. access hash slot via AUTOLOAD |
|
194
|
11
|
|
|
|
|
11
|
my $self=shift; |
|
195
|
11
|
|
|
|
|
13
|
my $helper_function=__PACKAGE__.'::_autoload'; |
|
196
|
11
|
|
|
|
|
24
|
$self->$helper_function('DESTROY',@_) |
|
197
|
|
|
|
|
|
|
} |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub _autoload { |
|
200
|
1796
|
|
|
1796
|
|
2925
|
my($self,$key)=splice(@_,0,2); |
|
201
|
1796
|
100
|
|
|
|
3270
|
if (my $object=tied %$self) { # tied hash, so invoke FETCH/STORE methods |
|
202
|
1184
|
100
|
|
|
|
3640
|
return @_==0? $object->FETCH($key): $object->STORE($key,@_); |
|
203
|
|
|
|
|
|
|
} else { # regular hash |
|
204
|
612
|
100
|
|
|
|
2485
|
return @_==0? ($self->{$key}): ($self->{$key}=$_[0]); |
|
205
|
|
|
|
|
|
|
} |
|
206
|
|
|
|
|
|
|
} |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# use vars qw(%CLASS2ANCESTORS); |
|
209
|
|
|
|
|
|
|
sub _ancestors { |
|
210
|
42
|
|
|
42
|
|
71
|
my($class,$visited)=@_; |
|
211
|
42
|
|
|
|
|
69
|
my $ancestors=$CLASS2ANCESTORS{$class}; |
|
212
|
42
|
100
|
|
|
|
128
|
defined $visited or $visited={}; |
|
213
|
42
|
50
|
66
|
|
|
203
|
unless (defined($ancestors) || $visited->{$class}) { |
|
214
|
|
|
|
|
|
|
# first call, so compute it |
|
215
|
36
|
|
|
|
|
80
|
$ancestors=[$class]; # include self |
|
216
|
36
|
|
|
|
|
73
|
$visited->{$class}++; |
|
217
|
36
|
|
|
|
|
1037
|
my @isa; |
|
218
|
30
|
|
|
30
|
|
166
|
{no strict "refs"; @isa = @{ $class . '::ISA' };} |
|
|
30
|
|
|
|
|
29
|
|
|
|
30
|
|
|
|
|
5651
|
|
|
|
36
|
|
|
|
|
40
|
|
|
|
36
|
|
|
|
|
45
|
|
|
|
36
|
|
|
|
|
504
|
|
|
219
|
36
|
|
|
|
|
85
|
for my $super (@isa) { |
|
220
|
6
|
|
|
|
|
22
|
push(@$ancestors,_ancestors($super,$visited)); |
|
221
|
|
|
|
|
|
|
} |
|
222
|
36
|
|
|
|
|
235
|
@$ancestors=uniq(@$ancestors); |
|
223
|
36
|
|
|
|
|
119
|
$CLASS2ANCESTORS{$class}=$ancestors |
|
224
|
|
|
|
|
|
|
} |
|
225
|
42
|
100
|
|
|
|
166
|
wantarray? @$ancestors: $ancestors; |
|
226
|
|
|
|
|
|
|
} |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub EXPORT_OK { |
|
229
|
149
|
|
|
149
|
|
2662
|
my $helper_class=shift; |
|
230
|
149
|
|
|
|
|
731
|
my($class)=$helper_class=~/^(.*)::helper$/; |
|
231
|
|
|
|
|
|
|
# for Hash::AutoHash::helper, @EXPORT_OK is given and function computes %EXPORT_OK |
|
232
|
149
|
100
|
|
|
|
398
|
if ($helper_class eq __PACKAGE__) { # NOTE: change this if you copy-and-paste into subclass |
|
233
|
30
|
|
|
30
|
|
160
|
no strict 'refs'; |
|
|
30
|
|
|
|
|
33
|
|
|
|
30
|
|
|
|
|
3451
|
|
|
234
|
113
|
|
|
|
|
104
|
my $export_ok_list=\@{$class.'::EXPORT_OK'}; |
|
|
113
|
|
|
|
|
337
|
|
|
235
|
113
|
|
|
|
|
123
|
my $export_ok_hash=\%{$class.'::EXPORT_OK'}; |
|
|
113
|
|
|
|
|
231
|
|
|
236
|
113
|
100
|
|
|
|
289
|
unless(%$export_ok_hash) { |
|
237
|
30
|
|
|
|
|
97
|
my $ancestors=$helper_class->_ancestors; |
|
238
|
30
|
|
|
|
|
56
|
for my $func (@$export_ok_list) { |
|
239
|
630
|
|
|
|
|
778
|
$export_ok_hash->{$func}=_export_sym($func,$class,$ancestors); |
|
240
|
|
|
|
|
|
|
}} |
|
241
|
113
|
|
|
|
|
261
|
return @$export_ok_list; |
|
242
|
|
|
|
|
|
|
} |
|
243
|
|
|
|
|
|
|
# for subclasses, @EXPORT_OK and %EXPORT_OK must both be computed |
|
244
|
36
|
|
|
|
|
42
|
my($export_ok_list,$export_ok_hash,@isa,@normal_export_ok,@rename_export_ok,%rename_export_ok); |
|
245
|
|
|
|
|
|
|
{ |
|
246
|
30
|
|
|
30
|
|
179
|
no strict 'refs'; |
|
|
30
|
|
|
|
|
38
|
|
|
|
30
|
|
|
|
|
10729
|
|
|
|
36
|
|
|
|
|
32
|
|
|
247
|
36
|
|
|
|
|
36
|
$export_ok_list=\@{$class.'::EXPORT_OK'}; |
|
|
36
|
|
|
|
|
99
|
|
|
248
|
|
|
|
|
|
|
# NG 12-11-29: 'defined @array' deprecated in 5.16 or so |
|
249
|
|
|
|
|
|
|
# return @$export_ok_list if defined @$export_ok_list; |
|
250
|
36
|
100
|
|
|
|
180
|
return @$export_ok_list if @$export_ok_list; |
|
251
|
6
|
|
|
|
|
8
|
$export_ok_hash=\%{$class.'::EXPORT_OK'}; |
|
|
6
|
|
|
|
|
19
|
|
|
252
|
6
|
|
|
|
|
8
|
@isa=@{$helper_class.'::ISA'}; |
|
|
6
|
|
|
|
|
26
|
|
|
253
|
6
|
|
|
|
|
9
|
@normal_export_ok=@{$class.'::NORMAL_EXPORT_OK'}; |
|
|
6
|
|
|
|
|
19
|
|
|
254
|
6
|
|
|
|
|
8
|
@rename_export_ok=@{$class.'::RENAME_EXPORT_OK'}; |
|
|
6
|
|
|
|
|
17
|
|
|
255
|
6
|
|
|
|
|
7
|
%rename_export_ok=%{$class.'::RENAME_EXPORT_OK'}; |
|
|
6
|
|
|
|
|
40
|
|
|
256
|
|
|
|
|
|
|
}; |
|
257
|
6
|
|
|
|
|
11
|
map {$_->EXPORT_OK} @isa; # mqke sure EXPORT_OK setup in ancestors |
|
|
6
|
|
|
|
|
42
|
|
|
258
|
6
|
|
|
|
|
36
|
my $ancestors=$helper_class->_ancestors; |
|
259
|
|
|
|
|
|
|
|
|
260
|
6
|
|
|
|
|
13
|
for my $func (@normal_export_ok) { |
|
261
|
14
|
|
|
|
|
21
|
$export_ok_hash->{$func}=_export_sym($func,$class,$ancestors); |
|
262
|
|
|
|
|
|
|
} |
|
263
|
6
|
|
|
|
|
24
|
while(my($caller_func,$our_func)=each %rename_export_ok) { |
|
264
|
6
|
|
|
|
|
9
|
$export_ok_hash->{$caller_func}=_export_sym($our_func,$class,$ancestors); |
|
265
|
|
|
|
|
|
|
} |
|
266
|
6
|
50
|
|
|
|
18
|
if (@rename_export_ok) { |
|
267
|
6
|
|
|
|
|
12
|
my($sub,@our_funcs)=@rename_export_ok; |
|
268
|
6
|
|
|
|
|
9
|
my %skip; |
|
269
|
6
|
100
|
|
|
|
15
|
unless (@our_funcs) { # rename list empty, so use default |
|
270
|
|
|
|
|
|
|
# start with all subclass-exportable functions from base classes |
|
271
|
|
|
|
|
|
|
@our_funcs=uniq |
|
272
|
2
|
50
|
|
|
|
4
|
map {UNIVERSAL::can($_,'SUBCLASS_EXPORT_OK')? $_->SUBCLASS_EXPORT_OK: ()} @isa; |
|
|
2
|
|
|
|
|
28
|
|
|
273
|
|
|
|
|
|
|
# %skip contains ones dealt with in @NORMAL_EXPORT_OK or %RENAME_EXPORT_OK |
|
274
|
2
|
|
|
|
|
14
|
@skip{@normal_export_ok}=(1) x @normal_export_ok; |
|
275
|
2
|
|
|
|
|
7
|
@skip{keys %rename_export_ok}=(1) x keys %rename_export_ok; |
|
276
|
|
|
|
|
|
|
# @skip{values %rename_export_ok}=(1) x values %rename_export_ok; |
|
277
|
|
|
|
|
|
|
} |
|
278
|
6
|
|
|
|
|
13
|
for my $our_func (@our_funcs) { |
|
279
|
40
|
|
|
|
|
35
|
local $_=$our_func; |
|
280
|
40
|
|
|
|
|
66
|
my $caller_func=&$sub(); # sub operates on $_ |
|
281
|
40
|
50
|
|
|
|
204
|
next if $skip{$caller_func}; |
|
282
|
40
|
|
|
|
|
53
|
$export_ok_hash->{$caller_func}=_export_sym($our_func,$class,$ancestors); |
|
283
|
|
|
|
|
|
|
} |
|
284
|
|
|
|
|
|
|
} |
|
285
|
6
|
|
|
|
|
62
|
@$export_ok_list=keys %$export_ok_hash; |
|
286
|
|
|
|
|
|
|
} |
|
287
|
|
|
|
|
|
|
sub SUBCLASS_EXPORT_OK { |
|
288
|
8
|
|
|
8
|
|
36
|
my $helper_class=shift; |
|
289
|
8
|
|
|
|
|
30
|
my($class)=$helper_class=~/^(.*)::helper$/; |
|
290
|
30
|
|
|
30
|
|
164
|
no strict 'refs'; |
|
|
30
|
|
|
|
|
55
|
|
|
|
30
|
|
|
|
|
3517
|
|
|
291
|
|
|
|
|
|
|
# for Hash::AutoHash::helper, @SUBCLASS_EXPORT_OK is given |
|
292
|
8
|
100
|
|
|
|
24
|
if ($helper_class eq __PACKAGE__) { # NOTE: change this if you copy-and-paste into subclass |
|
293
|
2
|
|
|
|
|
4
|
return @{$class.'::SUBCLASS_EXPORT_OK'}; |
|
|
2
|
|
|
|
|
49
|
|
|
294
|
|
|
|
|
|
|
} |
|
295
|
|
|
|
|
|
|
# for subclasses, @SUBCLASS_EXPORT_OK must be computed |
|
296
|
6
|
|
|
|
|
7
|
my $subclass_export_ok=\@{$class.'::SUBCLASS_EXPORT_OK'}; |
|
|
6
|
|
|
|
|
17
|
|
|
297
|
|
|
|
|
|
|
# NG 12-11-29: 'defined @array' deprecated in 5.16 or so |
|
298
|
|
|
|
|
|
|
# return @$subclass_export_ok if defined @$subclass_export_ok; |
|
299
|
6
|
50
|
|
|
|
15
|
return @$subclass_export_ok if @$subclass_export_ok; |
|
300
|
6
|
|
|
|
|
15
|
return @$subclass_export_ok=$helper_class->EXPORT_OK; |
|
301
|
|
|
|
|
|
|
} |
|
302
|
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
sub _export_sym { |
|
304
|
690
|
|
|
690
|
|
631
|
my($func,$class,$ancestors)=@_; |
|
305
|
690
|
|
|
|
|
596
|
for my $export_class (@$ancestors) { # @$ancestors includes self |
|
306
|
30
|
|
|
30
|
|
132
|
no strict 'refs'; |
|
|
30
|
|
|
|
|
37
|
|
|
|
30
|
|
|
|
|
38023
|
|
|
307
|
738
|
|
|
|
|
1083
|
my $export_sym=$export_class.'::'.$func; |
|
308
|
738
|
100
|
|
|
|
487
|
return $export_sym if defined *{$export_sym}{CODE}; |
|
|
738
|
|
|
|
|
2920
|
|
|
309
|
|
|
|
|
|
|
# see if ancestor renames it |
|
310
|
62
|
|
|
|
|
200
|
my($class)=$export_class=~/^(.*)::helper$/; |
|
311
|
62
|
|
|
|
|
65
|
my $export_sym=${$class.'::EXPORT_OK'}{$func}; |
|
|
62
|
|
|
|
|
104
|
|
|
312
|
62
|
100
|
|
|
|
139
|
return $export_sym if defined $export_sym; |
|
313
|
|
|
|
|
|
|
} |
|
314
|
4
|
|
|
|
|
15
|
undef; |
|
315
|
|
|
|
|
|
|
} |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
################################################################################# |
|
318
|
|
|
|
|
|
|
# constructor functions. recommended over 'new' |
|
319
|
|
|
|
|
|
|
################################################################################# |
|
320
|
|
|
|
|
|
|
# make real autohash |
|
321
|
|
|
|
|
|
|
# any extra params are key=>value pairs stored in object |
|
322
|
|
|
|
|
|
|
sub autohash_hash { |
|
323
|
160
|
|
|
160
|
|
20241
|
my(@hash)=@_; |
|
324
|
|
|
|
|
|
|
# store params in self. can do in one step since no special semantics to worry about |
|
325
|
160
|
|
|
|
|
835
|
my $self=bless {@hash},'Hash::AutoHash'; |
|
326
|
160
|
|
|
|
|
399
|
$self; |
|
327
|
|
|
|
|
|
|
} |
|
328
|
|
|
|
|
|
|
# tie autohash |
|
329
|
|
|
|
|
|
|
# any extra params passed to tie |
|
330
|
|
|
|
|
|
|
sub autohash_tie (*@) { |
|
331
|
115
|
|
|
115
|
|
41210
|
my($hash_class,@hash_params)=@_; |
|
332
|
115
|
|
|
|
|
292
|
my $self=bless {},'Hash::AutoHash'; |
|
333
|
115
|
|
|
|
|
679
|
tie %$self,$hash_class,@hash_params; |
|
334
|
115
|
|
|
|
|
2178
|
$self; |
|
335
|
|
|
|
|
|
|
} |
|
336
|
|
|
|
|
|
|
# wrap pre-existing hash. |
|
337
|
|
|
|
|
|
|
# any extra params are key=>value pairs passed to hash |
|
338
|
|
|
|
|
|
|
sub autohash_wrap (\%@) { |
|
339
|
240
|
|
|
240
|
|
35761
|
my($hash,@hash)=@_; |
|
340
|
|
|
|
|
|
|
# pass params to hash in loop in case it's tied hash with special semantics |
|
341
|
240
|
|
|
|
|
685
|
while (@hash>1) { |
|
342
|
498
|
|
|
|
|
1729
|
my($key,$value)=splice @hash,0,2; # shift 1st two elements |
|
343
|
498
|
|
|
|
|
1471
|
$hash->{$key}=$value; |
|
344
|
|
|
|
|
|
|
} |
|
345
|
240
|
|
|
|
|
1016
|
my $self=bless {},'Hash::AutoHash'; |
|
346
|
|
|
|
|
|
|
# if $hash is real, tie to 'alias', so autohash will alias hash |
|
347
|
240
|
100
|
|
|
|
636
|
if (my $object=tied(%$hash)) { |
|
348
|
122
|
|
|
|
|
1016
|
tie %$self,'Tie::ToObject',$object; |
|
349
|
|
|
|
|
|
|
} else { |
|
350
|
118
|
|
|
|
|
546
|
tie %$self,'Hash::AutoHash::alias',$hash; |
|
351
|
|
|
|
|
|
|
} |
|
352
|
240
|
|
|
|
|
2474
|
$self; |
|
353
|
|
|
|
|
|
|
} |
|
354
|
|
|
|
|
|
|
# wrap pre-existing tied object. (ie, object returned by tie), |
|
355
|
|
|
|
|
|
|
# any extra params are key=>value pairs passed to object's STORE method |
|
356
|
|
|
|
|
|
|
sub autohash_wrapobj { |
|
357
|
128
|
|
|
128
|
|
27970
|
my($object,@hash)=@_; |
|
358
|
|
|
|
|
|
|
# pass params to hash in loop in case it's tied hash with special semantics |
|
359
|
128
|
|
|
|
|
404
|
while (@hash>1) { |
|
360
|
259
|
|
|
|
|
1209
|
my($key,$value)=splice @hash,0,2; # shift 1st two elements |
|
361
|
259
|
|
|
|
|
549
|
$object->STORE($key,$value); |
|
362
|
|
|
|
|
|
|
} |
|
363
|
128
|
|
|
|
|
702
|
my $self=bless {},'Hash::AutoHash'; |
|
364
|
128
|
|
|
|
|
926
|
tie %$self,'Tie::ToObject',$object; |
|
365
|
128
|
|
|
|
|
2282
|
$self; |
|
366
|
|
|
|
|
|
|
} |
|
367
|
|
|
|
|
|
|
# tie and wrap hash in one step. any extra params passed to tie |
|
368
|
|
|
|
|
|
|
# kinda silly, but oh well... |
|
369
|
|
|
|
|
|
|
sub autohash_wraptie (\%*@) { |
|
370
|
128
|
|
|
128
|
|
31036
|
my($hash,$hash_class,@hash_params)=@_; |
|
371
|
128
|
|
|
|
|
1000
|
my $object=tie %$hash,$hash_class,@hash_params; |
|
372
|
128
|
|
|
|
|
2351
|
my $self=bless {},'Hash::AutoHash'; |
|
373
|
128
|
|
|
|
|
1044
|
tie %$self,'Tie::ToObject',$object; |
|
374
|
128
|
|
|
|
|
2235
|
$self; |
|
375
|
|
|
|
|
|
|
} |
|
376
|
|
|
|
|
|
|
# autohash_new - CAUTION: must come after other constructors because of prototypes |
|
377
|
|
|
|
|
|
|
# front-end to other constructor functions |
|
378
|
|
|
|
|
|
|
# cases: |
|
379
|
|
|
|
|
|
|
# 1) 0 params - autohash_hash |
|
380
|
|
|
|
|
|
|
# 2) >0 params - 1st param unblessed ARRAY - autohash_tie or autohash_wraptie |
|
381
|
|
|
|
|
|
|
# 0th element scalar - autohash_tie |
|
382
|
|
|
|
|
|
|
# 0th element HASH - autohash_wraptie |
|
383
|
|
|
|
|
|
|
# 3) >0 params - 1st param unblessed HASH - autohash_wrap |
|
384
|
|
|
|
|
|
|
# 4) >0 params - 1st param blessed HASH apparently not tied hash - autohash_wrap |
|
385
|
|
|
|
|
|
|
# 5) >0 params - 1st param blessed and looks like tied hash object - autohash_wrapobj |
|
386
|
|
|
|
|
|
|
# 6) other - autohash_hash |
|
387
|
|
|
|
|
|
|
sub autohash_new { |
|
388
|
348
|
100
|
|
348
|
|
77502
|
if (@_) { |
|
389
|
302
|
100
|
|
|
|
986
|
if ('ARRAY' eq ref $_[0]) { # autohash_tie or autohash_wraptie |
|
390
|
94
|
|
|
|
|
139
|
my $autohash; |
|
391
|
94
|
|
|
|
|
151
|
my $params=shift; |
|
392
|
94
|
|
|
|
|
174
|
my $class_or_hash=shift @$params; |
|
393
|
94
|
100
|
|
|
|
257
|
unless (ref $class_or_hash) { # it's a class. so tie it |
|
394
|
37
|
|
|
|
|
121
|
$autohash=autohash_tie($class_or_hash,@$params); |
|
395
|
|
|
|
|
|
|
} else { # it's a hash. next param is class |
|
396
|
57
|
|
|
|
|
113
|
my $hash=$class_or_hash; |
|
397
|
57
|
|
|
|
|
90
|
my $class=shift @$params; |
|
398
|
57
|
|
|
|
|
194
|
$autohash=autohash_wraptie(%$hash,$class,@$params); |
|
399
|
|
|
|
|
|
|
} |
|
400
|
94
|
|
|
|
|
363
|
return autohash_set($autohash,@_); |
|
401
|
|
|
|
|
|
|
} |
|
402
|
208
|
100
|
100
|
|
|
1129
|
if ('HASH' eq reftype($_[0]) && !_looks_wrappable($_[0])) { |
|
403
|
102
|
|
|
|
|
135
|
my $hash=shift; |
|
404
|
102
|
|
|
|
|
313
|
return autohash_wrap(%$hash,@_); |
|
405
|
|
|
|
|
|
|
} |
|
406
|
106
|
100
|
|
|
|
293
|
if (_looks_wrappable($_[0])) { |
|
407
|
54
|
|
|
|
|
217
|
return autohash_wrapobj(@_); |
|
408
|
|
|
|
|
|
|
}} |
|
409
|
|
|
|
|
|
|
# none of the above, so must be real |
|
410
|
98
|
|
|
|
|
271
|
autohash_hash(@_); |
|
411
|
|
|
|
|
|
|
} |
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
# try to decide if object tied to hash. very approximate... |
|
414
|
|
|
|
|
|
|
# say yes if blessed and has TIEHASH method |
|
415
|
260
|
100
|
|
260
|
|
1653
|
sub _looks_wrappable {blessed($_[0]) && UNIVERSAL::can($_[0],'TIEHASH');} |
|
416
|
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
################################################################################# |
|
418
|
|
|
|
|
|
|
# following functions provide standard hash operations on Hash::AutoHash |
|
419
|
|
|
|
|
|
|
# objects. they delegate to wrapped goodie |
|
420
|
|
|
|
|
|
|
################################################################################# |
|
421
|
15
|
|
|
15
|
|
23937
|
sub autohash_clear {%{$_[0]}=()} |
|
|
15
|
|
|
|
|
109
|
|
|
422
|
|
|
|
|
|
|
sub autohash_delete { |
|
423
|
185
|
|
|
185
|
|
2651
|
my $self=shift; |
|
424
|
185
|
|
|
|
|
758
|
delete @$self{@_}; |
|
425
|
|
|
|
|
|
|
} |
|
426
|
490
|
|
|
490
|
|
566276
|
sub autohash_each {each %{$_[0]}} |
|
|
490
|
|
|
|
|
1581
|
|
|
427
|
327
|
|
|
327
|
|
6213
|
sub autohash_exists {exists $_[0]->{$_[1]}} |
|
428
|
98
|
|
|
98
|
|
4644
|
sub autohash_keys {keys %{$_[0]}} |
|
|
98
|
|
|
|
|
482
|
|
|
429
|
95
|
|
|
95
|
|
1849
|
sub autohash_values {values %{$_[0]}} |
|
|
95
|
|
|
|
|
474
|
|
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
################################################################################# |
|
432
|
|
|
|
|
|
|
# convenience methods easily be built on top of keys |
|
433
|
|
|
|
|
|
|
################################################################################# |
|
434
|
26
|
100
|
|
26
|
|
3040
|
sub autohash_count {scalar(keys %{$_[0]}) || 0} |
|
|
26
|
|
|
|
|
107
|
|
|
435
|
27
|
100
|
|
27
|
|
735
|
sub autohash_empty {scalar(%{$_[0]})? undef: 1} |
|
|
27
|
|
|
|
|
99
|
|
|
436
|
27
|
100
|
|
27
|
|
5174
|
sub autohash_notempty {scalar(%{$_[0]})? 1: undef} |
|
|
27
|
|
|
|
|
76
|
|
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
################################################################################ |
|
439
|
|
|
|
|
|
|
# alias - connect autohash to hash - can be used to do the opposite of wrap |
|
440
|
|
|
|
|
|
|
################################################################################ |
|
441
|
|
|
|
|
|
|
sub autohash_alias (\$\%@) { |
|
442
|
49
|
|
|
49
|
|
5408
|
my($autohash_ref,$hash,@hash)=@_; |
|
443
|
49
|
100
|
|
|
|
154
|
if (!defined $$autohash_ref) { # no autohash, so create alias from hash to autohash |
|
444
|
8
|
|
|
|
|
28
|
return $$autohash_ref=autohash_wrap(%$hash,@hash); |
|
445
|
|
|
|
|
|
|
} else { # create alias from autohash to hash |
|
446
|
41
|
|
|
|
|
57
|
my $autohash=$$autohash_ref; |
|
447
|
41
|
|
|
|
|
124
|
autohash_set($autohash,@hash); |
|
448
|
41
|
|
|
|
|
170
|
tie %$hash,'Hash::AutoHash::alias',$autohash; |
|
449
|
|
|
|
|
|
|
} |
|
450
|
|
|
|
|
|
|
} |
|
451
|
|
|
|
|
|
|
################################################################################ |
|
452
|
|
|
|
|
|
|
# functional access to tied object. works on aliased hash, also |
|
453
|
|
|
|
|
|
|
################################################################################ |
|
454
|
|
|
|
|
|
|
# sub autohash_options (\[$%]) { |
|
455
|
|
|
|
|
|
|
# my($ref)=@_; |
|
456
|
|
|
|
|
|
|
# my $autohash; |
|
457
|
|
|
|
|
|
|
# if ('REF' eq ref $ref) { # it's autohash (we hope :) |
|
458
|
|
|
|
|
|
|
# $autohash=$$ref; # dereference to get autohash |
|
459
|
|
|
|
|
|
|
# my $object=tied %$autohash; |
|
460
|
|
|
|
|
|
|
# return undef unless $object; # real hash |
|
461
|
|
|
|
|
|
|
# return undef if 'Hash::AutoHash::alias' eq ref $object; # aliased to real |
|
462
|
|
|
|
|
|
|
# return $object; # tied or aliased to tied |
|
463
|
|
|
|
|
|
|
# } elsif ('HASH' eq ref $ref) { # HASH may be tied to 'real object or 'alias' |
|
464
|
|
|
|
|
|
|
# my $object=tied %$ref; |
|
465
|
|
|
|
|
|
|
# return undef unless $object; |
|
466
|
|
|
|
|
|
|
# return $object unless 'Hash::AutoHash::alias' eq ref $object; |
|
467
|
|
|
|
|
|
|
# # hash aliased to autohash. recurse to get underlying tied object |
|
468
|
|
|
|
|
|
|
# $autohash=$object->[0]; # extract autohash from alias |
|
469
|
|
|
|
|
|
|
# return &autohash_options(\$autohash); # use old-style call to turn off prototyping |
|
470
|
|
|
|
|
|
|
# } |
|
471
|
|
|
|
|
|
|
# undef; |
|
472
|
|
|
|
|
|
|
# } |
|
473
|
|
|
|
|
|
|
# sub autohash_options (\[$%]) { |
|
474
|
|
|
|
|
|
|
# my($ref)=@_; |
|
475
|
|
|
|
|
|
|
# my($autohash,$hash); |
|
476
|
|
|
|
|
|
|
# $autohash=$$ref if 'REF' eq ref $ref; # it's autohash (we hope :) |
|
477
|
|
|
|
|
|
|
# $hash=$ref if 'HASH' eq ref $ref; |
|
478
|
|
|
|
|
|
|
# if ($hash) { # do hash case first. sometimes falls into autohash case |
|
479
|
|
|
|
|
|
|
# my $object=tied %$ref; |
|
480
|
|
|
|
|
|
|
# return undef unless $object; |
|
481
|
|
|
|
|
|
|
# return $object unless 'Hash::AutoHash::alias' eq ref $object; |
|
482
|
|
|
|
|
|
|
# # hash aliased to autohash. extract autohash from alias and fall into authohash case |
|
483
|
|
|
|
|
|
|
# $autohash=$object->[0]; |
|
484
|
|
|
|
|
|
|
# } |
|
485
|
|
|
|
|
|
|
# if ($autohash) { |
|
486
|
|
|
|
|
|
|
# my $object=tied %$autohash; |
|
487
|
|
|
|
|
|
|
# return undef unless $object; # real hash |
|
488
|
|
|
|
|
|
|
# return undef if 'Hash::AutoHash::alias' eq ref $object; # aliased to real |
|
489
|
|
|
|
|
|
|
# return $object; # tied or aliased to tied |
|
490
|
|
|
|
|
|
|
# } |
|
491
|
|
|
|
|
|
|
# undef; |
|
492
|
|
|
|
|
|
|
# } |
|
493
|
|
|
|
|
|
|
# sub autohash_option (\[$%]@) { |
|
494
|
|
|
|
|
|
|
# my($ref,$option,@params)=@_; |
|
495
|
|
|
|
|
|
|
# my $object=&autohash_options($ref); # use old-style call to turn off prototyping |
|
496
|
|
|
|
|
|
|
# return undef unless $object; |
|
497
|
|
|
|
|
|
|
# $object->$option(@params); |
|
498
|
|
|
|
|
|
|
# } |
|
499
|
|
|
|
|
|
|
sub autohash_tied (\[$%]@) { |
|
500
|
376
|
|
|
376
|
|
24166
|
my $ref=shift; |
|
501
|
376
|
|
|
|
|
321
|
my($autohash,$hash,$tied); |
|
502
|
376
|
100
|
|
|
|
1015
|
$autohash=$$ref if 'REF' eq ref $ref; # it's autohash (we hope :) |
|
503
|
376
|
100
|
|
|
|
659
|
$hash=$ref if 'HASH' eq ref $ref; |
|
504
|
376
|
100
|
|
|
|
588
|
if ($hash) { # do hash case first. sometimes falls into autohash case |
|
505
|
171
|
|
|
|
|
177
|
$tied=tied %$ref; |
|
506
|
|
|
|
|
|
|
# hash aliased to autohash. extract autohash from alias and fall into authohash case |
|
507
|
171
|
100
|
|
|
|
344
|
$autohash=$tied->[0] if 'Hash::AutoHash::alias' eq ref $tied; |
|
508
|
|
|
|
|
|
|
} |
|
509
|
376
|
100
|
|
|
|
559
|
if ($autohash) { |
|
510
|
296
|
|
|
|
|
281
|
$tied=tied %$autohash; |
|
511
|
296
|
100
|
|
|
|
602
|
$tied=undef if 'Hash::AutoHash::alias' eq ref $tied; # aliased to real |
|
512
|
|
|
|
|
|
|
} |
|
513
|
376
|
100
|
100
|
|
|
1594
|
return $tied unless @_ && $tied; |
|
514
|
|
|
|
|
|
|
# have tied object and there are more params. this means 'run method on tied object' |
|
515
|
168
|
|
|
|
|
266
|
my($method,@params)=@_; |
|
516
|
168
|
|
|
|
|
853
|
$tied->$method(@params); |
|
517
|
|
|
|
|
|
|
} |
|
518
|
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
################################################################################# |
|
520
|
|
|
|
|
|
|
# get and set offer extended functionality for users of this interface. |
|
521
|
|
|
|
|
|
|
# 'set' is the useful one. 'get' provided for symmetry |
|
522
|
|
|
|
|
|
|
################################################################################# |
|
523
|
|
|
|
|
|
|
# get values for one or more keys. |
|
524
|
|
|
|
|
|
|
sub autohash_get { |
|
525
|
137
|
|
|
137
|
|
2215
|
my $self=shift; |
|
526
|
137
|
|
|
|
|
658
|
@$self{@_}; |
|
527
|
|
|
|
|
|
|
} |
|
528
|
|
|
|
|
|
|
# set one or more key=>value pairs in hash |
|
529
|
|
|
|
|
|
|
sub autohash_set { |
|
530
|
183
|
|
|
183
|
|
5736
|
my $self=shift; |
|
531
|
183
|
100
|
100
|
|
|
1006
|
if (@_==2 && 'ARRAY' eq ref $_[0] && 'ARRAY' eq ref $_[1]) { # separate arrays form |
|
|
|
|
66
|
|
|
|
|
|
532
|
19
|
|
|
|
|
35
|
my($keys,$values)=@_; |
|
533
|
19
|
|
|
|
|
77
|
for (my $i=0; $i<@$keys; $i++) { |
|
534
|
23
|
|
|
|
|
98
|
my($key,$value)=($keys->[$i],$values->[$i]); |
|
535
|
23
|
|
|
|
|
94
|
$self->{$key}=$value; |
|
536
|
|
|
|
|
|
|
}} else { # key=>value form |
|
537
|
164
|
|
|
|
|
531
|
while (@_>1) { |
|
538
|
255
|
|
|
|
|
1372
|
my($key,$value)=splice @_,0,2; # shift 1st two elements |
|
539
|
255
|
|
|
|
|
878
|
$self->{$key}=$value; |
|
540
|
|
|
|
|
|
|
}} |
|
541
|
183
|
|
|
|
|
1144
|
$self; |
|
542
|
|
|
|
|
|
|
} |
|
543
|
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
################################################################################# |
|
545
|
|
|
|
|
|
|
# destroy and untie rarely used but needed for full tied hash functionality. |
|
546
|
|
|
|
|
|
|
# destroy nop. untie calls tied object's untie method |
|
547
|
|
|
|
|
|
|
################################################################################# |
|
548
|
|
|
|
0
|
|
|
sub autohash_destroy {} |
|
549
|
|
|
|
|
|
|
sub autohash_untie { |
|
550
|
0
|
|
|
0
|
|
0
|
my $object=tied(%{$_[0]}); |
|
|
0
|
|
|
|
|
0
|
|
|
551
|
0
|
0
|
|
|
|
0
|
$object->UNTIE() if $object; |
|
552
|
|
|
|
|
|
|
} |
|
553
|
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
# ################################################################################# |
|
555
|
|
|
|
|
|
|
# # this package used to 'dup' autohash to externally supplied real hash |
|
556
|
|
|
|
|
|
|
# # amazing that nothing in CPAN does this! I found several 'alias' packages but |
|
557
|
|
|
|
|
|
|
# # none could connect new variable to old one without changing the type of old |
|
558
|
|
|
|
|
|
|
# ################################################################################# |
|
559
|
|
|
|
|
|
|
# package Hash::AutoHash::dup; |
|
560
|
|
|
|
|
|
|
# use strict; |
|
561
|
|
|
|
|
|
|
# use Tie::Hash; |
|
562
|
|
|
|
|
|
|
# our @ISA=qw(Tie::ExtraHash); |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
# sub TIEHASH { |
|
565
|
|
|
|
|
|
|
# my($class,$existing_hash)=@_; |
|
566
|
|
|
|
|
|
|
# bless [$existing_hash],$class; |
|
567
|
|
|
|
|
|
|
# } |
|
568
|
|
|
|
|
|
|
################################################################################# |
|
569
|
|
|
|
|
|
|
# this package used to 'alias' hash to externally supplied hash |
|
570
|
|
|
|
|
|
|
# amazing that nothing in CPAN does this! I found several 'alias' packages but |
|
571
|
|
|
|
|
|
|
# none could connect new variable to old one without changing the type of old |
|
572
|
|
|
|
|
|
|
################################################################################# |
|
573
|
|
|
|
|
|
|
package Hash::AutoHash::alias; |
|
574
|
|
|
|
|
|
|
our $VERSION=$Hash::AutoHash::VERSION; |
|
575
|
30
|
|
|
30
|
|
203
|
use strict; |
|
|
30
|
|
|
|
|
48
|
|
|
|
30
|
|
|
|
|
729
|
|
|
576
|
30
|
|
|
30
|
|
16772
|
use Tie::Hash; |
|
|
30
|
|
|
|
|
24937
|
|
|
|
30
|
|
|
|
|
2501
|
|
|
577
|
|
|
|
|
|
|
our @ISA=qw(Tie::ExtraHash); |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
sub TIEHASH { |
|
580
|
159
|
|
|
159
|
|
247
|
my($class,$existing_autohash)=@_; |
|
581
|
159
|
|
|
|
|
551
|
bless [$existing_autohash],$class; |
|
582
|
|
|
|
|
|
|
} |
|
583
|
|
|
|
|
|
|
1; |
|
584
|
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
__END__ |