[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] wantarray() Function Question



At 9:37 AM -0800 1/13/00, Ronald J Kimball wrote:
>On Wed, Jan 12, 2000 at 08:56:20PM -0800, Bruce Van Allen wrote:
>> In response to a question from sleidy@voicenet.com:
>> At 7:31 PM -0800 1/12/00, blm@halcyon.com wrote:
>> >|my(@the_Time) = &hms();
>> >|my($the_Time) = &hms();
>> >
>> >Read the "Private Variables via my()" section in perlsub.pod while thinking
>> >about the above lines.
>> >
>>
>> But don't stare too hard at the 'my' part of it. The point is that having
>> the scalar $the_Time in my's parentheses (at the time you assign the value
>> from &hms() to it) makes it an element in an array, so wantarray() returns
>> true...
>
>To be precise...  The parentheses around $the_Time make it part of a list,
>not of an array.  The builtin wantarry() was misnamed; it should have been
>wantlist() instead.
>
>Ronald

Yes, and I'm a first editioner (Camel book) and still mix up the terms (but
not the usage -- at least not any more than the usual programming thinkos
;-)

Let me see if I can state this correctly:

A. Values
The values of concern here are of two kinds in Perl (I'm not saying 'types'
because that means something different): 'scalar' and 'list' (which mean,
in effect, 'singular' and 'plural'). A scalar value may be an integer,
floating point number, exponential expression, string literal, constant,
etc., as well as a reference to any of these or anything else that Perl
lets us make references to (including lists). A list value is an ordered
series of zero or more values separated by commas; parentheses might or
might not be required to make sure the series of values are treated as a
list by functions and operators.

B. Variables
The Perl variables of concern here are 'scalar' and 'array' (there are
others). Scalar variables hold scalar values; that is, a scalar variable
holds a single value. Array variables hold... lists!

This statement assigns a list value to an array variable:

 @ary = ('a', 'b', 'c') ;
 ^^^^   ^^^^^^^^^^^^^^^
   ^          ^
   |          |
 array       list

C. Context
The Perl contexts of concern here are 'scalar'and 'list' (there are other
contexts, such as boolean). Scalar context expects a single value. List
context (before called array context) expects zero or more values
structured as a list.

Context is established by the, er, context in which a value is being used,
which may be set by Perl operators, built-in functions, and syntactical
structures. Array variables can tell if they are in list or scalar context,
yielding lists in list context and a single value in scalar context.
Well-written subroutines will also Do the Right Thing (and this was the
admirable goal of the original poster).

Context setting moves from left to right in a statement. [Is this always
true?] So, in the statements
  my $var = &some_sub;
  my ($var) = &some_sub;
nothing different happens to $var (it gets scoped), but the first puts
&some_sub into scalar context and the latter puts it into list context due
to the parentheses.

Aside.
The above statements show one of those features of Perl that is wonderful
but requires much care: the ability to scope a variable and assign a value
to it in one statement. For the purpose of my-ing a single variable,
there's no reason to have the parentheses. To my-scope several variables at
a time, my accepts a list of variables, and requires the use of parentheses
around the list or it will only scope the first variable in the list. If
values are being assigned to the variable(s), those parentheses have put
the assignee(s) into list context, so the source of the values being
assigned (&some_sub, on the right side of the = operator) is put into list
context.


So we have these terms:
  values:     'scalar' or 'list'
  variables:  'scalar' or 'array'
  context:    'scalar' or 'list'

[not counting the other kinds of variable and context]

My internal pattern spotter looks at that and equates 'list' and 'array'.

I think another reason I continue to mix up the terms 'array' and 'list' is
that for the most part we _can_ use arrays and lists the same way. E.g.:

  @ary = ('a', 'b', 'c');
  $j = $ary[2] ;            # $j gets the value 'c'.

  $j = ('a', 'b', 'c')[2];  # $j gets the value 'c'.


An idiom I use frequently is
  $_ = 'aa|bb|cc|dd|ee|';
  $item3 = (split /\|/)[2];  # $item3 gets the value 'cc'.
  $item3 = ( split(/\|/, $_) )[2];  # same thing de-obfuscated.

The exception I know of is
  @ary = ('a', 'b', 'c');
  $x = @ary;  # Scalar variable $x gets the value 3,
              # because in scalar context the array variable
              # @ary yields the number of its defined elements.

  $x = ('a', 'b', 'c');  # $x gets the value 'c', because the
                         # comma operator voids all but the last
                         # value of a list in scalar context.

Have I stated this correctly? Anything important missing? Obviously there's
more detail, especially about context.

Thanks for indulging me.






- Bruce

__Bruce_Van_Allen___bva@cruzio.com__Santa_Cruz_CA__

# ===== Want to unsubscribe from this list?
# ===== Send mail with body "unsubscribe" to macperl-request@macperl.org