Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Comma's and blocks

by zer (Deacon)
on Oct 04, 2007 at 05:41 UTC ( [id://642569]=perlquestion: print w/replies, xml ) Need Help??

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

Good morning,

I have come across some interesting questions from some friends on the use of comma's within the perl language. It appears that arguments for all subroutines are comma delimited. However when you come accross map/grep it changes

map {/dothis/} @variable; grep {/more stuff/} @more;
The proper formating is for blocks to be without a comma. Then with non-blocked items it would return to the comma. Another example is with the print statement.

open (A, ">File") or die; print A "hello"; print $somevar, "can be seperated like this";
So in this portion you are sending a file handle and it doesnt accept a comma. If you were to use seek it would be comma seperated. Which makes me ask...

  1. Why are the comma's excluded in some spots and not others?
  2. How does this work with your own prototypes and subroutines?
  3. Which perldoc covers this in depth?

Replies are listed 'Best First'.
Re: Comma's and blocks
by erroneousBollock (Curate) on Oct 04, 2007 at 06:05 UTC
    Why are the comma's excluded in some spots and not others?
    They're not excluded... you may have completely misunderstood some of the syntactic forms.

    map {/dothis/} @variable; grep {/more stuff/} @more;
    That's roughly equivalent to:
    map(sub {/dothis/}, @variable); grep(sub {/more stuff/}, @more);
    except that map() and grep() play with $_ on your behalf.

    As for:

    print A "hello"; print $somevar, "can be seperated like this";
    The second print statement is equivalent to
    print STDOUT $somevar, "can be seperated like this";
    .. unless you've called select() to change which is the default filehandle.

    How does this work with your own prototypes and subroutines?
    Prototypes allow the Perl parser to apply (for your subs) the same parser tricks it employs on built-in functions (like push()).

    Which perldoc covers this in depth?
    perlsyn, perlsub, perlfunc should do it.

    -David

      David,

      Thanks for the response! The map and grep is a lot clearer (kind of).

      #ex 1 map (sub {/dothis/},@_); map {/and this/}, @_; #now doesnt compile #ex 2 print STDOUT "hello"; print <STDOUT> , "Hello"; #runs
      In the above example. The first line is making sense and opened my eyes to that for the map. As well the print uses a comma when a proper file handle '<' and '>' are used. Why do the use of proper terms affect the use of commas?
        print <STDOUT> , "Hello"; #runs
        That doesn't do what you think.

        <STDOUT> reads from the STDOUT filehandle (which won't do anything useful).

        You can't put a comma between the file-handle and the printable content, the syntax is not short for any other syntax.

          print HANDLE expression

        is the normal form.

          print expression

        is parsed by perl to mean   print LATESTHANDLE expression

        where LATESTHANDLE is the last handle given to select() (the default is STDOUT).

        -David

        zerAs well the print uses a comma when a
        proper file handle '<' and '>' are used. Why do the use of proper
        terms affect the use of commas

        As has been said in another response,
        the  print <STDOUT> , "Hello";
        invokes reading a filehandle in list context and printing
        the result afterwards - but *not* through your "proper file handle" ;-)
        It has probably also been noted elswhere
        that this is like  print STDOUT <STDOUT>, "Hello";

        The notation print filehandle LIST stems (IIRC) from the
        "indirect object notation", like  $q = new CGI; #(no comma)
        which would, in "direct" object notation read:  $q = CGI->new()

        From this point of view, the file example might be equivalent
        to  STDOUT->print("Hello"); #, which indeed is the case.
        The above idioms can be used in Perl after including the IO::Handle
        module, then it'll look like (pseudocode):
        # from http://perldoc.perl.org/IO/Handle.html $io = new IO::Handle; # indirect object notation +! if ($io->fdopen(fileno(STDOUT),"w")) { $io->print("Hello"); # direct object notation! }
        See: IO::Handle documentation

        Regards
        mwa
Re: Comma's and blocks
by johngg (Canon) on Oct 04, 2007 at 08:48 UTC
    Note also that there are two ways to write a map, viz map { block } list and map expression, list.

    $ perl -le ' -> @arr = qw{a b c}; -> map { tr/[a-z]/[A-Z]/ } @arr; -> print qq{@arr};' A B C $ perl -le ' -> @arr = qw{a b c}; -> map tr/[a-z]/[A-Z]/, @arr; -> print qq{@arr};' A B C $

    Cheers,

    JohnGG

Re: Comma's and blocks
by oha (Friar) on Oct 04, 2007 at 10:24 UTC
    that's not so strange in computer languages, in C:
    if (COND) BLOCK
    as you can see, there are no commas and if BLOCK is surrounded by {} you can avoid the semicolon, too.
    Same applies to for, while.

    The only difference between those languages and perl1 is that perl allow more freedom: in some cases you can avoid (), there are more tokens which means the same (for, foreach), and the same token may have more available syntaxes (if (COND) { BLOCK },  EXPR if COND;) and so on. Probably Wirth would not like it, but i don't like pascal, so... :)

    Oha

    1 - The OP didn't compared perl to other langs, but i hope this diversion can be partially OT.

Re: Comma's and blocks
by naikonta (Curate) on Oct 04, 2007 at 16:46 UTC
    Well, what can I say. The syntax description for map is,
    map BLOCK LIST map EXPR,LIST
    If you use the block version, {}, then you don't need a comma. You do need a comma if you use the expression version. If you really like the block version, then just take it as a convenience. Further reading of the doc says,
    "{" starts both hash references and blocks, so "map { ..." could be either the start of map BLOCK LIST or map EXPR, LIST. Because perl doesn’t look ahead for the closing "}" it has to take a guess at which its dealing with based what it finds just after the "{". Usually it gets it right, but if it doesn’t it won’t realize something is wrong until it gets to the "}" and encounters the missing (or unexpected) comma.

    Hope it's clear now why map {/and this/}, @_; won't even compile.


    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re: Comma's and blocks
by Anonymous Monk on Oct 04, 2007 at 14:03 UTC
    print A "hello";

    Is actually a strange form of indirect method invocation, except that its a special case in that you can use it without using any modules, and that the method form *requires* you to use the IO::Handle module before it is used. (This will hopefully not be necessary to do in 5.10.1). In other words it is much the same as saying my $obj=new Class::Name

    demerphq using a computer he cant be bothered to log in from

Re: Comma's and blocks
by bsb (Priest) on Oct 05, 2007 at 02:44 UTC
    The & prototype and a comma causes problems with Data::Rmap:
    rmap { print }, 1..3; ^-------- bad news, you get and empty list: rmap(sub { print $_; }), 1..3;
Re: Comma's and blocks
by mrpeabody (Friar) on Oct 04, 2007 at 20:06 UTC
    First off, it's "commas", not "comma's".
    Why are the commas excluded in some spots and not others?

    Because of choices the designers made, either to reduce ambiguity or reduce typing. You always need a comma, except in the cases you noted: map, grep, and print FILEHANDLE.

    How does this work with your own prototypes and subroutines?

    Your own subroutines need commas between their arguments, with one exception. When using the & prototype in the first position and calling the subroutines without parentheses, you may use for that argument a plain BLOCK, rather than "sub BLOCK" followed by a comma. (Note that the reverse is NOT true; map( sub {$_ + 1}, 1, 2, 3 ) will produce a list of code references instead of (2, 3, 4).)

    99% of the time you don't need prototypes anyway.

    Which perldoc covers this in depth?

    For how to call built-in functions, see perlfunc. For how to write prototypes and subroutines, see perlsub.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://642569]
Approved by graff
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2024-04-19 07:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found