in reply to Re: Reset the effect of #line
in thread Reset the effect of #line

Hello Eily, thanks for your response.

I am writing a small Pod::Parser implementation that does something similar to Test::Pod::Snippets (that module doesn't work in my case and it doesn't look like I'd be able to extend it). I don't feel like this is an XY Problem, my question really does boil down to: how do I reset the effects of the #line directive so that error messages resume their default behavior and refer to the current file and line number again?

Keeping track of input file names and line numbers isn't the problem, it's output file names and line numbers, since I'm just writing to STDOUT and I have no way of knowing where that'll end up.

Anyway, here's an example of the general question. This is input.pl:

print "foo\n"; die "oops" if rand>0.7; print "bar\n";

Then I run this through my hypothetical script which generates and inserts some code, which produces output.pl:

#line 1 input.pl print "foo\n"; die "oops" if rand>0.7; #line __LINE__ __FILE__ print "I am some generated code\n"; die "some error" if rand>0.3; #line 3 input.pl print "bar\n";

The first die in either script always has the error message "oops at input.pl line 2", that's what I want.

Now the problem is, I'd like to have the error message from the second die be "some error at output.pl line 6". However, it is (unsurprisingly) "some error at input.pl line 5".

As I said above, even though I could theoretically try to track the output line number, I definitely can't track the output file name. If I replace #line __LINE__ __FILE__ with #line 5, I get the error message "some error at input.pl line 6", which isn't right either.

I hope this answers your questions and makes the problem clearer?

Replies are listed 'Best First'.
Re^3: Reset the effect of #line
by Eily (Monsignor) on Aug 26, 2013 at 08:00 UTC

    Oh well, not putting __FILE__ in the directive won't work there, my bad :).

    Could you eval your generated code instead? You do get the original filename back when you exit the eval scope:

    #line 10 Foo warn; eval <<"BAZ"; #line 100 Bar warn; BAZ warn;
    Warning: something's wrong at Foo line 10. Warning: something's wrong at Bar line 100. Warning: something's wrong at Foo line 15.