Pyjava
Pyjava

Reputation: 117

Calling one Perl program from another

I have two Perl files and I want to call one file from another with arguments

First file a.pl

$OUTFILE  = "C://programs/perls/$ARGV[0]";
# this should be some out file created inside work like C://programs/perls/abc.log

Second File abc.pl

require "a.pl" "abc.log";

# $OUTFILE is a variable inside a.pl and want to append current file's name as log.

I want it to create an output file with the name of log as that of current file.

One more constraint I have is to use $OUTFILE in both a.pl and abc.pl.

If there is any better approach please suggest.

Upvotes: 0

Views: 1958

Answers (3)

brian d foy
brian d foy

Reputation: 132812

I would do this another way. Have the program take the name of the log file as a command-line parameter:

% perl a.pl name-of-log-file

Inside a.pl, open that file to append to it then output whatever you like. Now you can run it from many other sorts of places besides another Perl program.

# a.pl
my $log_file = $ARGV[0] // 'default_log_name';
open my $fh, '>>:utf8', $log_file or die ...;
print { $fh } $stuff_to_output;

But, you could also call if from another Perl program. The $^X is the path to the currently running perl and this uses system in the slightly-safer list form:

system $^X, 'a.pl', $name_of_log_file

How you get something into $name_of_log_file is up to you. In your example you already knew the value in your first program.

Upvotes: 2

simbabque
simbabque

Reputation: 54323

The require keyword only takes one argument. That's either a file name or a package name. Your line

require "a.pl" "abc.log";

is wrong. It gives a syntax error along the lines of String found where operator expected.

You can require one .pl file from another .pl, but that is very old-fashioned, badly written Perl code.

If neither file defines a package then the code is implicitly placed in the main package. You can declare a package variable in the outside file and use it in the one that is required.

In abc.pl:

use strict;
use warnings;

# declare a package variable
our $OUTFILE  = "C://programs/perls/filename";

# load and execute the other program
require 'a.pl';

And in a.pl:

use strict;
use warnings;

# do something with $OUTFILE, like use it to open a file handle
print $OUTFILE;

If you run this, it will print

C://programs/perls/filename

Upvotes: 7

m4gic
m4gic

Reputation: 1513

You should convert your perl file you want to call to a perl module:

Hello.pm

#!/usr/bin/perl
package Hello;

use strict;
use warnings;

sub printHello { 
    print "Hello $_[0]\n" 
}
1;

Then you can call it: test.pl

#!/usr/bin/perl

use strict;
use warnings;

# you have to put the current directory to the module search path
use lib (".");
use Hello;

Hello::printHello("a");

I tested it in git bash on windows, maybe you have to do some modifications in your environment.

In this way you can pass as many arguments as you would like to, and you don't have to look for the variables you are using and maybe not initialized (this is a less safe approach I think, e.g. sometimes you will delete something you did't really want) somewhere in the file you want to call. The disadvantage is that you need to learn a bit about perl modules but I think it definitely worths.

A second approach could be to use the exec/system call (you can pass arguments in this way too; if forking a child process is acceptable), but that is an another story.

Upvotes: 2

Related Questions