On Jul 5, 10:49 am, [EMAIL PROTECTED] (Monty) wrote:
> I'm reading "Network Programming with Perl" by Lincoln Stein, and I've
> come across a snippet of code I'mnot quite following:
>
> open (WHOFH, "who |") or die "Can't open who: $!";
>
> While (<WHOFH>) {

Please configure your mail/newsreader not to randomly capitalize
words.  There is no "While" keyword in Perl.

>     next unless /^(\S+)/;
>     $who{$1}++;
> }
>
> It's the 'next' line I'm unclear on.  I know that results: parse the
> first field from each output line of the 'who' command, but I'm
> wondering why this might have been done in this way.  It seems to me
> that the 'next' line states "get the next record unless the current
> one startes with a non-whitespace character".
>
> The UNIX 'who' command output lines always start with non-whitespace
> characters, as far as I can see.  It seems just as sensible to leave
> this line out.  Does anyone know additional value to doing this?

Well, the next command is actually doing three things at once.  First,
it's determining whether or not the current line starts with non-
whitespace characters.  Then, if it doesn't start with whitespace
characters, it skips the remainder of this iteration of the while
loop.  Finally, if it does start with whitespace characters, it's
saving those characters in $1.

The third part is obviously important.  As for the first two, I have
no idea - maybe there are some rare circumstances in which `who`
returns blanks at the start of the line?

> Also, the '$who{$1}++' lines has the same effect here as "awk '{ print
> $1 }'",

No it doesn't.  $who{$1}++ increments the value in the %who hash that
has the key $1.  `awk '{ print $1 }'` prints the first element of the
string that awk has parsed.  Perl's $1 and awk's $1 are wholly
unrelated.

> and leads me to believe that $2, $3, etc. also exist

They exist, yes.  But they're not what you think they are, any more
than Perl's $1 is what you think it is.

> but that
> doesn't seem to be the case as I've tried printing those variables.
> How does the '$1' work in this case?

$1, $2, $3, etc store the contents of the sequentially numbered
parentheses-enclosed submatches of the most recent successful pattern
match.  For example:

"hello world" =~ /(\w+) (\w+)/;
print "$1-$2\n";  #prints "hello-world"
"fooooooooo bar baz" =~ /(o{2})(o)(o+)/;
print "$1 $2 $3\n";  #prints "oo o oooooo"

Any successful pattern match will set ALL $<number> variables.  If
there are only two capturing parentheses, $1 and $2 are set to
whatever those captured submatches are, and $3 and up are set to
undef.  If there are no captured parentheses, all of $1 on up are set
to undef.

In your example, only one set of captured parentheses existed in the
pattern match, and so only $1 was set to a defined value.

Read more about regular expressions in:
perldoc perlretut
perldoc perlre
perldoc perlreref

Paul Lalli


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to