Item 9: Know common shorthands and syntax quirks .Perl is a "human" language in that it has a very context-dependent syntax. You can take advantage of this by omitting things that are assumed by the interpreter, for example, default arguments, $_ , and optional punctuation. Perl figures out what you really mean from the context. (Usually.) Perl is also a very high level language with an extremely rich and diverse syntax, but sometimes the various syntactic features don't fit together as well as they might. In some cases, you may have to help Perl along by resorting to a syntactic gimmick of one kind or another. Along these lines, here are some suggestions and some things to watch out for. Use for instead of foreachThe keyword for is actually a synonym for the keyword foreach , and vice versa. The two are completely interchangeable. Thus we have the commonly seen:
And, conversely:
Perl determines which kind of loop you have written by looking at something other than the keyword. (I guess that's kind of obvious.) Substituting for in place of foreach is a fairly innocuous and frequently used shorthand among more worldly Perl programmersI've done it here and there in this book. Swap values with list assignmentsPerl doesn't have a special " swap" operator, but you can always use a list assignment to the same effect:
Slices give you a convenient syntax for permuting the contents of an array:
Force a list context with [ ] or ( )[ ] if you have toIn some cases you may need to force an expression to be evaluated in a list context. For example, if you want to split a string captured by a regular expression memory, you might first write:
To write this in a single expression without the use of the temporary $str , you have to resort to trickery , because the pattern match would not return the right kind of value in the scalar context imposed by split :
If you want to take a reference to a list literal in a single step, use the anonymous array constructor [ ] . The reference operator \ applied to a list literal actually creates a list of references, not a reference to a list. (Don't ask me whythis one never made much sense to me. Also see Item 32.)
Use => to make initializers, and some function calls, prettierThe => operator is a synonym for the comma operator. There is one minor difference in functionality, which is that if the left-hand argument to => is an identifier by itself, it is always treated as a string. It will not be inter-preted as a function call. Thus you can use things like print to the left of => without fear:
Use => to make initializers prettier, if you like. This is especially appropriate when creating initializers for hashes:
You can simulate named parameters for function calls. Here is one simple way to do it:
This is discussed further in Item 27. Finally, here's another interesting use of => as syntactic sugar: rename "$file.c" => "$file.c.old"; Don't confuse => with -> , which is used for subscripting references (see Item 30) and method calls (see Item 50). Watch what you put inside { }Parentheses, square brackets, angle brackets, and braces all have multiple meanings in Perl. Perl uses the contents of the braces (or whatever) and the surrounding context to figure out what to do with them. Usually the result makes sense, but at times it may surprise you. Be especially careful with braces. Braces are used to enclose blocks, delimit variable names , create anonymous hashes, and as hash element and dereferencing syntax. It's dizzying if you think about it too hard. It's pretty scary that the interpreter can tell the difference between an anonymous hash constructor and a block! If you see a plus sign inside braces for no apparent reason, there probably is a reason for it. Perl's unary plus has no effect on its argument, but it does provide a fix for some syntactic problems: Suppose we want to dereference a function returning an array ref.
If you're unlucky, you might also run into a situation in which an anonymous hash constructor is confused with a block: Suppose we have a function that returns a list of key-value pairs that we want to use in an anonymous hash constructor.
And, finally, you should be aware that an identifier appearing all alone (possibly surrounded by whitespace) inside braces is taken literally as a string. [2] If it is the name of a function, the function is not called unless there is something other than just an identifier present:
Use @{[ ]} or eval { } to make a copy of a listSometimes you may want to perform a destructive operation on a copy of a list, rather than the original: Find .h files that are missing. @cfiles_copy = @cfiles; @missing_h = grep { s/\.c$/\.h/ and not -e } @cfiles_copy; Perl doesn't give you a function for making copies of things, but if you need to make an unnamed copy of a list, you can put the list inside the anonymous array constructor [ ] , then dereference it: Find .h files that are missing, but without making an explicit copy. @missing_h = grep { s/\.c$/\.h/ and !-e } @{[@cfiles]}; Another way to make a copy of something is to put it inside an eval block: @missing_h = grep { s/\.c$/\.h/ and !-e } eval {@cfiles}; Use the block form of eval in situations like this, not the string form, since the block form is much more efficient (see Item 54). |