Rich Morin <rdm@cfcl.com> wrote: >BBEdit (a fine GUI-based text editor for Macs) is capable of running >MacPerl-based filters on selected text. I understand that some other >editors (e.g., vim) also have this capability. >I would love to have some intriguing demo filters on hand at WWDC (the >Apple World Wide Developers Conference) in a week or so. They should >have a strong "Gee Whiz!" factor. It would also be nice if they can >be explained to mortal programmers... >Does anyone feel like suggesting (or even coding up :-) something? A couple of quickies: s/(\S+)/reverse $1/ge; A few weeks ago, to my great surprise, I found myself on the Microsoft campus interviewing for a job. The job wasn't with Microsoft (or I wouldn't have been there), but with a new company to be composed largely of ex-Microsoft employees. The interviewer asked me to come up with some code that would reverse the order of all words in a file. I blinked, and asked if any language was permitted. He said yes. I quickly scratched out a Perl solution similar to the above. (Unfazed, he demanded I reimplement the solution in Java.) Speaking of which, back when I used to program in Java a lot, I would often be faced with the job of assigning unique numbers to a large number of static class constants that served the purpose of enums in C, eg: public final static int RED = 0, ORANGE = 1, YELLOW = 2, GREEN = 3, /* ... several more lines ... */ MAUVE = 103; I quickly realized that Perl could make this task much easier. I only had to write the names, and let Perl fill in the numbers. I would write something like this: public final static int RED, ORANGE, YELLOW, GREEN /* ... */; ...and then pipe it through this: perl -pe 's/([A-Z]\w*)/"$1 = ".$n++/ge' Sometimes I want to modify a big chunk of a file (or even the entire file), but the transformation is nontrivial enough that typing it into my editor's single command line makes it likely that errors will be introduced; or, I might want to undo the transformation, modify it slightly, and reapply it. There's a great trick that makes this kind of thing easy: Just move the cursor to just above the region to be transformed, and insert this text: while (<DATA>) { # apply transformations and print output } __DATA__ ...then pipe the above, followed by the region to be transformed, through perl. Often it's desirable to operate on the entire region as one long string; to do this, just use the variation: undef $/; $_ = <DATA>; # whatever print; __DATA__ As an example, just yesterday I was editing a C source file in which I had defined several arrays of a structure, something like so: my_struct foo[] = { { "FieldOne", Field::STRING, 10 }, { "FieldTwo", Field::CONSTANT, 0, "some string" }, { "FieldThree", Field::INTEGER, 20 }, }; I was retooling the data structures that were initialized by these arrays, and I wanted to do the following: 1) Replace Field::STRING and Field::INTEGER with the strings "S" and "I", respectively. 2) Replace Field::CONSTANT with the string "C" appended with the string given as the fourth element of the struct. 3) The name and width for constant fields were superfluous, so replace the name with 0 and eliminate the width. There were hundreds of lines to alter, but I converted the entire file by piping it through a filter like this: while (<DATA>) { if (/^ *{ (.*) },$/) { @array = split /, */, $1; if ($array[1] eq 'Field::STRING') { $array[1] = '"S"'; } elsif ($array[1] eq 'Field::INTEGER') { $array[1] = '"I"'; } elsif ($array[1] eq 'Field::CONSTANT' && $array[3] =~ /"(.*)"/) { @array = (0, qq("C$1")); } print " { ", join(", ", @array), " },\n"; } else { print; } } __DATA__ As expected, I made some mistakes before I was completely satisfied, but all I had to do to recover from them was undo the transformation, twiddle the Perl code, and re-pipe the file. Finally (sheesh, I never thought this article would get so long!), sometimes I write a block of code consisting solely of assignments, and I decide the code would look better if all of the '=' characters were lined up neatly. I wrote a Perl program to do this, which I am currently unable to locate. It's pretty trivial to recreate, though: ---------------------------------------------------------------------- #!/usr/local/bin/perl use strict; my $char = @ARGV ? $ARGV[0] : '='; my $max = 0; my ($index, @list); while (<>) { push @list, $_; $index = index($_, $char); $max = $index if $index > $max; } foreach (@list) { s/(.*?)\Q$char/$1 . " " x ($max - length($1)) . $char/eo; print; } ---------------------------------------------------------------------- Anyway, I hope some of these ideas are useful. -- Sean McAfee | GCS d->-- s+++: a27 C++ US+++ P+++$ L++ E- W+ N++ | | K w--- O? M- V-- PS+ PE Y+ PGP?>++ t+() 5++ X R+ | mcafee@ | tv+ b++ DI++ D+ G e++ h r---* y+>++ | umich.edu ==== Want to unsubscribe from Fun With Perl? Well, if you insist... ==== Send email to <fwp-request@technofile.org> with message _body_ ==== unsubscribe