our
$VERSION
=
'0.3a_pre1'
;
sub
wipe {
my
$self
=
shift
;
my
$tag
=
shift
|| croak
q{Cowardly refusing to wipe the whole dispatch table}
;
my
$count
= 0;
for
(
keys
%{
$self
->[0]}) {
delete
(${
$self
->[0]}{
$_
}) &&
$count
++
if
ref
(
$self
->[0]{
$_
}) eq
'ARRAY'
&&
$self
->[0]{
$_
}[1] eq
$tag
;
}
return
$count
;
}
sub
TIEHASH {
my
$class
=
shift
;
my
$ref
=
shift
;
my
$hash
=
shift
|| {};
croak
q{First argument should be an object reference}
unless
(
ref
(
$ref
) &&
ref
(
$ref
) ne
'HASH'
);
bless
[
$hash
,
$ref
],
$class
;
}
sub
STORE {
my
(
$self
,
$key
,
$value
) =
@_
;
my
$t
=
ref
(
$value
);
unless
(
$t
) {
$value
=
$self
->_check(
$value
) }
elsif
(
$t
eq
'ARRAY'
) {
$value
->[0] =
$self
->_check(
$value
->[0]) }
elsif
(
$t
ne
'CODE'
) { croak
qq{Can't use a $t reference as sub routine}
}
$self
->[0]{
$key
} =
$value
;
}
sub
_check {
my
$self
=
shift
;
my
$value
=
shift
;
$value
=~ s/(^\s*|\s*$)//g;
croak
'empty value not allowed'
unless
$value
;
croak
'value has an unsupported format'
if
$value
=~ /^\$/;
return
$value
;
}
sub
FETCH {
my
(
$self
,
$key
) =
@_
;
return
undef
unless
exists
${
$self
->[0]}{
$key
};
my
$value
=
$self
->[0]{
$key
};
my
$t
=
ref
$value
;
if
(
$t
eq
'CODE'
) {
return
$value
}
elsif
(
$t
eq
'ARRAY'
) {
return
$value
->[0]
if
ref
(
$value
->[0]) eq
'CODE'
;
$value
->[0] =
$self
->_convert(
$value
->[0]);
$self
->[0]{
$key
} =
$value
;
return
$value
->[0];
}
else
{
$self
->[0]{
$key
} =
$self
->_convert(
$value
);
return
$self
->[0]{
$key
};
}
}
sub
_convert {
my
$self
=
shift
;
my
$ding
=
shift
;
$ding
=~ s{^->((\w+)->)?}{
$self
->[1]->can(
'parent'
)
?
q#parent->#
.( $1 ?
qq#object('$2')->#
:
''
)
: ( $1 ?
qq#object('$2')->#
:
''
)
}e;
if
(
$ding
=~ /\(.*\)$/) {
$ding
=~ s/\)$/, \
@_
\)/ }
else
{
$ding
.=
'(@_)'
}
return
eval
(
"sub { \$self->[1]->$ding }"
);
}
1;