Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re^2: Confused as to why the "casting context" is mis-behaving ("list vs array", again)

by andal (Hermit)
on Oct 21, 2010 at 08:04 UTC ( [id://866495]=note: print w/replies, xml ) Need Help??


in reply to Re: Confused as to why the "casting context" is mis-behaving ("list vs array", again)
in thread Confused as to why the "casting context" is mis-behaving

You can't even return an array in Perl (you can return a reference to an array and you can write "return @array;" but that returns (a copy of) the list of scalar values that are in the array).

This is not 100% correct. The array is returned from the function. But to get a hold of it, you should COPY it somewhere. Either in another array, or into list of variables. Or where ever.

perl -e 'sub test{my @a=qw(a b c); return @a} my $v = test(); print $v +,"\n"' perl -e 'sub test{return qw(a b c);} my $v = test(); print $v,"\n"' perl -e 'sub test{my @a=qw(a b c); return @a} my ($a, $v) = test(); pr +int $v,"\n"' perl -e 'sub test{my @a=qw(a b c); return (@a)} my $v = test(); print +$v,"\n"' perl -e 'sub test{my @a=qw(a b c); return (@a, "b")} my $v = test(); p +rint $v,"\n"'

Everything in perl becomes logical if you think about @abc as about OBJECT, and about list as COLLECTION of objects. So obtaining a slice from the array gives you collection of objects. grep or map work with collections of objects, so if you pass array to them, this array is turned into collection of objects. Of course, neither grep nor map can return array since they have only collection of objects as input.

Placing array as member into collection/list does not make this array disappear. It stays in the list as the object. But when the list is copied somewhere, then the array object might be replaced with its elements. Depends on the context.

  • Comment on Re^2: Confused as to why the "casting context" is mis-behaving ("list vs array", again)
  • Download Code

Replies are listed 'Best First'.
Re^3: Confused as to why the "casting context" is mis-behaving (return array)
by tye (Sage) on Oct 21, 2010 at 13:43 UTC
    This is not 100% correct. The array is returned from the function. But to get a hold of it, you should COPY it somewhere.

    No, the array is copied before the function returns. You can observe that:

    my @a= ( 'a' .. 'e' ); sub returnArray { return @a; } my @b= ( 'v' .. 'z' ); for( returnArray() ) { $_ .= '?' } for( @b ) { $_ .= '!' } print "@a\n"; print "@b\n"; __END__ a b c d e v! w! x! y! z!

    And it is also not true that the function returns and then (after that) the scalar context decides to get the size of the array while the list context decides to copy the elements of the array.

    The context gets passed in to the function, to the returning statement so that it can, when possible, avoid the work of creating a whole list of values just to throw that list away.

    The method of returning information from a Perl function is to push zero or more scalar values onto the stack. return @array;, if called in a list context, loops over the array and pushes onto the stack, a copy of each element of the array. If you assign the return value to an array, then that assignment operator loops over the items on the stack and puts them into the array (whether each value is copied again here or the array just gets aliases to each of the original copies is an implementation detail and a matter of optimization that I have never needed to worry about).

    - tye        

      No, the array is copied before the function returns. You can observe that:

      You missed the point. It does not make any difference when the array is copied, before or after the return. The point was, when the function returns, the caller "can know" that some array was returned. So it makes difference what you return from the function, array or list or scalar.

      If you just wanted to say, that the array seen by the caller is not the same object as the array that was given to "return", then you are absolutely correct. But this is true for any returned object. Even references to arrays are copied, they are not the same references as the returned variables. Of course they reference the same array, but they are not the same references. So arrays are not an exception to this rule. It is general feature of the language.

      By the way, your code examples don't prove that the copying happens before the return. They just prove, that the "for" loop works with copies of values. Nothing else. When those copies were made stays unclear :)

        The point was, when the function returns, the caller "can know" that some array was returned.

        You'll have to explain how, then. The caller can't know that an array was involved because the caller only gets a list of scalar values pushed onto the stack.

        By the way, your code examples don't prove that the copying happens before the return. They just prove, that the "for" loop works with copies of values. Nothing else.

        Half of the code proves that the 'for' loop gets copies. The other half of the code proves that 'for' loops don't get copies when using an array. That's one of the major features of 'for' loops: They work on aliases not copies when possible. When calling a function, working on aliases isn't possible (because what gets pushed onto the stack is copies of each scalar value).

        - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://866495]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (2)
As of 2024-04-26 01:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found