Running multiple scripts

D

Dave Saville

I have a commercial program. The author has provided "hooks" at
various points in the program. The "hook" code can be written in
anything. Most of mine are perl but there is a problem in that I
actually want to run more than one script per hook.

At present I have a master script per hook that runs the required
scripts. But performance wise I am (re)loading the perl interpreter
every script. All scripts take the same two parameters and it is not
practical to combine them into one as they may be used by themselves
or in more than one hook.

Is there some cunning way I can invoke a perl script from inside
another without turning it into a function/package? Remember I need to
use them standalone too.

I was thinking, without any real knowledge, if I could do something
like the following although I don't know how I would pass the
parameters.

use strict;
use warnings;
my $parm1 = shift;
my $parm2 = shift;
my $HANDLE;
open $HANDLE, "somecode.pl";
undef $/;
my $stuff = <$HANDLE>;
close $HANDLE;
eval $stuff;

All pointers gratefully received.
 
D

Dave Saville

<snip>

A bit of Googling turns up "do" which is yet another perl thing I
didn't know about :) But although it works once I don't get control
back if the invoked script does not fail.

do 'script1.pl';
print "hello";
do 'script2.pl';

Never says "hello" unless script1 dies.
 
P

Peter J. Holzer

I have a commercial program. The author has provided "hooks" at
various points in the program. The "hook" code can be written in
anything. Most of mine are perl but there is a problem in that I
actually want to run more than one script per hook.

At present I have a master script per hook that runs the required
scripts. But performance wise I am (re)loading the perl interpreter
every script. All scripts take the same two parameters and it is not
practical to combine them into one as they may be used by themselves
or in more than one hook.

Is there some cunning way I can invoke a perl script from inside
another without turning it into a function/package? Remember I need to
use them standalone too.

I was thinking, without any real knowledge, if I could do something
like the following although I don't know how I would pass the
parameters.

use strict;
use warnings;
my $parm1 = shift;
my $parm2 = shift;
my $HANDLE;
open $HANDLE, "somecode.pl";
undef $/;
my $stuff = <$HANDLE>;
close $HANDLE;
eval $stuff;

Yes, that would work.

However, there is already a perl-builtin for the open...eval part. It is
called "do EXPR".

And then there is a builtin which calls "do" and does a couple of other
things, which is called "require".

And then there is a builtin which calls "require" and does a couple of
other things, which is called "use".

So pretty soon we arrive at the standard Perl mechanism for using
libraries, which is what you should have thought of in the first place
if you wanted to reuse code.

So I would put all my hooks into one or more .pm files and then write
mini-scripts like this:

#!/usr/bin/perl
use strict;
use warnings;
use CommercialApp::Hooks1 qw(hook1a hook1b);
use CommercialApp::Hooks2 qw(hook2a);

hook1a(@ARGV);
hook1b(@ARGV);
hook2a(@ARGV);
__END__

or for the simple case:

#!/usr/bin/perl
use strict;
use warnings;
use CommercialApp::Hooks1 qw(hook1b);

hook1b(@ARGV);
__END__

(I might even omit the strictures and warnings in this case ...)

hp
 
W

Willem

Dave Saville wrote:
) On Sat, 7 Apr 2012 11:59:39 UTC, "Dave Saville" <[email protected]>
) wrote:
)
)<snip>
)
) A bit of Googling turns up "do" which is yet another perl thing I
) didn't know about :) But although it works once I don't get control
) back if the invoked script does not fail.

The script you called probably has an 'exit' in there somewhere, which
causes your master script to exit.

) do 'script1.pl';
) print "hello";
) do 'script2.pl';
)
) Never says "hello" unless script1 dies.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
D

Dave Saville

Dave Saville wrote:
) On Sat, 7 Apr 2012 11:59:39 UTC, "Dave Saville" <[email protected]>
) wrote:
)
)<snip>
)
) A bit of Googling turns up "do" which is yet another perl thing I
) didn't know about :) But although it works once I don't get control
) back if the invoked script does not fail.

The script you called probably has an 'exit' in there somewhere, which
causes your master script to exit.

You are correct - I had just figured it out. Bother as I need multiple
return values and "exit value" was the easy way and as it's a "main"
script it won't let me use "return value" :-(

So a complete restructure to exit at the end of the program by
assigning the return code required to another variable as the last
statement rather than short circuiting (and reducing the indentation
{}'s ) by sticking an "exit n" on an conditional in the middle.

Or, following Willem's advice, rewriting the lot as .pm's - which I
wanted to avoid as that flies in the face of needing to be able to use
the scripts individually.
 
T

Tim McDaniel

You are correct - I had just figured it out. Bother as I need multiple
return values and "exit value" was the easy way and as it's a "main"
script it won't let me use "return value" :-(

Well, it's possible to get halfway there by wrapping the top-level
code (the stuff outside any sub bodies) in
sub init {
}
Then you can do a "return". But that's only halfway, ...
So a complete restructure to exit at the end of the program by
assigning the return code required to another variable as the last
statement

.... because main programs don't work the way subs work: as "man
perlrun" says as of Perl 5.14:

If the program runs off the end without hitting an exit() or die()
operator, an implicit exit(0) is provided to indicate successful
completion.

Unless you're running these scripts hundreds of times per second, or
the machine is really old and slow, I'd suck it up and just invoke
them as regular programs. Except in those cases, any inefficiency
would be insignificant. "Micro-optimization leads to micro-results".

Or follow Peter J. Holzer's advice in the other direct reply to you
and put the guts into real libraries.

Or, if you still want the current structure, then (untested) in each
of the standalone scripts, head each with
package SomethingUniqueToThisFile;
to try to reduce the global namespace pollution, and invoke them as
(untested)
eval {
local @ARGV = (...);
do "the_script";
};
and also check its exit status, $@, and $!, as mentioned in the do doc
in perlfunc.

But each script can still pollute the global namespace. If one of
them sets $|, say, or some other special variable, your caller and
everything it calls afterwards will see it.
 
U

Uri Guttman

DS> Or, following Willem's advice, rewriting the lot as .pm's - which I
DS> wanted to avoid as that flies in the face of needing to be able to use
DS> the scripts individually.

there are at least two easy ways to do that. first, make module files
and then also make some very short wrapper scripts that load and run
them. then you can call the modules from other programs or run them
standalone from the wrappers. that is how i would go about it. the other
way is to make the module files both loadable and executable. you can
tell if the module was loaded by checking caller (a top level script
will not have any caller data). so put the main line code in an if block
checking caller. this code is the same as the wrapper script i mentioned
before. here is some pseudo code for that:

package Foo ;

use base Exporter ;
our @EXPORT = qw( my_module_code ) ;

unless ( caller() ) {

# you can mung @ARGV first if needed

my_module_code( @ARGV ) ;

explicit exit since i like them. no harm with this one

exit() ;
}

sub my_module_code {

# your stuff here
}

1 ;


uri
 
D

Dave Saville

<snip>

When I started looking deeoer it turned out that sorting the "exits"
out was not that hard after all.

I now have it working with "do" and the scripts can still be used
standalone. Result :)

Thank you all for your advice.
 

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,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top