# 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_${sah}Ptr") { croak "3rd operand of tie should be the return value 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|PUSH|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 XYZ::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 name *$AUTOLOAD = sub{$val}; # in the general case the following line should be goto &$AUTOLOAD; return $val; }