Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Perl debugger not stop at breakpoints with do, but stops with require?

While using Perl EPIC debugger in Eclipse, Why the execution is not stopping at the Breakpoints in 'do' module, but stops at 'require' module?

script.pl

use strict;

#use sample;         # <-- Execution stops at breakpoint in printMessage() of 'sample.pm'
#require sample;     # <-- Execution stops at breakpoint in printMessage() of 'sample.pm'
#do 'sample.pm';     # <-- Execution DO NOT STOP at breakpoint in printMessage() of 'sample.pm'

sample::printMessage();

sample.pm

package sample;

sub printMessage
{
    print 'new message!';   
}

1;
like image 995
InnovWelt Avatar asked Oct 03 '22 12:10

InnovWelt


1 Answers

I tried this in Komodo IDE and on the command line and got the same results.

If you use or require a file, Perl keeps the file's name in %INC. That makes sure that a file is only loaded once. You can require the same module in many different other modules and use the functions like sample::printMessage(). The first require will be done, and all the others will be ignored because there already is a key $INC{'sample'} = './sample.pm' in %INC.

require sample;
require sample;
require sample;

sample::printMessage();

__END__
new message!

The same applies if you use the module instead of requireing it because use only is a require and an import in a BEGIN block. In both cases, Perl remembers that. My assumption (have not found documentation that proves that) is, that the debugger is able to do the same, or even reads the internal %INC.

Now if you do a file, that %INC mechanism is not triggered, meaning you can do the file over and over. It doesn't care about the file's name. That has the consequence that if you do the file several times, it will complain, even without use warnings.

do 'sample.pm';
do 'sample.pm';
do 'sample.pm';

__END__
Subroutine printMessage redefined at sample.pm line 4.
Subroutine printMessage redefined at sample.pm line 4.
new message!

My guess is that the debugger also does not remember, thus it doesn't know it has loaded sample.pm. The doc says:

Uses the value of EXPR as a filename and executes the contents of the file as a Perl script.

do 'stat.pl';

is largely like

eval `cat stat.pl`;

So it only slurps in the file and executes the content. No %INC. No filename for the debugger (which by the way is the same debugger in EPIC as in Komodo IDE as on the command line, the graphical ones just hook up to the Perl debugger). Because of that, your breakpoint is ignored when the code says do.

If you want your debugger to stop at line 5 in sample.pm even if you do it, you can tell the debugger to do that by adding $DB::single = 1; to the line above.

package sample;

sub printMessage
{
    $DB::single = 1;
    print 'new message!';
}

This is documented in perldebug. It will make the debugger stop at the next line and is equivalent of typing s in the debugger, or clicking the single step button in your EPIC debugger.


See also:

  • perlvar for %INC
  • perldebug for the command line debugger
  • perl5db.pl on CPAN
like image 115
simbabque Avatar answered Oct 13 '22 12:10

simbabque