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

In one project, I compile a lot of code (in AUTOLOAD) from a data base. When such a compiled function gets into trouble, the error message would read like:
Use of uninitialized value at (eval 137) line 24
Because I don't know in what order the functions are defined, this is much less useful than a message like:
Use of uninitialized value at (method P::foo) line 24

Is there a proper way to tell eval the origin of the code (in our case the string "Method P::foo") that the messages come out correctly?

At the moment, I hack the source of perl: I found the line where a buffer is set up with the string "_<(eval %l)". I added some code to check whether the perl variable $CB::EvalName is defined and true. If yes, it replaces the buffer (and comes out correctly). If no, then the buffer is used as normal.

It works fine but it doesn't look right...

Replies are listed 'Best First'.
Re: How to tell eval where the code is from
by tilly (Archbishop) on Aug 08, 2000 at 15:37 UTC
    You probably would find it best to use Carp, test @_ after the eval, and if it is set then confess to the problem.

    In the confess you can name the function.

    BTW don't use confess if you don't think that a stack backtrace would be helpful. Personally I do surprisingly often but YMMV.

      Thank you very much for your help.

      I am still stuck with AUTOLOADed routines: When the routine is called the first time, AUTOLOAD executes a statement like

      $code=$database{$AUTOLOAD}; # e.g: "sub pkg::foo {...}" eval $code; $@ and error_msg($AUTOLOAD, $@, $code); goto &$AUTOLOAD;

      This code catches compilation errors. But when the routine is actually called later, the variable $@ is no longer active.

      Also, warnings (like those for undefined values) are generated without giving the running code an opportunity to add some information.

        Inside your eval, add something like:
        $code = $database{$AUTOLOAD}; $pseudo_file = get_pseudo_for($AUTOLOAD); # like "Database_entry_for_p +kg::foo" eval qq{#line 1 "$pseudo_file"\n$code}; ...
        Now when an error triggers, you'll get
        whatever error from Database_entry_for_pkg::foo, line 14
        in $@ Use the cpp triggers, luke!

        -- Randal L. Schwartz, Perl hacker

        I thought of this after I posted.

        I actually think that your original approach is the right idea, wrong syntax. A better approach probably would be to provide a second optional argument to eval() that is the name to call this error.

        In any case I suggest that you sign up for the perl5-porters list, state your problem, state your proposed solution, and see if you cannot get it accepted. Possibly with the syntax I am recommending. Possibly with some better syntax that they think of.