in reply to Reset the effect of #line

Maybe you should provide an example because I'm not sure I understood quite well. But if you read the documentation on #line directives you'll see that you do not have to provide a filename. It's not expressed as such, but it is said that the #line syntax matches the regex:

/^\# \s* line \s+ (\d+) \s* (?:\s("?)([^"]+)\g2)? \s* $/x
where the last ? shows that the filename can indeed be omitted.

So just don't put it there, and it won't be fixed to any value.

I'd still advise you to post a broader description of your problem (why, and how are you generating perl code?) because it somehow seems like you're doing something wrong (reading from and writing to files without being able to track line numbers shouldn't happen with Perl). Are you sure you can't just have your additions to the code in separate files and do them, to let Perl keep track of files and lines for you?

Replies are listed 'Best First'.
Re^2: Reset the effect of #line
by Anonymous Monk on Aug 25, 2013 at 23:27 UTC

    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?

      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.