Catherine D
Catherine D

Reputation: 99

Run perl script within perl script using named arguments

I'm writing a Perl program that must run a few Perl scripts multiple times on different inputs.

The scripts I'm trying to use are count.pl and statistic.pl from Text::NSP. I didn't write those myself so I don't want to try and refactor them into a module.

I looked at a similar question and figured out how to use the system method from IPC::System::Simple.

However, I want to make use of the named arguments in count.pl and statistic.pl. I haven't yet figured out how to do this. This is my current code:

system($^X, token="valid_tokens.txt", "/Users/cat/perl5/bin/statistic.pl", "ll.pm", "lab01_jav_bigrams.ll",
"/Users/cat/Perl_scripts/214_Final_project/lab01_java_bigrams.cnt");

And this is the error I get:

Can't modify constant item in scalar assignment at ngram_calcs.PL line 22, near ""valid_tokens.txt"," Bareword "token" not allowed while "strict subs" in use at ngram_calcs.PL line 22.

It's worth noting that the code worked fine until I added the named argument. How do I supply a named argument to IPC::System::Simple? Or is there a better way to do what I'm trying to do?

Edit: Thanks, Haukex, I did have the wrong parameters, and using "--token=valid_tokens.txt" worked.

Even though the problem is solved, I'll share more context so that other people who see can benefit. On the commmand line I would type this:

count.pl -token validtokens.txt lab01_java_bigrams.cnt Users/cat/CS214/lab01_java.txt
statistic.pl -score 6.63 ll.pm lab01_java.ll lab01_java_bigrams.cnt

This is the correct perl code:

system($^X, "/Users/cat/perl5/bin/count.pl", "--token=valid_tokens.txt", "lab01_java_bigrams.cnt", $filename);
system($^X, "/Users/cat/perl5/bin/statistic.pl", "--score=6.63", "ll.pm", "lab01_java_bigrams.ll", "/Users/cat/Perl_scripts/214_Final_project/lab01_java_bigrams.cnt");

Upvotes: 3

Views: 886

Answers (3)

Borodin
Borodin

Reputation: 126742

Assuming your call to statistic.pl is broadly correct, the parameters to system need to look like this

system($^X,
    "/Users/cat/perl5/bin/statistic.pl",
    qq/token="valid_tokens.txt"/,
    "ll.pm",
    "lab01_jav_bigrams.ll",
    "/Users/cat/Perl_scripts/214_Final_project/lab01_java_bigrams.cnt"
);

i.e. all parameters belong after the program file, and the whole of the named parameter string must be enclosed in quotes

Please read the comment from haukex below for another potential error

Upvotes: 2

haukex
haukex

Reputation: 3013

I am confused about your system invocation. Looking at the sources of statistic.pl and count.pl, it seems that only the latter takes a token argument, but you don't seem to be running count.pl. $^X is the currently running Perl interpreter, which would normally be followed by any arguments to the interpreter, then the name of the script, then any arguments to the script, so placing the token argument before the script doesn't make sense to me.

If you are for example trying to pipe the output of count.pl into statistic.pl, you'll have to explain further, because that is something that IPC::System::Simple can't handle (at least not without invoking the shell, which I would recommend against), and you'd need a more advanced module like IPC::Run. For now, I will assume you want to pass the token parameter to a script that supports it.

Command line arguments are just strings. If from a *NIX shell you were to write something like ./script.pl token="test file" foo bar, then the shell would take over the interpretation of white space and quoting. script.pl will get a list of strings like ("token=test file", "foo", "bar") (note how the shell took care of the quotes there).

This list of strings is what you need to pass to system, which is not necessarily the same as what you would type on the command line. It is up to the called program to interpret those arguments. The two scripts you are running use Getopt::Long, and the named arguments need to be prefixed by two dashes. So something like this should work:

system($^X, "/Users/cat/perl5/bin/count.pl", "--token=valid_tokens.txt", ...);

As for how to pass arguments that include special characters like quotes (which does not apply in this case), there are various syntaxes in Perl: "--foo=\"bar\"", '--foo="bar"', or q{--foo="bar"} (see Quote and Quote-like Operators).

Upvotes: 4

Shuwn Yuan Tee
Shuwn Yuan Tee

Reputation: 5748

Can you try this format?

system('/Users/cat/perl5/bin/statistic.pl  --token valid_tokens.txt  ll.pm  lab01_jav_bigrams.ll  /Users/cat/Perl_scripts/214_Final_project/lab01_java_bigrams.cnt');

But I check the source of the CPAN module, seems token is an option for count.pl, but not statistic.pl.

Anyway, any options can be specified similar to --token valid_tokens.txt.

Hope this help!

Upvotes: 0

Related Questions