sureshkumar
sureshkumar

Reputation: 599

How are the values printed in the foreach statement?

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

Answers (3)

zdim
zdim

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/// and tr/// (aka y///) 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() and map() functions.

  • The implicit variable of given().

  • The default place to put the next value or input record when a <FH>, readline, readdir or each operation's result is tested by itself as the sole criterion of a while test. Outside a while 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

linuxtestside
linuxtestside

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

carlosn
carlosn

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

Related Questions