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");
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With