Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Re^3: Autovivification of scalars in sub calls

by Anonymous Monk
on Dec 08, 2005 at 22:01 UTC ( #515397=note: print w/ replies, xml ) Need Help??

in reply to Re^2: Autovivification of scalars in sub calls
in thread Autovivification of scalars in sub calls

Interesting. I knew that some builtins, like pos and keys, can be lvalues, but not that arguments to subs were. Come to think of it, I can't even say that I know what the expression "arguments to subs are lvalues" means. How is the argument in sleep( 3 ) an lvalue? Arguments to subs can be assigned to; they're lvalues in that sense. Therefore, you get these ugly situations:

my $var=3; mysleep($var); # these two lines are fine mysleep(3); # but this one causes an error!!! sub mysleep { sleep($_[0]); $_[0]=10; }
Or this ugly situation...:
$y=substr("hello",10,1); foo($y);# this runs, but substr() generates warnings because the subst +r() is outside the string foo( substr("hello",10,1) ); # this is a fatal error!

Why is it a fatal error? Well, because an invalid substr() is used in a lvalue context. Why is it an lvalue context? Because the subroutine *could* modify the value, and perl isn't smart enough to check to see if it does or not! Worse yet, substr() fails silently on such a fatal error, after generating the *same* warning that's nonfatal in a non-lvalue context. ***SIGH***

I've made it my policy to avoid lvalues() where possible, especially after that substr() issue killed our production code, and wasted a few hours of my time! --
Ytrew Q. Uiop

Comment on Re^3: Autovivification of scalars in sub calls
Select or Download Code
Re^4: Autovivification of scalars in sub calls
by truedfx (Monk) on Dec 09, 2005 at 11:51 UTC
    Perhaps also interesting is that lvalues remain lvalues even after passing them to the unary + operator.
    sub foo {} #foo(substr "hello", 10, 1); # fatal error as you pointed out #foo(+substr "hello", 10, 1); # I thought this would be a workaro +und foo(scalar substr "hello", 10, 1); # but you need something like this print "This only gets printed if the last line didn't cause a fatal er +ror\n";
    And testing to make sure:
    perl -e '+$a = "Hello, world!\n"; print $a' Hello, world!
    (I know it's documented that + does absolutely nothing, and I guess that does mean it doesn't convert lvalues to rvalues, but it's still somewhat surprising to me.)

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2014-09-17 06:10 GMT
Find Nodes?
    Voting Booth?

    How do you remember the number of days in each month?

    Results (60 votes), past polls