in reply to Autoloading tie routines

For cloture of this thread (not to be confused with "foreclosure" [a popular topic these days] nor with "closure" in perl and other languages [consult tilly about this]), here is the AUTOLOAD routine I ended up with:
# AUTOLOAD is used to # 1) 'autoload' constants from the constant() function in ABC.xs # If the name is not a constant then it's parsed for # 2) a tie package-name::function-name, which if matched is executed our $AUTOLOAD; # implicit argument of AUTOLOAD sub AUTOLOAD { # make the base name (without the "package::") (my $constname = $AUTOLOAD) =~ s/.*:://; # call the constant lookup routine in ABC.xs my $val = constant($constname, 0); if ($!) { # the name in $AUTOLOAD is not a constant defined by XYZ::ABC # sah = scalar/array/hash if (my ($abcx, $sah, $function) = $AUTOLOAD =~ /^XYZ::(ABCA?)::(Scalar|Array|Hash|BTree)::([ +A-Z]+)$/) { if (($sah = lc $sah) eq 'btree') {$sah = 'hash'} if ($function eq uc("TIE$sah")) { my $self = shift; my $base_sah = shift; # sah = scalar/array/hash $val = ''; if (!$base_sah || ($val = ref($base_sah)) ne "abc_${sa +h}Ptr") { croak "3rd operand of tie should be the return val +ue from abc_make_$sah: ref was '$val'"; } return bless \$base_sah, $self; # Scalar or Array or Hash } elsif ($function eq 'FETCH' || $function eq 'STORE' || $sah ne 'scalar' # Array or Hash && $function =~ /^(DELETE|EXISTS|CLEAR)$/ || $sah eq 'array' && $function =~ /^(FETCHSIZE|STORESIZE|EXTEND|POP|PU +SH|SHIFT|UNSHIFT|SPLICE)$/ || $sah eq 'hash' && $function =~ /^(FIRSTKEY|NEXTKEY|SCALAR)$/) { $function =~ s/KEY$/_KEY/; if ($sah eq 'array' #nowrap && $function =~ /^(FETCH$|STORE$|EXI|D|SP)/) {#nowrap $function .= '_nowrap'; #nowrap } my $subname = lc($abcx) . "_${sah}_" . lc($function); no strict 'refs'; # define the symbol so AUTOLOAD won't be called again +for this name *$AUTOLOAD = sub { # dereference the base scalar/array/hash my $base_sah_ref = shift; unshift @_, $$base_sah_ref; # go to the constructed sub name in ABC.xs goto &$subname; }; # having defined the symbol, execute the sub in ABC.xs goto &$AUTOLOAD; } elsif ($function eq 'UNTIE' || $function eq 'DESTROY') { return; # do nothing } } croak "$AUTOLOAD is not a defined constant or subroutine for X +YZ::ABC"; } # the name in $AUTOLOAD is a constant defined by XYZ::ABC: define +it for perl no strict 'refs'; # define the symbol so AUTOLOAD won't be called again for this nam +e *$AUTOLOAD = sub{$val}; # in the general case the following line should be goto &$AUTOLOAD +; return $val; }
If it changes I'll update this posting...

Thanks to all esp. tilly,
cmac
www.animalhead.com

A "universal can" is one that anyone can kick, drink from, or urinate into, although certain interactions among these methods are to be avoided...