in reply to Using sub routines or AUTOLOAD for XS constants

If you're getting the error message "can't locate exported subroutine $name via $class" from Sub::Exporter's default_generator(), the best option is to override can() in your package when you use AUTOLOAD(). That's a good practice anyway, though.

I haven't tested this code, but something like this should work:

sub can { my ($class, $name) = @_; return if $name eq 'constant'; my ($error, $val) = constant($name); return if $error; my $sub = sub () { $val }; { no strict 'refs'; *{ $class . '::' . $name } = $sub; } return $sub; }

Replies are listed 'Best First'.
Re^2: Using sub routines or AUTOLOAD for XS constants
by ikegami (Patriarch) on Jan 01, 2010 at 22:23 UTC
    Sub::Exporter uses can? That's a bug. can is for methods, and it makes no sense to export methods.
      can is for methods...

      I agree in principle, but what's the difference in practice between a method and a function, at least when you're groveling through a package's symbol table?

      There's likely a bug lurking in Sub::Exporter here as well, if it ever tries to export an inherited function.

        It means there's a hole (false positives) in the error checking the author apparently desires, and it probably allows it to export inherited subs are a result.
Re^2: Using sub routines or AUTOLOAD for XS constants
by aflott (Beadle) on Jan 01, 2010 at 20:54 UTC

    Yes that is exactly what I was looking for. Although I had to add

    return \&{$class . '::' . $name} if (defined(&{$name}));

    for having the non-constant subs reachable.

    Thanks for the nudge in the right direction.