In the Spring of 1996, I was taking dance lessons. Lindy Hop. The instructor was kind of a science nerd, but a very good swing dancer nonetheless. He always brought a laptop to the studio. Between lessons he'd work intensely on his 90Mhz beauty. I was always interested in what he was doing. Sometimes I'd ask, but he'd be too busy to talk. One day I told him that I was a computer programmer. This got his attention slightly. He looked up from the screen and asked, "Do you know Perl?". Well, I knew Perl as a set of O'Reilly books that I was going to read eventually, but I hadn't got around to it yet. My face started to sag, then suddenly brightened. "No, but I know Awk!", I beamed. He never talked to me again.
--- This is great news John. Most fitting too, because today Neil Watkiss and I embark on our latest: The Inline Book. It seems that everytime I'm about to do something new or cool with Inline, someone else (usually you) comes out with a new Inline module to inspire me. Cheers! You've obviously gone beyond the call of duty in preparing the module. By all means, load that puppy to CPAN. One point: > I wanted to call the module `Inline::Awk' but it caused problems when > working with `Inline::Files' filehandles which have to be in uppercase. Can you get around this by using the 'aliases' property in the 'register' method? That way the module would be called Inline::Awk, but the usage would be: use Inline::Files; use Inline AWK => ... Cheers, Brian On 14/11/01 10:40 +0000, John McNamara wrote: > > The Inline::AWK module allows you to include awk code in your Perl program. > > Version 0.02 is a more robust implementation which allows you to call awk > functions or entire programs. > > I have regression tested Inline::AWK against gawk and mawk for all of the code > examples and programs in "The AWK Programming Language". It gives the same > results for 130 of the programs without any modifications to the awk code. > With minor modifications to the awk code it can run an additional 20 of the > programs. > > If there are no major objections or corrections I would like to release this > module to CPAN. > > The module is available from: > http://homepage.eircom.net/~jmcnamara/perl/Inline-AWK-0.02.tar.gz > > ActivePerl users can use PPM as follows: > > C:\> ppm > PPM> set repository tmp http://homepage.eircom.net/~jmcnamara/perl > PPM> install Inline-AWK > PPM> quit > C:\> > > If this fails try the following: > > PPM>install http://homepage.eircom.net/~jmcnamara/perl/Inline-AWK.ppd > > > The original announcement for this module is archived here: > http:[EMAIL PROTECTED]/msg00760.html > > John. > > > =============================================================================== > > NAME > Inline::AWK - Add awk code to your Perl programs. > > VERSION > This document refers to version 0.02 of Inline::AWK, released November > 13, 2001. > > SYNOPSIS > Call an awk function from a Perl program: > > use Inline AWK; > > hello("awk"); > > __END__ > __AWK__ > > function hello(str) { > print "Hello " str > } > > Or, call an entire awk program using the `awk()' function: > > use Inline AWK; > > awk(); # operates on @ARGV by default > > __END__ > __AWK__ > > # Count the number of lines in a file > END { print NR } > > DESCRIPTION > The `Inline::AWK' module allows you to include awk code in your Perl > program. You can call awk functions or entire programs. > > Inline::AWK works by converting the awk code into Perl code using the > `a2p' utility which comes as standard with Perl. This means that you > don't require awk to use the Inline::AWK module. > > Here is an example of how you would incorporate some awk functions into > a Perl program: > > use Inline AWK; > > $num = 5; > $str = 'ciao'; > > print square($num), "\n"; > print echo($str), "\n"; > > print "Now, back to our normal program.\n" > > __END__ > __AWK__ > > function square(num) { > return num * num > } > > function echo(str) { > return str " " str > } > > You can call an awk program via the `awk()' function. Here is a simple > version of the Unix utility `wc' which counts the number of lines, words > and characters in a file: > > use Inline AWK; > > awk(); > > __END__ > __AWK__ > > # Simple minded wc > BEGIN { > file = ARGV[1] > } > > { > words += NF > chars += length($0) +1 # +2 in DOS > } > > END { > printf("%7d%8d%8d %s\n", NR, words, chars, file) > } > > awk() > > The `awk()' function is imported into you Inline::AWK program by > default. It allows you to run `Inline::AWK' code as a program and to > pass arguments to it. > > Say, for instance, that you have an awk program called `parsefile.awk' > that you would normally run like this: > > awk -f parsefile.awk type=1 example.ini > > If you then turned `parsefile.awk' into an Inline::AWK program, (perhaps > by using the `a2a' utility in the distro), you could run the code from > within a Perl program as follows: > > awk('type=1', 'example.ini'); > > If you are using `-w' or `warnings' in your Perl program you should > quote any literal string in the variable assignment that you pass: > > awk('type=ini', 'example.ini'); # gives a warning with -w > awk('type="ini"', 'example.ini'); # no warning > > The default action of an awk program is to loop over the files that it > is passed as arguments. Therefore, the `awk()' function without > arguments is equivalent to inserting the following code into your Perl > program: > > while (<>) { > # Converted awk code here > } > > As usual, the empty diamond operator, `<>' will operate on `@ARGV', > shifting off the elements until it is empty. Therefore, `@ARGV' will be > cleared after you call `awk()'. However, `awk()' creates a `local' copy > of any arguments that it receives so you can avoid clearing `@ARGV' by > passing it as an argument: > > awk(@ARGV); > # Do something else with @ARGV in Perl > > The only awk program that doesn't loop over a files is one that contains > only a BEGIN block: > > use Inline AWK; > > awk(); > > __END__ > __AWK__ > > BEGIN { print "Hello, world!" } > > If your program only has awk functions and no awk program you can ignore > `awk()'. However, it is still imported into you Perl program. > > HOW TO USE Inline::AWK > You can use `Inline::AWK' in any of the following ways. See also the > Inline documentation: > > Method 1 (the standard method): > > use Inline AWK; > > # Call the awk code > > __END__ > __AWK__ > > # awk code here > > Method 2 (for simple code): > > use Inline AWK => "# awk code here"; > > Method 3 (requires Inline::Files): > > use Inline::Files; > use Inline AWK; > > # Call the awk code > > __AWK__ > > # awk code here > > HOW Inline::AWK works > `Inline::AWK' in based on the same framework that underlies all of the > `Inline::' modules. This is described in detail in the `Inline-API' > document. > > Inline::AWK works by filtering awk code through the Perl utility `a2p'. > The a2p utility converts awk code to Perl code using a parser written in > C and YACC. Inline::AWK pre and post-processes the code going through > a2p to obtain a result that is as close as possible to the output of a > real awk compiler. However, it doesn't always get it completely right, > see the BUGS manpage. > > Nevertheless, Inline::AWK can compile and run 130 of the code examples > and programs in "The AWK Programming Language" and produce the same > results as awk, mawk or gawk. It can run an additional 20 programs from > the book with only minor modifications to the awk code. See, the > regression test at: > http://homepage.eircom.net/~jmcnamara/perl/iawk_regtest_0.01.tar.gz > > BUGS > While `a2p' does a very good job of converting awk code to Perl it was > never intended for the use that `Inline::AWK' put it to. While > Inline::AWK compensates for some of the areas where a2p differs from awk > you may still encounter bugs or discrepancies. The following sections > give some hints on how to work around these, ahem, issues. > > String versus numeric context > > Awk uses the same equality operators for both numbers and strings > whereas Perl uses different operators. For example consider the > following awk function: > > function max(m, n) { > return (m > n ? m : n) > } > > There isn't enough information here for a2p to tell if `m' and `n' will > be numeric or string values so it defaults to a string comparison and > generates a warning (See the the THE VOICE OF LARRY entry elsewhere in > this document): > > sub max { > local($M, $n) = @_; > ($M gt $n ? $M : $n); #??? > } > > This code may or may not be what was intended. However, a2p will take > into account any previous uses of a variable in a numeric or string > context. Therefore, the following modified code: > > function max(m, n) { > m += 0; > return (m > n ? m : n) > } > > Will produce a numeric comparison (although the warning is still > generated): > > sub max { > local($M, $n) = @_; > $M += 0; > ($M > $n ? $M : $n); #??? > } > > Return statements > > In an awk function `return expression' is a valid statement for any > valid expression. However, this can sometimes cause problems for a2p. > For example the following function would cause a translation failure: > > function isnum(n) { return n ~ /^[+-]?[0-9]+$/ } # Fails > > The simple workaround for this is to include parenthesis around any > complex expression in a return statement: > > function isnum(n) { return (n ~ /^[+-]?[0-9]+$/) } # Passes > > The ternary operator > > A2p can also have problems with the ternary operator `exp1 ? exp2 : > exp3' when it is used in complex expressions. Therefore, it is best to > put parentheses around all ternary conditionals. > > printf "Found %d file%s", n, n == 1 ? "": "s" # Fails > printf "Found %d file%s", n, (n == 1 ? "": "s") # Passes > > This isn't a problem for simpler assignments. > > The module name > > I wanted to call the module `Inline::Awk' but it caused problems when > working with `Inline::Files' filehandles which have to be in uppercase. > > Actually, since I have always wanted to write an awk compiler I would > have really liked to call the module `Inline::Jawk': that is to say, > John's awk. > > However, I was chastened by the BUGS section of the mawk man page where > mawk's author Mike Brennan says: "Implementors of the AWK language have > shown a consistent lack of imagination when naming their programs.". > > THE VOICE OF LARRY > The following warning indicates that `a2p' couldn't determine if a > string or numeric context was required at some point in your awk code: > > Please check my work on the lines I've marked with "#???". > The operation I've selected may be wrong for the operand types. > > See, the BUGS section for an explanation of why you should heed this > warning. > > Due to the nature of the Inline mechanism you will only see this warning > the first time you run your program. This may be good or bad, it depends > on your point of view. ;-) > > RATIONALE > The utility of this module is questionable: it doesn't do anything more > than you can already do with `a2p'; you can do something similar with > `Filter::exec "a2p";' and even without `a2p' it's generally easy to > translate awk code to Perl code. > > However, I am fond of awk and if nothing else it will give Brian > Ingerson an extra bullet point on his Inline languages slide. > > Also, `Inline::AWK' serves as an atonement for `Inline::PERL'. ;-) > > SEE ALSO > Inline.pm, the Inline API and Foo.pm. > > "The AWK Programming Language" by Alfred V. Aho, Brian W. Kernighan, and > Peter J. Weinberger, Addison-Wesley, 1988. ISBN 0-201-07981-X. > > ACKNOWLEDGEMENTS > Thanks to Brian Ingerson for the excellent `Inline::C' and the `Inline' > framework. > > AUTHOR > John McNamara [EMAIL PROTECTED] > > COPYRIGHT > � MMI, John McNamara. > > All Rights Reserved. This module is free software. It may be used, > redistributed and/or modified under the same terms as Perl itself. > > -- > perl -le 'use Inline AWK=>q+function j(){print"Just Another Awk Hacker"}+;j'
