random_perler has asked for the wisdom of the Perl Monks concerning the following question:

Greetings fellow monks!

I need to dynamically take a reference to a core function and assign it to my own (basically create an alias for it).

The background is that it should be possible to change how to handle module errors depending on import flags. The module has its own error() function, that is only called when module related errors happen, and that then either dies, or warns, or more or less prints the error message (depending on the mentioned import flags).

Modifying $SIG is not an option, since only module errors should be affected (all the 'normal' 'die's/'warn's that are unrelated to module logic should go untrapped). Calling 'die' or 'warn' from inside the function is not really an option either, since it messes up caller() information.
So I was thinking more of something like

sub import { ... no strict 'refs'; *{__PACKAGE__.'::error'} = $flag eq 'warn' ? .... # reference to ' +warn' ... } ... error('Something went wrong!') if $a != $b;

All the docs I've browsed only contain information on overloading core functions, and one of them even stated explicitly that you can't take a reference to core funcs through CORE / CORE::GLOBAL (that was the first thing I tried). Searching google and perlmonks had pretty much the same result.

So is it possible at all to create a direct reference to a core function? Or is there a better way?

Thanks in advance!

Replies are listed 'Best First'.
Re: Creating a reference to a core function (closures)
by tye (Sage) on Apr 28, 2008 at 05:49 UTC
Re: Creating a reference to a core function
by mscharrer (Hermit) on Apr 28, 2008 at 09:08 UTC
    AFIK, you can't reference to core functions because there are build-ins, i.e. written in C, and not normal Perl functions. The only way to pass them around is to enclose them in an (anonymous) subfunction like shown by tye above. In general you should know that most build-in functions are using prototypes, e.g. pop awaits an array as first argument. So you would have to rebuild this prototypes in your subfunction to get the same usage syntax. I'm not sure if you can use prototypes with anonymous subfunctions, but you could still create a named one and reference it.
      The problem with anonymous subs is that it still messes up caller() information and will display the line where the sub was defined as the error source. And rebuilding the behavior with prototypes leaves me basically with the same problem.

      I had a look at the source of Carp to see how it deals with that, and it seems that most of the (evil) magic comes from goto jumps and tracking the callers package name to exclude calls from those that are considered 'internal' (i.e. Carp itself).
      And since this all has already been invented, written and debugged, I'll go back to loading Carp and referencing to either carp() or croak() (which works as intended).

      Thinking about it, I'd guess that core functions 'live' in a different memory space than functions and variables generated on compile / run. So it probably makes good sense that you can't take a reference to them.

      It's just a bit 'disappointing' to run into some kind of limit in a language that seems to have none ;)

      Thanks alot for the replies!
Re: Creating a reference to a core function
by Anonymous Monk on Apr 28, 2008 at 04:22 UTC