Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Passing arguments

by Anonymous Monk
on Jan 28, 2004 at 21:41 UTC ( [id://324792]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi there , can someone tell me how to pass an array to a script as an argument: I am calling another perl script from my perl script and passing it an array as an argument :
#in my calling script system(qq(perl script2.pl @theArray));
#in my reciving script my @RecivedArray; if ($#ARGV != 0) { die " no argument was passed\n"; } @RecivedArray = $ARGV[0];
Can someone tell me what is the problem of the way I am passing the array? thanks

Replies are listed 'Best First'.
Re: Passing arguments
by John M. Dlugosz (Monsignor) on Jan 28, 2004 at 21:50 UTC
Re: Passing arguments
by Roy Johnson (Monsignor) on Jan 28, 2004 at 22:09 UTC
    First, bypass any shell interpolatation to keep your array elements separate in transit:
    system('perl', 'script2.pl', @theArray);
    Then, your second script can just use @ARGV:
    @ReceivedArray = @ARGV;

    The PerlMonk tr/// Advocate
Re: Passing arguments
by Zaxo (Archbishop) on Jan 28, 2004 at 21:56 UTC

    This logic is probably wrong:

    if ($#ARGV != 0) { die " no argument was passed\n"; }
    I think you want to test equality, and the 0 may be wrong. It might help sort this out if you eliminated the shell by calling the list form of system and checking errors, system( '/path/to/perl', '/path/to/script2.pl', @theArray) and die $?, $!;

    After Compline,
    Zaxo

Re: Passing arguments
by blue_cowdawg (Monsignor) on Jan 28, 2004 at 21:57 UTC

        Can someone tell me what is the problem of the way I am passing the array?

    Check out this experiment:

    $ cat argvtest.pl printf "I saw %d arguments\n",$#ARGV+1; #show how many @argsin=@ARGV; # Snarf in the argnuments printf "They were \"%s\"\n",join(",",@argsin); # and what
    a test run shows:
    $ perl argvtest.pl 1 2 3 4 I saw 4 arguments They were "1,2,3,4"
     $#ARGV is the argument count minus one or in other words the last index of the array @ARGV or the list of arguments passed to the script.

    With that in mind your test should look something like:

    if ( $#ARGV < 0 ) { # NOTE: not != 0 printf "I expected an argument not simple refutation\n"; exit(0); }

    UPDATE: Re-reading your original post I picked up on something...

    You tried:

    @RecievedArray=$ARGV[0];
    Since @ARGV is an array of scalars you are just referencing the first element of @ARGV which is itself a scalar and attempting to assign that to an array.

    I set up another experiment just to demonstrate what is going on:

    use Data::Dumper; @ry=qw/ a b c d /; @ry2=$ry[0]; printf "First array:\n"; print Dumper(\@ry); printf "Second array:\n"; print Dumper(\@ry2);
    When that code is run you get the following:
    First array: $VAR1 = [ 'a', 'b', 'c', 'd' ]; Second array: $VAR1 = [ 'a' ];
    As you can see all that gets assigned to the second array is the first element of the first array.

    Hope all this helps.


    Peter L. Berghold -- Unix Professional
    Peter at Berghold dot Net
       Dog trainer, dog agility exhibitor, brewer of fine Belgian style ales. Happiness is a warm, tired, contented dog curled up at your side and a good Belgian ale in your chalice.
Re: Passing arguments
by monktim (Friar) on Jan 28, 2004 at 21:53 UTC
    #in my calling script my @array = ('a','b','c'); system(qq(perl C:\\script2.pl @array)); print "system failed. [$?]: $!" if ($?); #if args contain spaces my @array = ('a 1','b 2','c 3'); my $args; $args .= '"'.$_.'" ' foreach (@array); system(qq/perl C:\\Backup\\script2.pl $args/); print "system failed. [$?]: $!" if ($?); # Script2.pl my @RecivedArray = @ARGV;; print join(',',@RecivedArray);
    Update Added a line of code to check the status of the system call. Also added a block showing arguments that contain spaces.
Re: Passing arguments
by revdiablo (Prior) on Jan 28, 2004 at 21:59 UTC

    To generalize your question, you are looking for a method of Inter-Process Communication. There are many ways to do this, from your method (command line arguments), to a simple text file, to a full blown client-server arrangement. The type of IPC one uses depends on the situation at hand. For lots of documentation on the subject, check out perldoc perlipc.

Re: Passing arguments
by NetWallah (Canon) on Jan 29, 2004 at 05:50 UTC
    As others have suggested, there are several hazards you will encounter when trying to pass parameters using the shell (system call).

    Some of these are:

    • Spaces in data
    • Binary data
    • structured data (AoA or HoA etc)
    • Special chars in data like < ^ >

    For a more general solution, you may want to consider using the storable Module, which can be used thus:

    #In Calling program use Storable; store(\@array, "filename"); # later , in Called program .. $aref = retrieve("filename"); # Get a ref or @array = @{ retrieve("filename") }; # direct into array
    "When you are faced with a dilemma, might as well make dilemmanade. "
Re: Passing arguments
by ysth (Canon) on Jan 28, 2004 at 21:55 UTC
    $#ARGV is the last used index in @ARGV. If @ARGV contains 1 element, $#ARGV will be zero. It's -1 if @ARGV is empty. You should use if (@ARGV) instead.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://324792]
Approved by valdez
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (4)
As of 2024-04-25 07:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found