... is a list, no wait a tuple, noooo whatever you want to get me is fine. As
its POD succinctly puts it, Want
is a generalization of wantarray. This means, if you are so inclined,
that instead of being limited to list/hash or scalar returns without the caller
explicitly telling you what it wants in @_ you can now offer a
smorgasborg of possibilities by relying upon that old perlish standby: context.
Want appears to have several advantages over wantarray beyond the variety of
contexts you can detect; I say appears because I'm not wholly familiar with
perl's guts or some of the features I'm about to relate. In particular:
- You can niftily determine the number of return values required
- Thus avoiding any unnecessary copying of large data structures, or allowing
you a novel/contextual manner to specify a limit for depth of recursion to
something like an implementation of the Fibonacci sequence.
- lvalues
- Among other things perlsub has the following to say about lvalues:
You can't use the return keyword, you must pass out the
value before falling out of subroutine scope. (see
comment in example above). This is usually not a
problem, but it disallows an explicit return out of a
deeply nested loop, which is sometimes a nice way out.
Want actually gives you a return for use within lvalue subs, of course it's
spelled differently...
Actually, speaking of lvalues the documentation says you'll get "Can't modify
non-lvalue subroutine call in lvalue subroutine return." if you have a lvalue
sub without an explicit return at the end. I actually see "Can't modify logical
and (&&) in lvalue subroutine return at want.pl line 30, near '}'" under perl
5.8.0 and unless my weary eyes deceive me I may have seen another one
altogether as well. So be careful of that. You're also supposed to use
rreturn for rvalue contexts with lvalued subs but it seems
return may work too under some circumstances.
A few final observations before I leave you with some sample code. First, note
that the current implementation interface is not stable; it is only 0.09, even
if it has taken 4 years to get there. Second, it's want('LIST') and
not want('ARRAY'). And finally, order apparently matters: do your
lvalue check first.
1 use Want;
2 use Lingua::EN::Numbers::Ordinate;
3
4 my @days = <DATA>;
5
6 sub days :lvalue {
7 if( want('LVALUE', 'ASSIGN') ){
8 my $n = shift;
9 $days[$n] = want('ASSIGN');
10 lnoreturn;
11 }
12 if( want('SCALAR') ){
13 my $str = '';
14 foreach( 1..12 ){
15 $str .= sprintf $days[0], ordinate($_);
16 $str .= join '', reverse(@days[1..$_]), "\n";
17 }
18 rreturn $str;
19 }
20 if( want('LIST') ){
21 my $n = shift || want('COUNT');
22 if( $n ){
23 rreturn @days[1..$n];
24 }
25 else{
26 rreturn @days;
27 }
28 }
29 return;
30 }
31
32 #Rewrite the lyrics
33 days(5) = "Five onion rings!\n";
34
35 #Stringified
36 print scalar days;
37
38 #Equivalent subsets
39 my @gifts = days(3);
40 my($gift1, $gift2, $gift3) = gifts;
41 (days)[1..3];
42
43 __DATA__
44 On the %s day of Christmas, my true love gave to me
45 A partridge in a pear tree.
46 Two turtle doves
47 Three French hens
48 Four calling birds
49 Five golden rings.
50 Six geese a-laying,
51 Seven swans a-swimming
52 Eight maids a-milking
53 Nine ladies dancing
54 Ten lords a-leaping
55 Eleven pipers piping
56 Twelve drummers drumming