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...
- Why are the comma's excluded in some spots and not others?
- How does this work with your own prototypes and subroutines?
- Which perldoc covers this in depth?
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
| [reply] [d/l] [select] |
|
#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? | [reply] [d/l] |
|
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
| [reply] [d/l] [select] |
|
zer: 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
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
| [reply] [d/l] [select] |
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 | [reply] [d/l] [select] |
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. | [reply] [d/l] [select] |
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!
| [reply] [d/l] [select] |
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
| [reply] [d/l] [select] |
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;
| [reply] [d/l] |
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.
| [reply] [d/l] [select] |
|
|