How can I warn about the use of functions in `perl -c`?

Our code contains various debug hooks which should be used only for testing. As an illustrative example:

sub example { my ($arg) = @_; my $result = do_something_with($arg); debug_dump_values($arg); # debugging code return $result; } 

Of course, such debugging code does not have to be perfect (or even deployed). Is there a way to generate a warning when you run this code via perl -c ? Something along the lines

 Debug function debug_dump_values() called at example.pl line 4. 

This would be trivial to implement as a warning at runtime:

 sub debug_dump_values { carp "Debug function debug_dump_values() called"; ... } 

But I want to get a warning that appears in my text editor through a syntax check plugin, so it should be a "compile time" warning.

+5
source share
3 answers

I think this is not an easy task - it will not be possible without any significant revision of the coding style.

Approaches I can think of:

Put your debug code in a separate module.

Insert a warning into a module that indicates that it is enabled - embed in the "BEGIN" block. (This will not necessarily tell you which sub-call is called, and where)

eg.

 BEGIN { carp "Debugging module is imported" } 

The advantages of this may be: you can have a module "debug" and "not debug", as well as the same subtitles in both. "Not debugging" will be placed in dummy subtitles.

Then you can use B::Lint to check your module and check if subkeys are defined:

perl -MO=Lint[,OPTIONS] foo.pl

undefined-subs This option warns whenever an undefined subroutine is invoked. This option will only catch explicitly invoked subroutines such as foo() and not indirect invocations such as &$subref() or $obj->meth() . Note that some programs or modules delay definition of subs until runtime by means of the AUTOLOAD mechanism

Assign your substream via the link.

Edit: it doesnโ€™t work as good as I thought - had the concept of declaring anonymous subscribers and creating links in BEGIN blocks - it doesnโ€™t work as good as I thought - it is only runtime errors because you get errors in volume.

The best I can offer is:

 use strict; use warnings; my $debug = 1; ##debug code bit. #Comment out if not needed my $debug_sub = gimme_debug(); sub gimme_debug { if ( $debug ) { warn "Debugging enabled\n"; return sub { print "Got values of :", @_, "\n"; }; } else { warn "Debug subroutine defined with debug disabled!" }; } #... way down code ... &$debug_sub ( "Some input" ); 

If you remove the declaration, you will get a compile-time warning because $debug_sub not declared. This can be combined with the above, for example, linking it in a module or object.

Automated Testing

It does not specifically do what you asked for, but you can still consider it. Automatic testing of your code / modules. For example, using TAP::Harness . This is a little more complicated and more intense than you ask, but having something that automatically delays the debugging code (and otherwise checks the various components of your code) is probably the โ€œrightโ€ way to do this.

I also heard (but not really done much) Class::Inspector , which may be suitable for your needs. But I think that at a fairly fundamental level, what you are trying to do is not checked at compile time, because it is very difficult to evaluate which bits of code are actually called without actually running the code. So all you do is what you need to "manually manage."

Problem with stop

"In computability theory, the stopping problem is the problem of determining, from a description of an arbitrary computer program and input, whether the program will end or continue to work forever.

Alan Turing proved in 1936 that a general algorithm for solving the stop problem for all possible pairs of program inputs cannot exist. A key part of the proof was the mathematical definition of a computer and a program that became known as a Turing machine; the stopping problem is unsolvable over Turing machines. This is one of the first examples of solving the problem.

So, if you come up with a good solution for this - perhaps a big win will be useful here :).

+1
source

In my development environment, I am facing a similar problem. My approach was to combine debugging code with #ifdef and #endif C-style comments, for example:

 sub example { my ($arg) = @_; my $result = do_something_with($arg); #ifdef DEBUG debug_dump_values($arg); # debugging code #endif return $result; } 

As part of creating the release, the ppp.pl program (which I wrote) runs on each Perl source file and comments on (or deletes) the debugging code. Simple ppp.pl is easy to write. If anyone is interested, I can publish my version in a public place.

0
source

if you used Log :: Log4perl and created a log called $logger , you can check the debugging mode with $logger->is_debug() , which is called by the function only if the debugging level is enabled

then your code could just stay, but only be called when debugging.

t

 sub example { my ($arg) = @_; my $result = do_something_with($arg); debug_dump_values($arg) if $logger->is_debug(); # debugging code return $result; } 
0
source

Source: https://habr.com/ru/post/1206560/


All Articles