Reputation: 599
I am very very new to perl programming.
While reading about the loops, for the foreach loop I got two examples.
The one example is,
foreach ('hickory','dickory','doc') {
print $_;
print "\n";
}
Output:-
hickory
dickory
doc
The $_ variable contains the each item. So, it prints.
In another example, they said did not specified the $_ variable in print statement. The empty print statement only there. How it prints the foreach arguments.
foreach ('hickory','dickory','doc') {
print;
print "\n";
}
Output:-
hickory
dickory
doc
For this also the same output. How it prints the values. In that book they did not given any explanation for that. I was searched in internet. But I am not able to find anything.
Upvotes: 4
Views: 1112
Reputation: 66883
Your question about print
in foreach
being answered, here is a little more on $_
.
From General Variables in perlvar
Here are the places where Perl will assume
$_
even if you don't use it:
- The following functions use
$_
as a default argument:- abs, alarm, chomp, chop, chr, chroot, cos, defined, eval, evalbytes, exp, fc, glob, hex, int, lc, lcfirst, length, log, lstat, mkdir, oct, ord, pos, print, printf, quotemeta, readlink, readpipe, ref, require, reverse (in scalar context only), rmdir, say, sin, split (for its second argument), sqrt, stat, study, uc, ucfirst, unlink, unpack.
All file tests (
-f
,-d
) except for-t
, which defaults to STDIN. See-X
The pattern matching operations
m//
,s///
andtr///
(akay///
) when used without an=~
operator.The default iterator variable in a
foreach
loop if no other variable is supplied.The implicit iterator variable in the
grep()
andmap()
functions.The implicit variable of
given()
.The default place to put the next value or input record when a
<FH>
,readline
,readdir
oreach
operation's result is tested by itself as the sole criterion of awhile
test. Outside awhile
test, this will not happen.
$_
is by default a global variable.
As you can see, it is available nearly everywhere and it is indeed used a lot. Note that the perlvar page describes a whole lot more of similar variables, many of them good to know about.
Here is an example. Consider that we read lines from a file, want to discard the ones which have only spaces or start with #
(comments), and for others want to split them by spaces into words.
open my $fh, '<', $file or die "Can't open $file: $!";
while (<$fh>)
{
next if not /\S/;
next if /^\s*#/;
my @words = split;
# do something with @words ...
}
Let's see how many uses of $_
are in the above example. Here is an equivalent program
while (my $line = <$fh>)
{
next if not $line =~ m/\S/; # if not matching any non-space character
next if $line =~ m/^\s*#/; # if matching # after only (possible) spaces
my @words = split ' ', $line; # split $line by ' ' (any white space)
# do something with @words ...
}
Compare these two
the filehandle read <$fh>
in the while
condition assigns to $_
, then available in the loop.
regular expression's match operator by default works on $_
. The m
itself can be dropped.
split
by default splits $_
. We also use the other default, for the pattern to split the string by, which is ' '
(any amount of any white space).
once we do $line = <$fh>
the deal with $_
is off (it is undefined in the loop) and we have to use $line
everywhere. So either do this or do while (<$fh>)
and use $_
.
To illustrate all this a bit further, let us find the longest capitalized word on each line
use List::Util 'max';
my $longest_cap = max map { length } grep { /^[A-Z]/ } @words;
The grep takes the list in @words
and applies the block to each element. Each element is assigned to $_
and is thus available to the code inside the block as $_
. This is what the regex uses by default. The ones that satisfy the condition are passed to map, which also iterates assigning them to $_
, what is of course the default for length. Finally max
from List::Util picks the largest one.
Note that $_
is never actually written and no temporary variable is needed.
Here is some of the relevant documentation. The I/O Operators in perlop discusses while (<$fh>)
and all manner of related things. The regex part is in Regexp Quote-Like Operators in perlop and in perlretut. Also have a look at split.
Defaults are used regularly and to read code written by others you must understand them. When you write your own code though you can choose whether to use $_
or not, as one can always introduce a lexical variable instead of it.
So, when to use $_
as default (which need not be written) and when not to?
Correct use of defaults, $_
in particular, can lead to clearer and more readable code. What generally means better code. But it is quite possible to push this too far and end up with obscure, tricky, and brittle code. So good taste is required when deciding.
Another case is when some parts of the code benefit from having $_
for their defaults while at other places you then have to use $_
explicitly. I'd say that if $_
is seen more than once or twice in a section of code it means that there should be a properly named variable instead.
Overall, if in any doubt simply name everything.
Upvotes: 5
Reputation: 371
I will explain why you getting same results with the different syntax:
If you omit the control variable from the beginning of the foreach loop, Perl uses its favorite default variable, $_ . This is (mostly) just like any other scalar variable, except for its unusual name. For example:
foreach ('hickory','dickory','doc') {
print $_;
print "\n";
}
Output :
hickory
dickory
doc
Although this isn’t Perl’s only default by a long shot, it’s Perl’s most common default. You’ll see many other cases in which Perl will automatically use $_ when you don’t tell it to use some other variable or value, thereby saving the programmer from the heavy labor of having to think up and type a new variable name. So as not to keep you in suspense, one of those cases is print , which will print $_ if given no other argument:
foreach ('hickory','dickory','doc') {
print; # prints $_ by default
print "\n";
}
Output :-
hickory
dickory
doc
Upvotes: 0
Reputation: 433
If you are not declaring any variable in your foreach
loop it sets by default $_
From perldoc about foreach:
The foreach keyword is actually a synonym for the for keyword, so you can use either. If VAR is omitted, $_ is set to each value.
So it explains the first loop.
The second loop, as you already know now that $_
is set with each element from your array, will works because you are omitting the $var
.
You could use foreach loop with explicit variable like this:
foreach my $item ( @list )
{
print "My item is: $item\n";
}
Or you can omit like you did and print will still work as @Dada said because:
If FILEHANDLE is omitted, prints to the last selected (see select) output handle. If LIST is omitted, prints $_ to the currently selected output handle.
Upvotes: 2