# 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 { my $constname; ($constname = $AUTOLOAD) =~ s/.*:://; my $val = constant($constname, 0); if ($!) { # the name in $AUTOLOAD is not a constant defined by XYZ::ABC if (my ($kind, $nolock, $function) = $AUTOLOAD =~ /^XYZ::ABC::(Scalar|Array|Hash)::(NoLock::)?([A-Z]+)$/) { if ($function =~/^TIE$kind$/i) { my $self = shift; my $sah = shift; # sah = scalar/array/hash return bless \$sah, $self; # vv Scalar or Array or Hash } elsif ($function =~ /^(FETCH|STORE)$/ || $kind !~ /^S/ # vv Array or Hash && $function =~ /^(DELETE|EXISTS|CLEAR)$/ || $kind =~ /^A/ # vv Array && $function =~ /^(FETCHSIZE|STORESIZE|EXTEND|POP|PUSH|SHIFT|UNSHIFT|SPLICE)$/ || $kind =~ /^H/ # vv Hash && $function =~ /^(FIRSTKEY|NEXTKEY|SCALAR)$/) { my $subname = 'abc' . ($nolock ? 'a_' : '_') . lc($kind) . '_' . lc($function); my $sah_ref = shift; { no strict 'refs'; # differentiate subs with and without return values if ($function =~ /^(ST|CL|PU|UN|EXT)/) { &$subname ($$sah_ref, @_); return; } else { return &$subname ($$sah_ref, @_); } } } elsif ($function =~ /^(UNTIE|DESTROY)$/) { # how do we do nothing? return; # ?? } } 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? }