Originally published in the 3000 NewsWire
The Perl interface to Suprtool
Export Multi-line records with Suprtool and Perl
Perl is an interpreted language that is the brainchild of Larry Wall. He continues to develop and guide the language, which, through the help of the net community, is available on virtually every computer platform, from Apple Macintosh to MPE.
Perl, officially known as either Practical Extraction and Reporting Language or Pathologically Eclectic Rubbish Lister, is a popular language for implementing web page CGI scripts, processing string data, even system administration. The semi-official Perl web site is www.perl.com
However, Perl is much more than a sometimes-odd-looking web scripting language. It has enough power to be a full programming language. One glance at some of the O'Reilly Perl books will testify to that (Perl for Bioinformatics, Perl for System Administration, Perl for Website Management).
If you think of perl as a shell-like programming language that evolved from quick-and-dirty handling of text, lists, associate arrays, and regular expressions, then you're already thinking Perl. Let's dive in!
0 # Perl has no line numbers, they're here for reference only 1 $num = 123; 2 $str = "abc"; 3 print "number=$num string=$abc";
Line 0 is a single-line Perl comment, which are similar to Unix shell comments. There are no multi-line comments.
Perl is not a strictly typed language, so a variable can hold either numeric or string values. Also, no declarations of variables are needed before they are used. Line 1 and 2 assign a number and a string. These type of variables are known as scalar variables (they hold a single primitive value), and their names are prefixed by a $ sign. One characteristic of Perl is that all variables names have a prefix character such as $. This may seem strange, but not when you think of similarities to Unix shell scripts.
1 @list = (12.3, "abc", 4..6);
2 foreach $i (@list) {
3 print "$i\n";
4 }
5 $count = @list;
6 print "There are $count items\n";
Another fundamental variable type in Perl is List. Line 1 shows the assignment of a list variable, whose name is prefixed with a @ sign. A list variable is like a 1-dimensional array. But unlike strictly typed languages, a list in Perl can contain mixed types of data. Here, the list contains 5 values: the number 12.3, the string "abc", and numbers 4, 5, and 6 (specified by the range 4..6).
Lines 2-4 are a typical way of looping through all the items in a list, using the foreach construct. In line 3, notice that literal strings in double quotes can contain variables that are dereferenced.
Line 5 may initally look like an error (assigning a list variable to scalar variable), but it is a common occurrence in Perl and shows an important concept: context. Think of context as fancy type-conversion. Here, because the left-hand-side of the assignment is a scalar variable, the right-hand-side must also be scalar. So the list variable is "evaluated in a scalar context", which does the convenient thing of returning the number of items in the list. You'll discover that Perl has many of these types of conveniences built-in. This is of course a double-edge sword; a wrong context can give you more opportunities to debug your code. For a more extreme example of Perl assuming useful defaults, see the "Perl Cookbook" example in the O'Reilly Books section below.
We could also have accessed the list in a traditional array-like fashion by numeric indexing. Like C, Perl starts array indexes at 0.
7 for ($i=0; $i<@list; $i++) {
8 print "$list[$i]\n";
9 }
Line 7 is a standard for loop for looping over n items, and we once again evaluated @list in a scalar context in the comparison $i<@list. Note in Line 8 that we prefixed the list variable with a $. Are we referring to a scalar variable call $list or the list variable @list? Actually neither; we are referring to a scalar element of the list which is list[$i]. Since this is a scalar value, a scalar prefix is needed. Another important point is that scalar and list variables names are in different namespaces. This means you can simultaneously have a separate $abc scalar variable and @abc list variable. Use this feature carefully, otherwise you end up write hard-to-understand code such as $abc = $abc[$abc].
$review{"Monsters Inc."} = "funny and original";
$review{"Harry Potter"} = "true to the book";
$review{"Lord of the Rings"} = "also true to the book except for Arwen";
The above defines a hash called "review". It is a list of brief reviews that is indexed by the name of the movie. In using hashes, we use the curly braces { } instead of square brackets [ ] when indexing.
Here is an example of parsing a string similar to those commonly returned from an HTML form:
1 $line="option=1&company=Robelle&product=Qedit,Suprtool";
2 @pairs=split(/&/,$line);
3 foreach $item (@pairs) {
4 ($name, $value) = split(/=/,$item);
5 $form{$name} = $value;
6 }
7 @list = keys(%form);
8 foreach $name (@list) {
9 print "$name = $form{$name} \n";
10 }
In Line 2 and 4, the split function takes a regular expression (although we are using it here just for a simple string search) and a string, finds the substrings that are separated by the regexp, and returns a list of those sub-strings. So in Line 2, we are looking for the substrings separated by an ampersand &. Split returns this list of three strings:
option=1 company=Robelle products=Qedit,SuprtoolIn Line 4, the split works in a similar way to break up the name/value pairs "option=1" into a list of two elements ("option", "1"). Notice that Perl allows simultaneous assignments of several variables. The assignment puts the first element in $name and second element in $value. You can swap two variables without a temporary value by doing ($a,$b)=($b,$a).
In Line 5, the assignment to a hash looks almost like assigning to an array assignment, except that curly braces are used instead of square brackets. And remember that the variable "form" is a hash despite the leading $ sign.
In Line 7, the keys function returns a list of all the key values in a hash ("option", "company", "product"). Notice that a hash is prefixed by a % sign when used in hash context. If you wanted to get all the values in a hash, you would use the values function, which would have returned (1, "Robelle", "Qedit,Suprtool")
http://jazz.external.hp.com/src/hp_freeware/perl/
Perl was ported to the HP 3000 by Mark Bixby. Here are some notes on Perl/iX from the Jazz web site:
"The following prerequisites apply to Perl on MPE/iX:
MPE::CIvar
Ken Hirsch's interface for MPE/iX JCWs, CI variables, and the HPCICOMMAND intrinsic. Please see http://invent3k.external.hp.com/~MGR.HIRSCH/CIvar.html for more info. For more MPE Perl modules, search CPAN.
MPE::IMAGE
Ted Ashton's interface for MPE/iX TurboIMAGE databases. New Maintainer for MPE::IMAGE Perl Module: Maintenance of this module is being taken over from Ted Ashton by David Oksner, who is adding Eloquence and HP-UX support.
Read another Robelle technical tip: Export Multi-line records with Suprtool and Perl
The primary Perl web sites are:www.perl.org - Perl user community
www.perl.com - O'Reilly, offical Perl home
www.cspan.org - Comprehensive Perl Archive Network
Problem: "How to do something to every word in a file"
Solution: Split each line on whitespace:
while (<>) {
for $word (split) {
# do something with $word
}
}
And read more about it at: http://invent3k.external.hp.com/~MGR.HIRSCH/Suprtool.html
To install the Suprtool extension, you also need the gcc compiler tools. Ken Hirsch has instructions for how to install his packages at http://invent3k.external.hp.com/~MGR.HIRSCH/perlinst.html
From Ken's documentation file, here is a sample Suprtool task in Perl and some explanation of the functions provided:
use MPE::Suprtool;
chdir "/$ENV{HPACCOUNT}/PUB" or die "Cannot cd to PUB: $!\n";
# May be necessary to chdir to an MPE group
# (depending on Suprtool version)
my $supr = MPE::Suprtool->new
or die "Cannot run Suprtool\n";
my $account = 518;
$supr->cmd(
"bas ordrdb,5,password",
"chain order-detail,account=$account",
"extr order-num, account, invoice",
"output ordlist,ascii",
"purge ordlist",
"exit") or die "Error on Suprtool comand '" . $supr->lastcmd .
"', status = " . $supr->status . "\n";
print "I wrote ", $supr->count, " records.";
The extension provides three functions: new, cmd and lastcmd.
new ( [args] )
Creates a new Suprtool object. new optionally takes arguments; these arguments are in key-value pairs and define the execution priority and the XL location of the Suprtool2 subroutine. For example:
my $supr = MPE::Suprtool->new( printstate => 'AL', pri => 'CS')
or die "Cannot run Suprtool\n";
cmd( @list )
cmd submits a command or list of commands to Suprtool. This is a list of strings, which can be an array variable, string literals, a list of scalar string variables, or just about any combination. The normal Perl rules apply, so if you want to say OUTPUT $NULL you'll need to use single quotes 'OUTPUT $NULL' or escape the $ in double quotes: ``OUTPUT \$NULL'' Of course, sometimes you want to interpolate a variable. The commands are only executed when there's an ``EXIT'' in a string by itself. Each command string can be up to 256 characters long. You can combine commands in one string by separating them with a semicolon. The following all have the same effect:
$supr->cmd("INPUT FILE1; KEY 1,4; OUTPUT FILE2", "EXIT");
OR
$supr->cmd("INPUT FILE1", "KEY 1,4");
$supr->cmd("OUTPUT FILE2", "EXIT");
OR
$supr->cmd("INPUT FILE1");
$supr->cmd("KEY 1,4");
$supr->cmd("OUTPUT FILE2");
$supr->cmd("EXIT");
OR
@a = ("KEY 1,4", "OUTPUT FILE2");
$supr->cmd("INPUT FILE1", @a, "EXIT");
and so on.
lastcmd
The last command executed. If cmd is passed a list, it will stop on any command giving an error. Some syntax errors will be caught on the command containing the error, but most errors will only get caught on the 'EXIT' command, so this is of limited utility.
So now you have a great excuse to install Perl on your HP 3000 and learn it - you can use it to execute Suprtool tasks!
|
|
|---|