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

It is said in the Holy Books that the only program that can correctly parse Perl is Perl itself. I have taken this teaching to heart and have written a twisted little Perl tags generator (like ctags) that does not attempt to parse the Perl text itself. I have put it in Craft here. Instead, it runs as a Perl debugger, which gives it access to the tables of symbols and line numbers that debuggers have access to. And it works quite well.
Except for one thing: anything in a BEGIN (or probably also INIT) block gets run. If these blocks print to STDOUT they mess up the tags file.
Now I guess I could just use another file handle to write to and hope that the BEGIN blocks don't have nasty side effects, but does anyone know how I can gain control before the BEGIN blocks run? (I've tried adding the line
BEGIN { $DB::single=1 }
to the end of the PERL5DB env var but it didn't help)

Replies are listed 'Best First'.
(tye)Re: Preventing BEGIN blocks from being run in the debugger?
by tye (Sage) on May 25, 2001 at 19:03 UTC

    "perldoc perldebug" says:

    Debugging compile-time statements

    If you have compile-time executable statements (such as code within BEGIN and CHECK blocks or use statements), these will not be stopped by debugger, although requires and INIT blocks will, and compile-time statements can be traced with AutoTrace option set in PERLDB_OPTS). From your own Perl code, however, you can transfer control back to the debugger using the following statement, which is harmless if the debugger is not running:

    $DB::single = 1;

    So it seems you were close but you need to put that BEGIN block in your source code and not in PERL5DB environment variable. (Though I haven't tried this.)

            - tye (but my friends call me "Tye")
      But this is a perl tags utility; I can't edit the source code.
      In perldebguts, though, it says that the contents of PERL5DB will be inserted at the beginning of the program being debugged. Which is the same as putting it in the source code. And, in fact, had I not misspelled $DB::begin, it would have worked. However, it doesn't do what I want: if you break in a BEGIN block, the line number arrays aren't yet set up, so the tags utility won't work. Oh well...
Re: Preventing BEGIN blocks from being run in the debugger?
by AidanLee (Chaplain) on May 25, 2001 at 06:50 UTC
    You best bet may actually be to have your own begin block that copies STDOUT to another handle, and then close the normal STDOUT. You can then print to your special STDOUT handle and none of the other begin blocks will have a chance (I hope?) to mess up your output.

    correct me if i'm wrong....this is a stab in the dark...

      That would probably work for the output, though bikeNomad mentioned that he could just use another filehandle for the output. It wouldn't, however, work for the side-effects, which I gathered to be the greater of the two problems.

      Unfortunately, I don't think that there's any way to stop the BEGIN blocks running, short of pre-parsing the file, inserting return() calls as the first instruction in the BEGIN block before loading the modified code into the debugger. Of course, that means that you have to try to parse Perl code yourself, which defeats the original purpose. *shrug* And, of course, that doesn't even come close to handling things like use.

      But, honestly, for the code to be parsed correctly at all, some compile-time execution is probably unavoidable. Otherwise you wouldn't get your import's set up correctly and all that. Perhaps all one can do is hide any output from the compile-time code and hope for the best. *sigh* Maybe this kind of thing will get easier when Perl 6 comes around.

      Seasons don't fear The Reaper.
      Nor do the wind, the sun, and the rain.
      We can be like they are.