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

Why does
my @list = qw/The quick brown fox/; print @list,"\n";
give
Thenewbrownfox
and
use CGI (:all) @list = param(),"\n";
give
1
or some other number depending on the number of parameters passed?

Replies are listed 'Best First'.
(MeowChow) Re: Newbie question No.2
by MeowChow (Vicar) on Jun 05, 2002 at 00:56 UTC
    Operator precedence; your code is equivalent to:
    (@list = param()), "\n";
    because "=" is higher precedence than ",".
       MeowChow                                   
                   s aamecha.s a..a\u$&owag.print
Re: Newbie question No.2
by yodabjorn (Monk) on Jun 05, 2002 at 04:32 UTC
    Everyone has answered the why, but an easy way to get your desired result is to use join.
    my @list = qw/The quick brown fox/; print join(" ", @list ), "\n";
    outputs:
      The quick brown fox 

      an even easier way is to set $"=" ", which is the "list separator" (i.e. what character to use when a list is printed inside double quotes)
      $"=" "; @list = qw/The quick brown fox/; print "@list\n";

      thor

        The capital E Easier way is to join, just as yodabjorn suggested. If you go mucking about with $", you're liable to break things, due to the fact that $" is a global variable. Since that's like changing the value of pi, which would cause bridges to fall down, and dams to burst, somewhere else in that program there may be a piece of code that expects the default behavior and it won't work properly any more. join, of course, has no such "action at a distance".

        If you absolutely must do this, declare your $" to be local:
        local $" = " ";
Re: Newbie question No.2
by beernuts (Pilgrim) on Jun 05, 2002 at 01:37 UTC
    Your first one is answered by 'perldoc perlop' {earlier posts about perldoc notwithstanding... =-) }

    qw/STRING/
      Evaluates to a list of the words extracted out of STRING,
    using embedded whitespace as the word delimiters. It can be 
    understood as being roughly equivalent to:
    
       split(' ', q/STRING/);
    
    the difference being that it generates a real list at 
    compile time. So this expression:
       
       qw(foo bar baz)
    
    is semantically equivalent to the list:
    
       'foo', 'bar', 'baz'
    

    Sooo, since whitespace is the delimiter for qw, you get 'Thequickbrownfox' when you print out the array.

    Try this:

    foreach(@list){
       print "$_ "
    }
    print "\n";
    

    Note, that this actually prints:

    'The quick brown fox ' (trailing space), but it illustrates the idea. Best of luck!

    -beernuts

Re: Newbie question No.2
by tadman (Prior) on Jun 05, 2002 at 01:00 UTC
    Your second example, for me, seems to work just fine:
    #!/usr/bin/perl -w use strict; use CGI qw[:all]; my @list = param(),"\n"; print @list;
    When run like this:
    % perl test 'this=is&a=big&test=ok'
    Returns 'thisatest' as expected.

    Note that your example used '(:all)' with out qw(), which doesn't seem to be correct.
Re: Newbie question No.2
by BrowserUk (Patriarch) on Jun 05, 2002 at 01:36 UTC

    Sorry! I should know better than to type example code instead of cut & pasting it. Here is the actual code I was using.........

    #!e:/Perl/bin/Perl.exe use strict; use diagnostics; #use CGI qw( :all ); use CGI::Pretty qw( :all ); my @test_list = qw/the quick brown fox/; print @test_list, "\n"; print "Have parameters\n" if param; my @params = param(); print @params. "\n";
    which gives
    C:\www\NB.biz\html>menu.pl "a=1&b=2&" thequickbrownfox Have parameters 2

    The result is that I now notice I have a "." (dot) after @params in the print line instead of a "," (comma)!

    Thanks for your help guys.

      Context, context, context;) The print function accepts either a list or a scalar. The '."\n"' you are using in the second example forces scalar context, which will return the number of items in the array.

      Changing the dot(.) operator to a comma (,) will give print a list context to work with.