c has asked for the wisdom of the Perl Monks concerning the following question:

I am seeing two very different results between:

my ($rcs) = (q$Revision: 1.41 $ =~ /(\d+(?:\.\d+)+)/);


my $rcs = (q$Revision: 1.41 $ =~ /(\d+(?:\.\d+)+)/);

can someone explain the difference? I am not seeing the significance of the ( ) although it obviously has some very important differentiating power.

humbly -c

Replies are listed 'Best First'.
Re: difference between ($scalar) and $scalar
by tadman (Prior) on Jul 21, 2001 at 11:03 UTC
    The difference is that one can possibly land you in jail, while the other won't. Or something to that effect.

    I'm a particular fan of brackets, even when not strictly necessary, but I have been warned that this does have some side-effects on commands that are sensitive to the calling context. Maybe your biggest fear is only the Perl Police.

    Certain commmands do different things in different contexts. Consider an example from the above article:
    my ($fortune) = `fortune`;
    When the backtick detects "array context", it splits up the lines returned by the command into an array and returns it. $fortune then gets the first element/line and the rest go unassigned.
    my $fortune = `fortune`;
    In scalar context, the entire result is returned in one string, meaning that the linefeeds are not split.

    Or compare the two here, using the context sensitive localtime function:
    my ($time1) = localtime; my $time2 = localtime; print "$time1 / $time2\n";
    This prints, for me at least: "42 / Sat Jul 21 03:02:42 2001", which shows you how important those brackets can be.
      The difference is that one can possibly land you in jail, while the other won't. Or something to that effect.

      Very interesting! But I wonder how the administrators could see it at all, if the school's proxy was blocked by the firewall?

Re (tilly) 1: difference between ($scalar) and $scalar
by tilly (Archbishop) on Jul 21, 2001 at 10:58 UTC
    Without the parentheses, you are defining a scalar. With them you define a list of one thing. The difference is that the RHS is evaluated in a different context, as can be verified by putting a function there and testing wantarray.

    Look at Arrays are not lists for more on this topic.

Re: difference between ($scalar) and $scalar
by tachyon (Chancellor) on Jul 21, 2001 at 13:19 UTC

    To understand Perl you need to understand the notion of list versus scalar context. Many Perl functions can be called in either list or scalar context. What they return depends on the context in which tey were called. In scalar context they return a scalar value (often 1 for true if they succeed) whereas in list context they return a list of values. The examples below illustrate list versus scalar context as they apply to your question.

    $str = "aa bb cc"; # scalar context $a = $str =~ m/(\w+)/; print "$a\n"; # prints 1 # list context (1 element list $a) ($a) = $str =~ m/(\w+)/g; print "$a\n"; # prints aa # list context (multi element array list) @a = $str =~ m/(\w+)/g; print "@a\n"; # prints aa bb cc

    Another classic list versus scalar context gotcha is the localtime function which can either return a string that reads like Sat Jul 21 19:11:12 2001 in scalar context or a list. Run this code to see. Print applies a default list context.

    print localtime(), "\n"; print scalar localtime(), "\n"; $time = localtime(); @time = localtime(); print "\$time => $time\n"; print "\@time => @time\n";

    Hope this helps.




Re: difference between ($scalar) and $scalar
by japhy (Canon) on Jul 21, 2001 at 15:17 UTC
    I wrote an article that might help you here. "List" is a Four-Letter Word, found on my web site.

    Jeff japhy Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: difference between ($scalar) and $scalar
by elbie (Curate) on Jul 21, 2001 at 15:48 UTC
    It is a difference between the list and scalar contexts. Your pattern matching operation will return a list, but if the assignment is to a scalar (as it is in the second case) then you only get the scalar value of the list. i.e. The number of elements in the list. In this case, that's the number of matches made.

    If the assignment is made to a list, which you can explicity do by putting the brackets around the variable as in your first case, then you will get the elements of the left hand side's list (in this case, the one variable $rcs) matched up with the elements of the right hand side (the matches from the regexp) on a one-for-one basis until one side reaches the end of the list.

Re: difference between ($scalar) and $scalar
by DrZaius (Monk) on Jul 21, 2001 at 20:23 UTC
    This isn't really regarding the question, but have you considered doing this to get your version:
    my $rcs = (qw$Revision: 1.41$)[-1];
    Just a thought :)
      All of these responses have been incredible and an excellent education in perl. My final question before I say that I have sucked all I can learn from this thread...

      I toyed around with your coded to fully understand what was happening. I see that you're pulling the first element from the right using -1. However I see that it changes when I write it as:

      my $rcs = (qw($Revision: 1.46 $))[-2]

      Since I set the [ ] value to -2, I still get the correct value that I am looking for, however with my syntax and using -1 I retrieve just the $. Why is that? Since I am used to creating my arrays in the format qw(a b c); I would have thought these additional parens would not have changed the result. But they do.

      humbly -c

        Look at your spacing and what you are using for the qw delimiters.

        My code uses qw$$ while yours uses qw().

        Try these:

        perl -e 'my $rev = (qw$Revision: 1.41 $)[-1]; print $rev, "\n"' perl -e 'my $rev = (qw($Revision: 1.41 $))[-1]; print $rev, "\n"'
Re: difference between ($scalar) and $scalar
by merlyn (Sage) on Jul 22, 2001 at 02:36 UTC