http://www.perlmonks.org?node_id=904871

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

Hi I am new in perl, was wondering how i can pass array reference from one perl file to other, I am able to pass complete array from one file to other sucessfully but when i pass the array reference it fails E.g. I am passing array from test-1.pl to test-2.pl

#test-1.pl

my @array = (1,2,3,4,5);

my $test = \@array;

open (FILE, "| ./test-2.pl");

print FILE "$test";

close (FILE);

#...............close...........

#test-2.pl

foreach (<>) {

$temp = $_;

}

print "array = @$temp";

#.................. close............

Error : "Can't use string ("ARRAY(0x26158c0)") as an ARRAY ref while "strict refs" in use"

Any suggestion ...?

  • Comment on How to pass array as a reference from one perl file to other

Replies are listed 'Best First'.
Re: How to pass array as a reference from one perl file to other
by moritz (Cardinal) on May 14, 2011 at 19:45 UTC

    In short, you don't. The array is in the memory of the first perl process, and the second one can't access it - the operating system is very protective about process memory spaces.

    So you need some kind of serialization and deserialization, for example with JSON. You can convert the array to a JSON string, pass it to the second program, and there turn it back into a Perl array.

Re: How to pass array as a reference from one perl file to other
by PyrexKidd (Monk) on May 14, 2011 at 21:41 UTC
    As the previous replier stated you can't. You pass a list of -values- (by value) to your second script. You CAN pass an array by values (unroll it), pass the values, then roll it back up as an array. i.e.:
    #!/usr/bin/perl # test1.pl use strict; use warnings; my $array = ( 1, 2, 3, 4); open my $FH, '| ./test2.pl'; print $FH @{$array}; close $FH; #!/usr/bin/perl # test2.pl use strict; use warnings; while (my $var = <>){ print $var; }

    However, it is safer to use exec or system then using the two argument open method for opening a file handle. i.e.:

    #!/usr/bin/perl # test1.pl use strict; use warnings; my $array = ( 1, 2, 3, 4); my $program = 'test2.pl'; exec { $program } @{$array}; #!/usr/bin/perl # test2.pl use strict; use warnings; print "$_ " foreach @ARGV;
    an aside:
    `exec` can be written: exec { $program } @{$array}; exec $program, @{$array}; exec { './test2.pl' } @{$array}; exec './test2.pl', @{$array}; exec './test2.pl', 1, 2, 3, 4;

    That being said, you may want to investigate modules as this is probably more along the lines of what you are looking for. (I could be way off about the modules, but in general, every time I've wanted to call an external -Perl- script, I've been able to solve my problem more effectively by writing a module that I then import; as you haven't provided any details about the context in which you are attempting to call this external script, I could be wrong.)

      You have a typo: my $array = ( 1, 2, 3, 4); should be my $array = [ 1, 2, 3, 4 ];
      I am explaning my function below. I am using perl tk application to extract user input from this main program and pass the arguments from the user to child program where it connect to database and perform query. The child program after performing the query should pass the result to the parent module. I need some suggestion on how to perform an two way communication between 2 perl programs where each program can chnage it control from each other

      saw some tips from text books on 2 way communication via use IO::Handle but its very hard to grasp its concept

      okke The use of moudle worked....but still a curious to know how to transfer data to and from two files in perl via pipes or other mehtod. I am confused on below text book e.g.

      use IO::Handle;

      pipe(READFROMCHILD.WRITEFROMCHILD);

      pipe(READFROMPARENT,WRITETOCHILD);

      WRITETOPARENT->autoflush(1);

      if ($pid ==fork) {

      close(READFROMPARENT);

      close(WRITETOPARENT);

      print WRITETOCHILD "parent says hi\n";

      $data = <READFROMCHILD>;

      close READFROMCHILD;

      close WRITETOCHILD;

      waitpid(-1,0); }

Re: How to pass array as a reference from one perl file to other
by John M. Dlugosz (Monsignor) on May 15, 2011 at 04:46 UTC
    I would agree with the second reply, that in this example your test-2.pl should be loaded to become part of the same program, not run as a separate process.

    But maybe the example is easier than the real problem? If it's an existing program or a real mess and you can't alter it, you need some kind if Inter-Process Communication. But if you can't alter the existing program, you can't make it do that... so how is program 2 expecting the data already? Maybe you simply wanted to pass the contents of the array as individual arguments.

    But you are also using the pipe-to form, so will program 2 be reading from standard input?

    Without the pipe behavior, you can write:

    system ("./test-2.pl", @$test);
    And have test-2 see the values as the contents of @ARGV.

    If you really do want to pass the data via standard input and the pipe, then your print statement would be: print FILE (join "\n",@$test); that is, write the contents of the array one value per line, which is how your existing test-2 is reading it.



    Edited for correction

      I am explaning my function below.

      I am using perl tk application to extract user input from this main program and pass the arguments from the user to child program where it connect to database and perform query.

      The child program after performing the query should pass the result to the parent module.

      I need some suggestion on how to perform an two way communication between 2 perl programs where each program can chnage it control from each other saw some tips from text books on 2 way communication via use IO::Handle but its very hard to grasp its concept

      system ("./test-2.pl", @$test);
      And have test-2 see the values as the contents of @_.
      No, the values are in @ARGV.