Running multiple scripts

Discussion in 'Perl Misc' started by Dave Saville, Apr 7, 2012.

  1. Dave Saville

    Dave Saville Guest

    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.
    --
    Regards
    Dave Saville
    Dave Saville, Apr 7, 2012
    #1
    1. Advertising

  2. Dave Saville

    Dave Saville Guest

    On Sat, 7 Apr 2012 11:59:39 UTC, "Dave Saville" <>
    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.

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

    Never says "hello" unless script1 dies.
    --
    Regards
    Dave Saville
    Dave Saville, Apr 7, 2012
    #2
    1. Advertising

  3. On 2012-04-07 11:59, Dave Saville <> wrote:
    > 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


    --
    _ | Peter J. Holzer | Deprecating human carelessness and
    |_|_) | Sysadmin WSR | ignorance has no successful track record.
    | | | |
    __/ | http://www.hjp.at/ | -- Bill Code on
    Peter J. Holzer, Apr 7, 2012
    #3
  4. Dave Saville

    Willem Guest

    Dave Saville wrote:
    ) On Sat, 7 Apr 2012 11:59:39 UTC, "Dave Saville" <>
    ) 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
    Willem, Apr 7, 2012
    #4
  5. Dave Saville

    Dave Saville Guest

    On Sat, 7 Apr 2012 13:22:11 UTC, Willem <> wrote:

    > Dave Saville wrote:
    > ) On Sat, 7 Apr 2012 11:59:39 UTC, "Dave Saville" <>
    > ) 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.
    --
    Regards
    Dave Saville
    Dave Saville, Apr 7, 2012
    #5
  6. Dave Saville

    Tim McDaniel Guest

    In article <fV45K0OBJxbE-pn2-qsKzC8oNCHJ7@localhost>,
    Dave Saville <> wrote:
    >On Sat, 7 Apr 2012 13:22:11 UTC, Willem <> wrote:
    >
    >> Dave Saville wrote:
    >> ) On Sat, 7 Apr 2012 11:59:39 UTC, "Dave Saville" <>
    >> ) 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" :-(


    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.

    --
    Tim McDaniel,
    Tim McDaniel, Apr 7, 2012
    #6
  7. Dave Saville

    Uri Guttman Guest

    >>>>> "DS" == Dave Saville <> writes:

    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
    Uri Guttman, Apr 7, 2012
    #7
  8. Dave Saville

    Dave Saville Guest

    <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.

    --
    Regards
    Dave Saville
    Dave Saville, Apr 7, 2012
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jan Danielsson
    Replies:
    8
    Views:
    613
    Mike Meyer
    Jul 22, 2005
  2. Jp Calderone
    Replies:
    0
    Views:
    445
    Jp Calderone
    Jul 21, 2005
  3. davidj411
    Replies:
    0
    Views:
    483
    davidj411
    Jun 27, 2008
  4. Earle Clubb
    Replies:
    3
    Views:
    119
    Brian Candler
    Jun 2, 2007
  5. Replies:
    13
    Views:
    516
    Anno Siegel
    Sep 10, 2007
Loading...

Share This Page