2

I need some help with reading value assigned inside sub scripts executed within main script in perl

  1. I have "main.pl" where i have few hashes (%var1 %var2) declared and assigned and am processing the values throughout the script.
  2. Within main.pl, i execute a perl script "sub_scirpt.pl" using system(perl sub_script.pl)
  3. Inside sub.pl, if i am assigning few value to %var1 %var2
  4. How do i print the values assigned in sub_script.pl of %var1 at main.pl script level?

Hope the above description gives some picture on my requirement.

content of sub_script.pl

our %var1 ; 
our $var1 = "start";
our $var2 = "abcd";
our $var3 = "efgh";
our @var4 = qw{test1 test2 test3};

$var1{$var2}{$var3}->{test1} = "1234";
$var1{$var2}{$var3}->{test2} = "5679";
$var1{$var2}{$var3}->{test3} = "5555";

foreach $var (@var4) {
    print "sub_script:: var1: $var1 \nsub_script:: var2: $var2  \nsub_script:: var3: $var3 \nsub_script:: var4: $var   \nsub_script:: hash-value: $var1{$var2}{$var3}->{$var}\n";
}

Output of sub_script.pl:

sub_script:: var1: start 
sub_script:: var2: abcd  
sub_script:: var3: efgh 
sub_script:: var4: test1   
sub_script:: hash-value: 1234
sub_script:: var1: start 
sub_script:: var2: abcd  
sub_script:: var3: efgh 
sub_script:: var4: test2   
sub_script:: hash-value: 5679
sub_script:: var1: start 
sub_script:: var2: abcd  
sub_script:: var3: efgh 
sub_script:: var4: test3   
sub_script:: hash-value: 5555

content of main.pl

@var1 = qw{start end};
$var1 = @var1[1];
our $var2  = "abcd";
our $var3  = "efgh";
@var4 = qw{test1 test2 test3};

system ("perl sub_script.pl");

print "\n\n";
foreach $var (@var4) {
    print "main:: var1: $var1 \nmain:: var2: $var2  \nmain:: var3: $var3 \nmain:: var4: $var   \nmain::hash-value:$var1{$var2}{$var3}->{$var}\n";
}

Output of main.pl:

main:: var1: end 
main:: var2: abcd  
main:: var3: efgh 
main:: var4: test1   
main:: hash-value:
main:: var1: end 
main:: var2: abcd  
main:: var3: efgh 
main:: var4: test2   
main:: hash-value:
main:: var1: end 
main:: var2: abcd  
main:: var3: efgh 
main:: var4: test3   
main:: hash-value:

Intended output:

main:: var1: start 
main:: var2: abcd  
main:: var3: efgh 
main:: var4: test1   
main:: hash-value: 1234
main:: var1: start 
main:: var2: abcd  
main:: var3: efgh 
main:: var4: test2   
main:: hash-value: 5679
main:: var1: start 
main:: var2: abcd  
main:: var3: efgh 
main:: var4: test3   
main:: hash-value: 5555

-Thanks in advance

15
  • 4
    Important: please provide code, instead of a description which is very difficult to work with. (Isn't it also easier?) In short: you start and run a separate program (sub.pl), and what happens in it is completely separate from the "main" script. So that program needs to pass the data back to the "main" script, and there is a number of ways to do so. But we need to see more of what you are doing and how, to be able to say more Commented Jun 6, 2020 at 10:49
  • 1
    metacpan.org/pod/IPC::Shareable Commented Jun 6, 2020 at 16:14
  • @zdim My bad, should have included it at first place, didnt know how to update in comment, so edited the main post with more details. Hope its much clear now. Commented Jun 6, 2020 at 19:36
  • Why do you run two scripts in separate processes? Can't you just have one script and use the other? Commented Jun 6, 2020 at 19:41
  • @Robert, i just showed this small snippet as an example to have the issue explained better, actual script does few more processing inside sub_script.pl, which i dont want to clutter main.pl (some 500line code to process few logfiles) with, and i just want the few subset of values to be used in main.pl Commented Jun 6, 2020 at 21:35

1 Answer 1

4

In short, you need to pass data from a program back to the program that invoked it.

If the called program (sub_script.pl) needs to return only simple values then it can just print them to STDOUT, where the calling program (main.pl) runs it via "backticks" (qx in the operator form), which returns the program's STDOUT.

However, more complex data structures need be serialized so that they can be meaningfully sent down a pipe (of some kind) byte by byte. There are various ways to do so, with good libraries, and simple code below demonstrates two of them.

The JSON format is very simple, human readable, and accessible from any language and system. Perl libraries for conversion between Perl data structures and corresponding JSON are very simple to use. This is a good and safe solution for a wide range of situations.

Perl's Storable is a tool for persistency, so that complex data structures can be dumped to disk and later restored from the file. One can also serialize data to strings that can be passed between programs with no need for files.

The program sub_script.pl below creates a hash and makes a JSON string out of it and prints it, and then also serializes the hash into a Storable string which it also prints

use warnings;
use strict;
use feature 'say';

use JSON;
use Storable qw(nfreeze);

my %h = (a => { A => 1}, b => { B => 2 }); 

my $str_json = encode_json \%h;
say $str_json;

my $str_st = nfreeze \%h;
say $str_st;

The following program (main.pl) runs the sub_script.pl above using qx so that it receives its STDOUT, and then it rebuilds the hash from both the JSON and Storable strings. In both cases we get back a hashref, a reference to data like the original hash

use warnings;
use strict;
use feature 'say';

use JSON;
use Storable qw(thaw);

use Data::Dump qw(dd);

my @ret = qx( sub_script.pl );
chomp @ret;

my $hr1 = decode_json $ret[0];
dd $hr1;

my $hr2 = thaw $ret[1];
dd $hr2;

I use JSON for simplicity, which will use the fast JSON_XS if installed, or the pure-Perl fallback, the core JSON_PP. Another option is Cpanel::JSON::XS, a fork of JSON_XS.

To print complex data structures so to see them easily I use Data::Dump, which probably need be installed. There is a number of other good modules to show complex data, the most widely used one being the core Data::Dumper (so no need to install).


In all of this, the program that is called still just prints to its STDOUT. When data exchange needs get more complex you may need to use some "Inter-Process-Communication" (IPC) techniques.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.