counting perl src when have nested requires?

S

Sherm Pendley

Ted said:
I've inherited a perl program and libs which have extremely
nested series of "require" statements. ....
Is there any way to --->count the lines of perl src<---
by inserting some sort of magic statement right after
the "main()" line in the master file, "foo.pl"?

You can get a list of all the files that have been included with use(),
require(), or do() from the special hash %INC. The keys are the values as
given in your script(s), and the values are the actual paths at which the
files were found.

So, in the simplest case, it could be as simple as this:

system("wc -l " . join(' ', values(%INC)));

Like I said, that's the simple case - obviously, if there are spaces or
other funky stuff in the paths to these files, you'll need to deal with
that by escaping them properly before executing the "wc -l" shell command.
I'll leave that as an exercise for the reader. :)

sherm--
 
T

Ted Johnson

I've inherited a perl program and libs which have extremely
nested series of "require" statements.

For example, in the main file, "foo.pl" we have:
#!/usr/bin/perl
require "lib1.pl";
require "lib2.pl";
require "lib3.pl";
...

# main() routine starts here...


But each of the libs in turn "require" other libs, eg,
"lib1.pl" has:
require "sublib11.pl";
require "sublib22.pl";
require "sublib33.pl";
...

And each sublib in turn "require"s yet more sublibs, eg,
"sublib11.pl" has:
require "sublib111.pl";
require "sublib429.pl";
require "sublib937.pl";

Is there any way to --->count the lines of perl src<---
by inserting some sort of magic statement right after
the "main()" line in the master file, "foo.pl"?

Thanks in advance!
-Ted
 
A

Anno Siegel

What "main()" line? Perl isn't C.
You can get a list of all the files that have been included with use(),
require(), or do() from the special hash %INC. The keys are the values as
given in your script(s), and the values are the actual paths at which the
files were found.

So, in the simplest case, it could be as simple as this:

system("wc -l " . join(' ', values(%INC)));

A solid approach, but it will report all modules loaded anywhere in the
program (up to the point where %INC is evaluated). The OP seems to be
interested in the modules loaded directly or indirectly by one specific
"use" statement.

To make it selective that way (and to add a little magic) I propose
this:

END {
my @report_these; # collect modules to report
sub report_loading {
push @report_these, $_[ 1];
return; # undef, so search continues
}
# Line counting left as an exercise
print "$_ => $INC{ $_}\n" for @report_these;
}

use Some::Stuff;

use lib \ &report_loading;
use Nested::Module;
no lib \ &report_loading;

use Other::Stuff;

The END block will only report what has been loaded between the "use lib ..."
and "no lib ..." statements. More pairs could be added.

This makes use of the fact that you can put a code object on @INC that will
be called when a module is loaded. The feature is described with "require".

Anno
 
B

Brian McCauley

Anno said:
Sherm Pendley said:
So, in the simplest case, it could be as simple as this:

system("wc -l " . join(' ', values(%INC)));


A solid approach, but it will report all modules loaded anywhere in the
program (up to the point where %INC is evaluated). The OP seems to be
interested in the modules loaded directly or indirectly by one specific
"use" statement.

To make it selective that way (and to add a little magic) I propose
this:

END {
my @report_these; # collect modules to report
sub report_loading {
push @report_these, $_[ 1];
return; # undef, so search continues
}
# Line counting left as an exercise
print "$_ => $INC{ $_}\n" for @report_these;
}

use Some::Stuff;

use lib \ &report_loading;
use Nested::Module;
no lib \ &report_loading;

Er, why not simply compare %INC before and after?
 
B

Brian McCauley

Sherm said:
system("wc -l " . join(' ', values(%INC)));

That, of course counts the total number of lines, not just Perl source
which could be significantly less where the file contains __DATA__ or
__END__. Also it's debatable if lines of POD before the __END__ should
be considered "lines of perl source".
 
A

Anno Siegel

Brian McCauley said:
Anno said:
Sherm Pendley said:
So, in the simplest case, it could be as simple as this:

system("wc -l " . join(' ', values(%INC)));


A solid approach, but it will report all modules loaded anywhere in the
program (up to the point where %INC is evaluated). The OP seems to be
interested in the modules loaded directly or indirectly by one specific
"use" statement.

To make it selective that way (and to add a little magic) I propose
this:

END {
my @report_these; # collect modules to report
sub report_loading {
push @report_these, $_[ 1];
return; # undef, so search continues
}
# Line counting left as an exercise
print "$_ => $INC{ $_}\n" for @report_these;
}

use Some::Stuff;

use lib \ &report_loading;
use Nested::Module;
no lib \ &report_loading;

Er, why not simply compare %INC before and after?

Good idea, now you mention it :)

It's conceptually simpler than making use of the obscure behavior of
coderefs on @INC. It may take a little more code to implement.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top