in reply to Re^3: hash slice
in thread hash slice

I thought that seeing it on my screen would make it easier to understand. I'm missing something here. I was kind of expecting the array to be unchanged ... but that's not what happened:

$ perl -MData::Dumper -e '@x=0..10; undef @x[2..7]; print Dumper(\@x)' $VAR1 = [ 0, 1, 2, 3, 4, 5, 6, undef, 8, 9, 10 ];

Obviously, if undef worked as is otherwise expected, all numbers from 2 through 7 would be undef. What surprised me here is that 7 still is undef'd. Something funky is happening.

Not that I'd ever have this problem in production code - I don't ever have the need for this type of behaviour (undefing a slice)... and would have thought about using @x[2..7] = () first anyway.

Update: Yeah, Roy Johnson explained it - I see that now. However, it's still a bit buried, and Roy Johnson's lengthier explanation below is much clearer. Thanks, Roy!

Replies are listed 'Best First'.
Re^5: hash slice
by Roy Johnson (Monsignor) on Mar 10, 2005 at 17:56 UTC
    It may have not been there when you started to respond, since I tend to revise and expand my answers after posting, but I did explain the behavior you see. I agree that it is not what most people expect.

    The slice is being converted internally into a list: ($x[2]..$x[7]), and then that list is being evaluated in a scalar context, which means that it is not a list, but an expression with multiple comma operators. And the comma operator yields its right-hand side.

    Interestingly, defined works the same way, so defined(@x[2..7]) is the same as defined($x[7]). So at least when you undef a hash slice, testing it for definedness works as expected, even though several of the values are defined.

    I note again, you cannot provide a list to undef or defined. You get a compiler error. For defined, you can say

    defined scalar($x[2],$x[3]) or warn "not defined!";
    and it does the same as it does for a slice. But you can't use scalar() with undef, because scalar doesn't yield lvalues.

    Caution: Contents may have been coded under pressure.