> -----Original Message-----
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED] On 
> Behalf Of Stump, Gary
> Sent: Wednesday, August 03, 2005 1:27 PM
> To: [email protected]; 
> [EMAIL PROTECTED]
> Subject: RE: Return to Sender (w/apologies to Elvis)
> 
>  
> 
> > -----Original Message-----
> > From: [EMAIL PROTECTED] 
> > [mailto:[EMAIL PROTECTED] On 
> > Behalf Of Lloyd Sartor
> > Sent: Wednesday, August 03, 2005 10:19 AM
> > To: [EMAIL PROTECTED]
> > Cc: [email protected]
> > Subject: Re: Return to Sender (w/apologies to Elvis)
> > 
> > [EMAIL PROTECTED] wrote on 08/03/2005 08:16:53 AM:
> > 
> > > I have a subroutine which is supposed to return a reference to an 
> > > array. All this subroutine does is call another sub (i.e.: it's a 
> > > wrapper), which returns the array that the first sub then has to 
> > > return the reference to. Isn't there a one-liner way of 
> doing this? 
> > > I was using: 
> > > 
> > > sub outer_sub { 
> > >    @ret_ary = _inner_sub(); 
> > >    return( [EMAIL PROTECTED] ); 
> > > } 
> > > 
> > > where the returned value from _inner_sub is an array: 
> > > 
> > > sub _inner_sub { 
> > >    # create @inner_ret_ary. . . 
> > >    return( @inner_ret_ary ); 
> > > } 
> > > 
> > > which worked fine. But, when I tried to streamline 
> > outer_sub like this: 
> > > 
> > > return( \_inner_sub()); # _inner_sub just returns @ 
> > > 
> > > with the same return value (an array)  from _inner_sub, it fails. 
> > 
> > The one-liner attempt is returning a reference to the 
> > subroutine. You can 
> > create an anonymous list in outer_sub using the bracket 
> > syntax and return 
> > its reference:
> > 
> > sub outer_sub { 
> >    # @ret_ary = _inner_sub(); 
> >    # return( [EMAIL PROTECTED] ); 
> >    return([_inner_sub()]);
> > } 
> 
> 
> When I play with the "outer_sub" return a little I got the following
> results (from ActiveState build 638 on a MS Windows XP system):
> 
> #   return [ _inner_sub() ];
> #     calls _inner_sub in a LIST context and returns a ref to an
> #     anonymous array created from the returned list.
> # 
> #   return _inner_sub();
> #   return ( _inner_sub() );
> #     calls _inner_sub in a SCALAR context and so returns the 
> #     length of the list returned.
> #
> #   return \_inner_sub();
> #   return \( _inner_sub() );
> #     calls _inner_sub in a LIST context and returns a 
> #     reference to the last element of the list.

Apologies. The above is misleading because it neglects the fact that the
'return' provides the same context for its expression that its
subroutine was called with. This means that the above information is
correct if "outer_sub" is called in a scalar context since the
presumption was that "outer_sub" is going to return a reference.

############### revised version ###################

- return [ _inner_sub() ];
     calls _inner_sub in a LIST context and evaluates [...] expression
to a ref to an anonymous array created from the _inner_sub list. The
calling code evaluates this scalar value within its context. If
"outer_sub" is called in a scalar context, the reference to the array is
returned. If "outer_sub" is called in a list context, it will treat it
as a 1-element list.

- return _inner_sub(); or
- return ( _inner_sub() );
     calls _inner_sub in a the same context as outer_sub. Returns the
length of the list in a scalar calling context, just as if the
_inner_sub list were an array, and, in a list calling context, the
_inner_sub list of values. Essentially the same as calling _inner_sub
directly.

- return \_inner_sub(); or
  return \( _inner_sub() ); or
  return ( \_inner_sub() ); or
  return \&_inner_sub();
     calls _inner_sub in a LIST context regardless of the calling
context of "outer_sub", applies the \ operator to each element of the
list then treats the result as a "list". In a scalar context, a
reference to the last element is returned. In a list context, a list of
references to each element of the _inner_sub list is returned. A
difference between lists and arrays is that, in a scalar context, a list
evaluates to the last element while an array evaluates to its length.

- return \&_inner_sub;
     does not call _inner_sub. Returns a ref to the _inner_sub code
value. This happens only there is no argument list passed. The calling
code treats the CV ref value according to its context, i.e. as a scalar
value or a 1-element list.

- return \_inner_sub;
     compiler error if strict subs is in use (_inner_sub is a bareword).
If "no strict 'subs'" then doesn't call _inner_sub but returns a
reference to a scalar string '_inner_sub' (a bareword default).

- return _inner_sub;
     compiler error if strict subs is in use (_inner_sub is a bareword).
If "no strict 'subs'" then doesn't call _inner_sub but returns a string
value of '_inner_sub' (a bareword default).

########### end revised version ###################

Operator precedence comes into play here in that the "_inner_sub()"
expression is evaluated before the \ operator so it operates on the
returned list rather that getting the address of the subroutine.

We always get a list from "_inner_sub". Perl does not allow getting a
reference to a list. We can get a ref to an array but not a list. The
only option for getting a ref to the list is to use the list to build an
array value and get a reference to that array. A real, actual array is
always stored in an AV value in dynamic memory and in a single,
identifiable data struct in a single, consistent format that must always
be pointed to by at least one reference value or a variable name in
order to continue to live, thus always providing at least one name with
which to identify it. But Perl provides no means of attaching any
identifier to a list. (One sort of exception to this is '@_', the
magical argument list/array value.) The way lists are handled internally
also does not lend itself to allowing one to be readily pointed to or
otherwise identifed.

I had thought that putting something inside () changed the context to a
list context under more circumstances than it seems to. A disadvantage
of Perl is that its context dependence sometimes means that the
"obvious" isn't always obvious, or even true, unless you have finally
learned the all the rules.

> _______________________________________________
> ActivePerl mailing list
> [email protected]
> To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
> 

_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to