Item 25: Use wantarray to write subroutines returning lists.You probably already know that subroutines can return either scalar or list values. Perhaps you have written both kinds of subroutine. You also probably understand the significance of scalar and list context in Perl. In an idle moment, you may have even wondered how something like the following worked: Create a sorted list of text files in a directory.
If you write something like: print join " ", sorted_text_files "/etc"; then you get the expected list of files. Because it's what you expect, you probably don't see anything magical about it. However, things are different if you instead write: print join " ", scalar(sorted_text_files "/etc"); In this case, you get no output . Maybe what's going will become more apparent if you change the last line, sort @files , to read @files = sort @files . Now, instead of nothing at all, you get a number. Hmm. What you are seeing is the result of the way that Perl evaluates the return value of a subroutine. The contextlist or scalarof the return value of a subroutine is determined by the context in which the subroutine is called . The context is noted when the subroutine is called, and that context is applied to whatever expression winds up as the return value. [5] If you need to know what the calling context is, you can use the wantarray operator, which returns true if the subroutine call appeared in a list context. Let's say that you want to modify the sorted_text_files subroutine so that it returns a join -ed list of filenames if evaluated in a scalar context. You could rewrite it like this:
Create a sorted list of text files in a directory (improved version).
The wantarray operator is also occasionally useful for answering questions. When I was writing the Idiomatic Perl section and wanted to find out whether grep 's block argument was evaluated in a scalar or list context, I wrote something like the following: sub how { print wantarray ? "arrayish" : "scalarish" } grep { how() } 1; If you run this, it produces the output: scalarish which pretty much settles the question. |