开发者

What's the purpose of perl's #line directives?

开发者 https://www.devze.com 2022-12-22 23:58 出处:网络
Line directives (#line) a开发者_运维知识库re used to reconfigure perl\'s idea of the current filename and line number. When is this required to get right filename and line number (in an error message)

Line directives (#line) a开发者_运维知识库re used to reconfigure perl's idea of the current filename and line number. When is this required to get right filename and line number (in an error message)?


Usually such markers are put into code that has been pre-processed or mechanically generated in order to refer back to the human-generated source.

For example, if there was a program that converted Python to Perl, it might insert a

# line 812 "foo.py"

so that error messages would refer to the original Python code which would make more sense to the programmer.


They're useful when wrapping a Perl script in another file, like pl2bat does. Perl doesn't see the batch commands at the beginning of the file which throws off its idea of line numbers. A #line directive at the beginning of the Perl source compensates for this.


I've seen several times that people incorrectly write the current line's number into the #line directive. It should contain the next line's number. Example code of linetest.pl (using a ksh wrapper to set an environment variable for the perl script):

1  #!/usr/bin/ksh
2  MY_ENV_VAR='something'
3  export MY_ENV_VAR
4  /usr/bin/perl -x $0 $@ 2>&1
5  exit $?
6
7  #!/usr/bin/perl
8  #line 9
9  print "MY_ENV_VAR is $ENV{MY_ENV_VAR}\n";
10 die "This is line 10.";

Run the script and check the result:

$ ./linetest.pl
MY_ENV_VAR is something
This is line 10. at ./linetest.pl line 10.

You can see that line numbers are matching after writing #line 9 on line 8.


In addition to the already mentioned reasons perl has a (strongly discouraged) -P option that runs the Perl file through a C preprocessor before it is executed. Since most C preprocessor's will use line directives when they include or remove part of a file so any errors will be reported from where they were located in the original source instead of the processed source.

Line directives can also be very useful if you are generating code in strings that is then passed to eval. Normally if there is a warning or error in such code you get an error reported like "died at (eval 1) line 1." Using line directives you can supply a useful file name and line number.


The #line directive is also very helpful when doing perl -e in a shell script. I write

perl -e '#line X
more perl code here...
'

where X is the current shell script line +1 so that any Perl errors tell me the shell line where the failed Perl statement is.

0

精彩评论

暂无评论...
验证码 换一张
取 消