>          # form a script
>          local($^I, @ARGV) = ('.bak', glob("*.c"));
>          while (<>) {
>              if ($. == 1) {
>                  print "This line should appear at the top of each
file\n";
>              }
>              s/\b(p)earl\b/${1}erl/i;        # Correct typos,
preserving case
>              print;
>              close ARGV if eof;              # Reset $.
>          }

A quick glance shows this is going to read through
*.c files, modifying them (and renaming the old file
to *.c.bak). In each file, it's going to stick a line at
the top and change pearl to perl.

(Both the one liner and this are clearly someone
experimenting.)

>          # form a script

This isn't a complete script in a traditional sense.
Usually a perl script starts with:

    #!/usr/bin/perl -w

or similar.

Anyhow:

>          local($^I, @ARGV) = ('.bak', glob("*.c"));

    local $foo = "bar";
    local ($foo, $bar) = ("foo", "bar");

sets the variables listed on the left to the values
listed on the right. There are four ways to do this:

    $foo = "foo";
    my $foo = "foo";
    our $foo = "foo";
    local $foo = "foo";

(ok, there's lots more ways, but these are some
basics.)

our and local should refer to a global variable.
local is a form of our that tells perl to forget the
"local" value when the current {} pair is exited.

    @ARGV = (1, 2);
    {
        local @ARGV = (3, 4);
        # @ARGV contains (3, 4)...
    }
    # @ARGV contains (1, 2)...

In this case, the script is setting $^I and @ARGV.

$^I is the same as the -i switch at a shell prompt /
command line.

Set $^I to '' (null string) to switch inplace editing on,
without backups. Set it to a string to have backups
created with the string added to the backup name.
(You can get clever with this naming. See the doc.)

@ARGV is the list of "arguments" to the script. The
glob() takes its parameter and returns all the matching
directory entries; so in this case, @ARGV will end up
with a bunch of *.c files (presuming there are some to
match).

(When you use something like *.c at a shell prompt,
the shell does something akin to the glob() itself. So
if you do "perl -pi -e 's/foo/bar' *.c" the perl code will
operate on all the directory entries matching *.c in the
current directory.)

So, what the initial local line does is set up the rest of
the script to work on inplace editing a bunch of *.c
files, and it localizes the changes to $^I and @ARGV
just in case this bit of code is embedded in a larger
bunch of perl code that might also make use of these
variables.

>          while (<>) {

A wonderful perl idiom.

This means keep grabbing lines from input, as long
as there are lines to grab. In this case, input is from
the files listed in @ARGV, one by one until all the
lines in all the files are used up, then the while quits.

The current line is stuffed into $_, the default variable
on which things like s/// and print work if not told what
variable to work on.

>              if ($. == 1) {
>                  print "This line should appear at the top of each
file\n";

$. is the line number in the current file.

>              s/\b(p)earl\b/${1}erl/i;        # Correct typos,
preserving case

A pretty bizarre s/// to change pearl to perl.

\b means word boundary. Which means anywhere that
is in the middle of two characters in a string and on the
left, the character is alphanumeric (or a _) and on the
right it is not. Or vice versa. (\b also matches at the
start or end of a string.)

${foo} is the same as $foo. You usually use it if not using
it would make perl think you are talking about some other
variable than the one you mean. For example:

    ${foo}bar;
    $foobar;

The second one is the variable $foo followed by the
literal text 'bar'.

the /i on the end of the s/// means ignore case.

>              print;

Print $_ (the current line).

>              close ARGV if eof;              # Reset $.

Not usually needed. But in this case, the programmer
wants to reset $. (line number) as each new input file
is opened.

eof tests for end of file on the current file.

(eof() tests for end of file on the last file.)

---------------

Now, don't DARE tell me you didn't need to know
all this once you knew they were experiments... :>

Reply via email to