Why does this work?

Why does this work?

am 21.05.2008 00:53:10 von Barry Brevik

OK, I've stumped myself. I wanted to assign 0 to several variables,
except for a single variable that should be set to 1.

Before I knew what I was doing I whipped this code into my editor:

($frow = $ax = $bx = $cx = 0)++;

....and it works as I expected. That is, all of the variables are set to
0 except $frow which is 1.

Now I'm afraid that it might not always work because I don't understand
why it works in the first case. Anyone want to suggest if this is stable
code or not?

Barry Brevik

_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Re: Why does this work?

am 21.05.2008 01:09:09 von Jenda Krynicky

From: "Barry Brevik"
> OK, I've stumped myself. I wanted to assign 0 to several variables,
> except for a single variable that should be set to 1.
>
> Before I knew what I was doing I whipped this code into my editor:
>
> ($frow = $ax = $bx = $cx = 0)++;
>
> ...and it works as I expected. That is, all of the variables are set to
> 0 except $frow which is 1.
>
> Now I'm afraid that it might not always work because I don't understand
> why it works in the first case. Anyone want to suggest if this is stable
> code or not?

It will always work, but you should not do it like this.

$frow = 1;
$ax = $bx = $cx = 0;

would be much cleaner.

It works because the assignment "returns" not the value, but the
variable. That is

($x = 7)++;

is not equivalent to

$x = 7;
7++;

but to

$x = 7;
$x++;


There are few cases when this is actually fine to use, one of them is

($newvar = $oldvar) =~ s/some/transformation/;

in this case again, you assign the value of $oldvar to $newvar and
then apply the s/// to the $newvar.

Jenda



===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery

_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Re: Why does this work?

am 22.05.2008 12:14:45 von casteele

On 20 May 2008 at 15:53, Barry Brevik wrote:

> OK, I've stumped myself. I wanted to assign 0 to several variables,
> except for a single variable that should be set to 1.
>
> Before I knew what I was doing I whipped this code into my editor:
>
> ($frow = $ax = $bx = $cx = 0)++;
>
> ...and it works as I expected. That is, all of the variables are set
> to 0 except $frow which is 1.
>
> Now I'm afraid that it might not always work because I don't
> understand why it works in the first case. Anyone want to suggest if
> this is stable code or not?
>
> Barry Brevik

It works (but is not a good way of doing what you want to do!) because the only way for Perl
to properly evaluate something like "$x = $y = $z = 0" is by making assignment a side effect
of the "=" operator, and making the "=" operator return the variable assigned. You read that
right: Assigning a value to a variable is only a side effect of the "=" operator, not it's primary
operation. It's primary operation is to return the variable that was assigned! (That is also why
you can do something like "somefunction($x = 4);", which is the same as "$x = 4;
somefunction($x);")

The code you wrote is the same as:

($frow = ($ax = ($bx = ($cx = 0))))++;

Breaking that down, you'll have..

After evaluating "($cx = 0)" and replacing it with "$cx"
($frow = ($ax = ($bx = $cx)))++;

After evaluating "($bx = $cx)" and replacing it with "$bx"
($frow = ($ax = $bx))++;

After evaluating "($ax = $bx)" and replacing it with "$ax"
($frow = $ax)++;

After evaluating "($frow = $ax)" and replacing it with "$frow"
$frow++;

The last I think you can figure out for yourself..


_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs