# 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 eq 'BTree') {$sah = 'Hash'} if ($function eq uc("TIE$sah")) { my $self = shift; my $base_sah = shift; # sah = scalar/array/hash 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/; my $subname = lc($abcx) . '_' . lc($sah) . '_' . lc($function); my $base_sah_ref = shift; unshift @_, $$base_sah_ref; # dereference the base scalar/array/hash goto &$subname; } 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 eval "sub $AUTOLOAD { $val }"; # can this be $constname rather than $AUTOLOAD? goto &$AUTOLOAD; # can this just be 'return' if all of the defined names really are constants? }