0

How to use 'do' on a Perl script and avoid multiple subroutine definitions?

I'm trying to call a Perl script from another Perl script. The way I'm accomplishing this is the following:

 local @ARGV = (
   $arg1,
   $arg2
 );
 do 'perl_script.pl';

The reason I'm using 'do' instead of using 'system()' is that this old codebase involves calling multiple Perl scripts which in turn are calling multiple Perl scripts (Now of course I could refactor everything into Perl modules but that is not worth it at this point).

Using 'do' instead of 'system()' allows easier debugging with the '-d' flag and avoids unnecessary system calls. The problem I'm running into is that 'do' will fail if calling the same perl scripts more than once because the Perl scripts have subroutines defined in them, and calling the script more than once leaves me with 'subroutine redefined' errors.

Is there another way to do this besides 'do' or some way to ignore subroutines that are redefined?

2 Answers 2

2

It sounds like you know this is an ugly setup, so I'll skip going into depth on it. You could use a scoped no warnings in your running block:

{
    no warnings 'redefine';
    local @ARGV = (
       $arg1,
       $arg2
    );
    do 'perl_script.pl';
}
Sign up to request clarification or add additional context in comments.

2 Comments

I just tried this. And I suspect the reason it doesn't work is that perl_script.pl has a 'use warnings;' clause in it. So I suppose the workaround would be to comment out the use warnings in the my other perl scripts
I wouldn't reccommend uncommenting use warnings. On looking: perldoc.perl.org/perllexwarn.html - '... the scope of the warning pragma is limited to the enclosing block. It also means that the pragma setting will not leak across files (via use, require or do.)' Either set the consumed code to 'use warnings; no warnings "redefine";' or make them modules (it's /really/ not that hard.)
0

If you don't have a problem editing the files you are calling, then a quick somehow dirty solution can be to define different namespaces for each script:

package script1; # From this point, the current namespace is script1
use warnings;
use strict;

... # some code

sub some_sub {
    ...
}

That way, if another script defines some_sub, it won't be considered redefined as it's in a different namespace. This could also prevent scripts from poluting the execution of the rest of the scripts with global variables or other definitions that might cause unexpected results.

Again, this is far from optimal or good practice (not the fact of defining namespaces, but defining them arbitrarily just to isolate things quickly, since you might duplicate code that could be reused in an organized scheme). It's just an idea that might help you get this working quickly.

HTH

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.