subroutines return values

B

Brad Baxter

Consider the code below. My admittedly superficial understanding makes me
think that line 7 says essentially, "Copy the value of $right to $left."

My intuition, based on statements in documents like `perldoc perlsub`,
makes me wonder if line 10 may, on the other hand, mean something like,
"Copy the value of $right to the holding area where subroutine return
values are processed, and then copy the value from this holding area to
$left."

I ask only to get an idea of what might happen if the value of $right we
very large. I.e., would there not only be a copy of this hypothetical
large value in $right and $left, but also in this "holding area" (which
I'm not sure actually exists).

Thanks,

Brad

1 #!/usr/local/bin/perl
2 use warnings;
3 use strict;
4
5 our( $left, $right ) = ( 'left', 'right' );
6
7 $left = $right;
8 print $left;
9
10 $left = right();
11 print $left;
12
13 sub right{ $right }
 
S

Sisyphus

Brad said:
1 #!/usr/local/bin/perl
2 use warnings;
3 use strict;
4
5 our( $left, $right ) = ( 'left', 'right' );
6
7 $left = $right;
8 print $left;
9
10 $left = right();
11 print $left;
12
13 sub right{ $right }

Make line 13:
sub right {return $right}

Then, at line 10, $left gets assigned to it the value returned by the
'right()' subroutine. So line 11 should print 'right' because that's the
value that the 'right()' subroutine returned. Right ??
:)

The way you had line 13 written it wasn't returning anything.

Cheers,
Rob
 
J

Jay Tilton

: Brad Baxter wrote:
:
: > 13 sub right{ $right }
:
: Make line 13:
: sub right {return $right}
[snip]
:
: The way you had line 13 written it wasn't returning anything.

That is incorrect.

From perlsub:

The return value of a subroutine is the value of the
last expression evaluated.
 
U

Uri Guttman

S> Make line 13:
S> sub right {return $right}

and how does that change anything? the first version just returns the
last evaluated expression.

S> The way you had line 13 written it wasn't returning anything.

no, he did it correctly. there was something else going on.

uri
 
S

Sisyphus

Uri said:
S> Make line 13:
S> sub right {return $right}

and how does that change anything? the first version just returns the
last evaluated expression.

S> The way you had line 13 written it wasn't returning anything.

no, he did it correctly. there was something else going on.

uri

Oh ... thanks for the correction uri, Jay.

Cheers,
Rob
 
L

LaDainian Tomlinson

Brad Baxter said:
Consider the code below. My admittedly superficial understanding makes me
think that line 7 says essentially, "Copy the value of $right to $left."

[ line 7: $left = $right; ]
My intuition, based on statements in documents like `perldoc perlsub`,
makes me wonder if line 10 may, on the other hand, mean something like,
"Copy the value of $right to the holding area where subroutine return
values are processed, and then copy the value from this holding area to
$left."

[ line 10: $left = right(); ]
I ask only to get an idea of what might happen if the value of $right we
very large. I.e., would there not only be a copy of this hypothetical
large value in $right and $left, but also in this "holding area" (which
I'm not sure actually exists).

<snip code>

I'm not completely positive about the Perl compiler/interpreter, but I think
I'm safe in assuming that it uses a memory stack to keep up with the data
currently in scope (ignoring static or global data, which may be somewhere
else entirely). Your variables $left and $right are really just spots on
the stack.

When you say '$left = $right;', you're telling the compiler 'look in the
address on the stack (or wherever) pointed to by $right, take that value,
and stick it in the spot on the stack (or wherever) pointed to by $left'.
The exact way that you 'stick it' varies depending on the data type:
sometimes a copy of the data is made, sometimes you get a reference to the
original data.

When you say '$left = right();', the call to right() allocates some more
memory on top of the stack where it's local variables reside (in this case,
it has none). Every subroutine's stack frame has a place on it for the
return value of the subroutine. The _calling_ subroutine knows where to
find this value after the _called_ subroutine exits. In your example, the
return value happens to be $right. So the compiler looks for a spot in the
current stack frame labelled '$right', doesn't see it, backs up one frame,
finds it there, and copies the value to the return value's place in the
current stack frame (i.e., right()'s stack). When the subroutine exits, the
calling code knows where to find that return value and sticks it in $left's
spot on the stack. So your 'holding area' doesn't exist as you mean it, but
there is a short time period where $left does not necessarily contain the
value returned by right() (a few clock cycles at most). After that, the
memory that was occupied by right() is available for allocation again, and
so the slot for the return value is garbage.

I hope this clears things up a little, since it's awfully long-winded.

Brandan L.
 
S

Steve Grazzini

Brad Baxter said:
Consider the code below. My admittedly superficial understanding
makes me think that line 7 says essentially, "Copy the value of
$right to $left."
Right.

My intuition, based on statements in documents like `perldoc
perlsub`, makes me wonder if line 10 may, on the other hand, mean
something like, "Copy the value of $right to the holding area where
subroutine return values are processed, and then copy the value
from this holding area to $left."

That's partially correct. When you say "return $x" from a normal
(non-lvalue) subroutine, it means "return a temporary copy of $x".

If $x is a string, the actual string will be copied...
I ask only to get an idea of what might happen if the value of
$right we very large. I.e., would there not only be a copy of
this hypothetical large value in $right and $left, but also in
this "holding area" (which I'm not sure actually exists).

But this won't happen. Perl checks for that (very common) case
in order to avoid copying the temporary string.
 
T

Tad McClellan

Steve Grazzini said:
But this won't happen. Perl checks for that (very common) case
in order to avoid copying the temporary string.


And what the OP calls the "holding area" is most usually
called "the stack".
 
B

Brad Baxter

<snip text>

When you say '$left = $right;', you're telling the compiler 'look in the
address on the stack (or wherever) pointed to by $right, take that value,
and stick it in the spot on the stack (or wherever) pointed to by $left'.
The exact way that you 'stick it' varies depending on the data type:
sometimes a copy of the data is made, sometimes you get a reference to the
original data.

<...> So your 'holding area' doesn't exist as you mean it, but
there is a short time period where $left does not necessarily contain the
value returned by right() (a few clock cycles at most). After that, the
memory that was occupied by right() is available for allocation again, and
so the slot for the return value is garbage.

I hope this clears things up a little, since it's awfully long-winded.

Yes, thanks to all for the answers. I conclude that I can likely not
worry about the details and trust perl (the program) to do the right/best
thing in a situation like this.

What prompted this was my desire to make access methods for a class as
efficient as possible. For instance, if I know an object's attribute is
very large, I might choose to return a reference to it instead of
returning it's value. I think now it's probably a bad idea in general,
and the instances where this will happen rare.

Regards,

Brad
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,298
Messages
2,571,542
Members
48,284
Latest member
RedaBruno6

Latest Threads

Top