Haritz
Haritz

Reputation: 1752

Passing hash reference as an argument to perl script from perl script

I want to pass a hash reference as an argument from one perl script (script1.pl) to another perl script (script2.pl). This is how my code looks:

----------------------------script1.pl---------------------------------

#!/usr/bin/perl -w

use strict;
use warnings;

my %hash = (
'a'      => "Harsha",
'b'      => "Manager"
);

my $ref = \%hash;

system "perl script2.pl $ref";

----------------------------script2.pl---------------------------------

#!/usr/bin/perl -w

use strict;
use warnings;

my %hash = %{$ARGV[0]};

my $string = "a";

if (exists($hash{$string})){
    print "$string = $hash{$string}\n";
}

And this is the output error:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `perl script2.pl HASH(0x8fbed0)'

I can't figure out the right way to pass the reference.

Upvotes: 1

Views: 2572

Answers (4)

Mukesh Bhoj
Mukesh Bhoj

Reputation: 21

Your way of calling perl file is wrong. Just change the way of calling it and you are done.

Script1.pl
---------------------------------

#!/usr/bin/perl -w

use strict;
use warnings;

my %hash = (
    'a'      => "Harsha",
    'b'      => "Manager"
);

system("perl","script2.pl",%hash);

Use this %hash in another perl script as shown below.

Script2.pl
----------------------------------

#!/usr/bin/perl -w

use strict;
use warnings;

my %hash = @ARGV;

my $string = "a";

if (exists($hash{$string})){
    print "$string = $hash{$string}\n";
}

OutPut is

a = Harsha

Upvotes: -2

Chankey Pathak
Chankey Pathak

Reputation: 21666

Use Storable to store data in first script and retrieve it from other.

firstscript.pl

store (\%hash, "/home/chankey/secondscript.$$") or die "could not store";
  system("perl", "secondscript.pl", $$) == 0 or die "error";

secondscript.pl

my $parentpid = shift;
my $ref = retrieve("/home/chankey/secondscript.$parentpid") or die "couldn't retrieve";
print Dumper $ref;

You've received the %hash in $ref. Now use it the way you want.

Upvotes: 1

Sobrique
Sobrique

Reputation: 53478

A hash is an in memory data structure. Processes 'own' their own memory space, and other processes can't just access it. If you think about it, I'm sure you'll spot why quite quickly.

A hash reference is an address of that memory location. Even if the other process could 'understand' it, it still wouldn't be able to access the memory space.

What we're talking about here is actually quite a big concept - Inter Process Communication or IPC - so much so there's a whole chapter of the documentation about it, called perlipc.

The long and short of it is this - you can't do what you're trying to do. Sharing memory between processes is much more difficult than you imagine.

What you can do is transfer the data back and forth - not by reference, but the actual information contained.

I would suggest that for your example, the tool for the job is JSON, because then you can encode and decode your hash:

#!/usr/bin/perl -w

use strict;
use warnings;

use JSON;

my %hash = (
    'a' => "Harsha",
    'b' => "Manager"
);

my $json_string = to_json( \%hash );

print $json_string;

This gives:

{"b":"Manager","a":"Harsha"}

Then your can 'pass' your $json_string - either on the command line, although bear in mind that any spaces in it confuses @ARGV a bit if you're not careful - or via STDIN.

And then decode in your sub process:

use strict;
use warnings;

use JSON;

my $json_string = '{"b":"Manager","a":"Harsha"}';

my $json = from_json ( $json_string );

my $string = "a";

if (exists($json -> {$string} )){
    print "$string = ",$json -> {$string},"\n";
}

(You can make it more similar to your code by doing:

my $json = from_json ( $json_string );
my %hash = %$json;

Other options would be:

  • use Storable - either freezing and thawing ( memory) or storing and retrieving (disk)
  • use IPC::Open2 and send data on STDIN.

There's a variety of options really - have a look at perlipc. But it's not as simple a matter as 'just passing a reference' unfortunately.

Upvotes: 9

Alnitak
Alnitak

Reputation: 339816

You can't pass a reference from one script to another - that reference only has meaning within the currently running instance of perl.

You would need to "serialise" the data in the first script, and then "deserialise" it in the second.

Upvotes: 0

Related Questions