The remainder of this meditation deals with what I believe is pretty much undefined behavior resulting from context mismatched code. For all of the following examples, assume that strictures and warnings are turned on.
Start by considering the following:
my $a; $a = ( 1, 2, 3 );
The actual (and defined) behavior of using the comma operator in scalar context, according to perlop is to assign the rightmost value to $a. We're all used to this by now (hopefully).
Now consider this code:
my ( $a, $b, $c ) = 1;
perlop doesn't seem to comment on what happens when you assign a single scalar value to a list, but the actual behavior is for $a (the first element of the lvalue list) gets set to 1. The other elements remain undeffed.
If you do it this way:
my ( $a, $b, $c ); ($a, $b, $c) = (1, 2, 3); ($a, $b, $c) = 1;
You can see that the assignment is actually pretty much doing as expected; assigning 1 to the first list element, and assigning undef to the rest of the elements.
Now try something bizzarre:
my ( $a, $b, $c ) = (1, 1, 1); ( $a, $b, $c ) += 1;
What do you get? Two warnings are generated (the same warning, twice): Useless use of private variable in void context at.... And the surprise now is that the last element is what got incremented. $c is now 2. The others are still 1.
I'm actually happy to see a warning here. But I'm surprised to find that the third element is now what got incremented. Undefined behavior, perhaps. Good thing there's a warning!
For what its worth, try this code too:
my ( $a, $b, $c ) = ( 1, 1, 1 ); ($a, $b, $c)++;
Now you get the same two warnings, plus a compilation error: Too many arguments for postincrement (++) at.... Bravo, I wanted an error here; there simply can't be any basis for DWIM in this case.
Ok, hold onto your hats, let's introduce hash slices (array slices behave similarly, but I was just playing with hashes today, that's all)...
my %hash = ('a'=>1, 'b'=>1, 'c'=>1); @hash{'a'..'c'} = 2;
This has the effect of assigning 2 to $hash{'c'}. ...the last first element in the slice. Remember, ($a, $b, $c) = 2; assigns 2 to the first element. This represents, what I consider, inconsistant behavior. By the way, just as expected, the elements remaining elements were all assigned undef as their value. Update: This case was a false alarm.
Now try this:
my %hash = ( 'a'=>1, 'b'=>1, 'c'=>1 ); @hash{'a'..'c'}+=1;
Here, we add-assign the last element of the hash slice, $hash{'c'}, and the other two remain 1. So += is consistant inconsistant with =.
And here's the last test:
my %hash = ( 'a'=>1, 'b'=>1, 'c'=>1 ); @hash{'a'..'c'}++;
Here, we also increment the last item of the hash slice; 'c' becomes 2.
However, assignment of a scalar to a hash or array slice results in the last first element of the slice taking the value, and other elements being given a value of undef. But....
But performing += additive assignment to a hash or array slice doesn't result in a warning, and still, the last element is the one that changes. The rest stay unchanged.
Autoincrement performed on a hash or array slice results in the last element being incremented, and no warnings or errors are generated.
I don't know what to think of it all. Most of it seems to be completely undocumented. My biggest issues are: (1) inconsistancy in outcome, and (2) inconsistancy in warnings/errors.
Update: My testing was done with Active State Perl v5.8.1 on a WinXP system with use strict; and use warnings; set. I am seeing comments in CB that some are seeing differing results.
Thanks bart and antirice for double-checking my work. All those tests upon tests, I misread one of them. My points on all other issues aside from the assignment operator (=) seem to remain valid still.
I think that at minimum, slices, and pure lists should behave the same with respect to which elements get affected, and with respect to what warnings are issued when using += and ++.
Dave
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Fringe case slice behavior
by Abigail-II (Bishop) on Jan 13, 2004 at 10:12 UTC | |
|
Re: Fringe case slice behavior
by bart (Canon) on Jan 13, 2004 at 08:23 UTC | |
|
Re: Fringe case slice behavior
by TimToady (Parson) on Jan 13, 2004 at 18:21 UTC | |
by BrowserUk (Patriarch) on Jan 13, 2004 at 21:10 UTC | |
by TimToady (Parson) on Jan 14, 2004 at 02:17 UTC | |
by BrowserUk (Patriarch) on Jan 14, 2004 at 02:37 UTC | |
by Abigail-II (Bishop) on Jan 13, 2004 at 21:22 UTC | |
by BrowserUk (Patriarch) on Jan 14, 2004 at 00:02 UTC | |
|
Sourcediving Challenge: Fringe case slice behavior
by Zaxo (Archbishop) on Jan 13, 2004 at 08:14 UTC | |
|
Re: Fringe case slice behavior
by ysth (Canon) on Jan 13, 2004 at 16:09 UTC | |
|
Re: Fringe case slice behavior
by tilly (Archbishop) on Jan 13, 2004 at 19:25 UTC | |
by ysth (Canon) on Jan 13, 2004 at 20:01 UTC | |
by Anonymous Monk on Jan 14, 2004 at 04:10 UTC |