AGH. Silly mistakes

Thursday, March 18th, 2010 04:42 pm
afuna: Cat under a blanket. Text: "Cats are just little people with Fur and Fangs" (Default)
[personal profile] afuna
In my attempt to conquer Bug 2344: Default View/Default filters should be default when adding from hover menu, I wrote this line of code:

$success ||= $filter->add_row( userid => $u->id )

What I thought it said:

* add this user to the filter
* once you've added the user, check whether it was successful, and keep a running tab on the status so you'll know in the end whether everything succeeded or not

What it was actually saying:
* once you've successfully done one thing (e.g., added the user to a filter or subscribed to that user), we're done. We don't need to do anything else (in this case, adding a user to the filter).

So now I've rewritten it more properly as:

$success = $filter->add_row( userid => $targetu->userid ) && $success;

(I got the boolean logic initially wrong too *rueful*)


This was an entire afternoon's worth of frustration (whyyyyyyy isn't it adding the user to the filter? Why doesn't it print out any of my warn statements within add_row? I didn't realize I wasn't calling it at all), solved with one of those flashes of insight you get when you get up and grab a glass of water and happen to reread your code when you get back.

Date: 2010-03-18 01:14 pm (UTC)
yvi: Kaylee half-smiling, looking very pretty (Default)
From: [personal profile] yvi
Would it cheer you up if I told you I have no idea why that line is doing what it's doing?

Date: 2010-03-18 06:10 pm (UTC)
janinedog: (Default)
From: [personal profile] janinedog
It has to do with short circuiting, I think. Written out the long way, it'd be:

$success = $success || add_row

First time around, $success is 0 (I assume), so it checks $success, sees it's false, then goes to the next part and does the add_row and assigns the return value.

Second time around, $success is 1, so it checks $success, sees that it's true, and then doesn't even do add_row; since the first part is true, and it's an || operator, you don't have to check/do the second part.

At least, that's how I read it while not really awake yet. ;)

Date: 2010-03-18 06:11 pm (UTC)
yvi: my yellow leopard gecko, River (Geckos - River 2)
From: [personal profile] yvi
...

I didn't realize this of course had to be in a loop of some kind.

Let's just pretend I am not here ;)

Date: 2010-03-18 06:13 pm (UTC)
janinedog: (Default)
From: [personal profile] janinedog
Haha, no worries! :)

Date: 2010-03-18 06:12 pm (UTC)
poulpette: A man with a puzzled face (SoT - Richard o_ô)
From: [personal profile] poulpette
$success ||= $filter->add_row( userid => $u->id )
I never saw the ||= notation before, what does it do? Is it language specific? It makes me curious this :)

Date: 2010-03-18 06:16 pm (UTC)
janinedog: (Default)
From: [personal profile] janinedog
In Perl, pretty much any operator can be written with an equals sign like that if you want to do assignment after doing the operation. It's like this:

$a += $b is $a = $a + $b
$a *= $b is $a = $a * $b
$a .= $b is $a = $a . $b (concatenation of strings...I use .= all of the time)
$a ||= $b is $a = $a || $b

It's just shorthand. Perl has lots of shorthand, hehe. :)

Date: 2010-03-23 02:40 pm (UTC)
pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)
From: [personal profile] pne
Java doesn't have the "a ||= b" ( a = a OR b )

Probably at least partly because it would be much less useful in Java -- first off, the logical operators only work on boolean-typed variables, and even in C, where you don't have this (well, you don't even have a boolean type in the first place), the return value of && or || is always 1 or 0, whereas in Perl, the "true" return value of || is the first operand.

So in Perl, if you have $a with the value 5, when $a ||= 7 would have $a still containing 5 afterwards, whereas in C, a = a || 7 would have a contain 1 afterwards ("true").

(So ||= is sometimes used to initialise a variable that may not be initialised -- "Use this as the default value, unless the variable has already been assigned a value before, in which case keep that." Which doesn't work if the variable has been explicitly assigned a value of 0, "0", or "", which is why newer Perls have a separate operator for that, //=, which tests for "contains the undefined value" rather than "contains a false value".)

Date: 2010-03-18 06:19 pm (UTC)
branchandroot: oak against sky (Default)
From: [personal profile] branchandroot
Oh yeah, one of those. *wry* And it's so hard to go away and let it sit until you can see it again when you're in the code groove.

Date: 2010-03-23 02:36 pm (UTC)
pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)
From: [personal profile] pne
Um, Fu? You do know that Perl has both bitwise and logical boolean operators?

In this case, I think you want bitwise-and: $success = $filter->add_row( userid => $targetu->userid ) & $success;.

Which also has the advantage, for you, of not being short-circuiting, unlike the logical boolean operators, so you could also write $success = $success & $filter->add_row( userid => $targetu->userid ) or even $success &= $filter->add_row( userid => $targetu->userid ).

This all assumes that you're using 0 for false and 1 for true (well, that $filter->add_row does). Well, actually, that you're using 0 for false and a non-zero integer value for true.

|| and && are good for logical decisions (do X if/unless Y, or do X if Y AND Z), but that's not what you want here.

Date: 2010-03-23 03:32 pm (UTC)
pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)
From: [personal profile] pne
I was aware of the bitwise & as opposed to the boolean |

Huh?

Did you mean "the bitwise & as opposed to the boolean &&"? Or something else?

I'd call & and | "bitwise boolean operators" and && and || "logical boolean operators", but all four of them are binary boolean operators, to me.

I am used to thinking of them primarily for bitmasks

Understandably, I suppose -- you'd see them most often in things like if (flags & 0x0407) { ... }.

But I've also used &= in the kind of "success accumulator" situation you have (in Java, with a boolean variable), where the accumulator starts as OK but even one NOK will make the entire status NOK -- it only stays OK if all individual portions of the task returned OK.

hence the use of the boolean operators

It seems we have different understandings of what a "boolean operator" is -- what does it mean to you?

P.S. Not trying to put your down or make you feel stupid - honestly trying to help you.
Edited Date: 2010-03-23 03:33 pm (UTC)

Date: 2010-03-23 03:52 pm (UTC)
pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)
From: [personal profile] pne
it's not like you can know what I already know, or don't, or am assuming

*nods*

And thanks for your last paragraph.

I had more to say but I couldn't think of a good way to express it.

<3

Date: 2010-03-25 08:58 am (UTC)
pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)
From: [personal profile] pne
WRT explaining, I think the hardest thing about explanations is that sometimes they *don't stop*. [...] lately I've been having a run of people explaining things to me unnecessarily and just not stopping

If I ever do that, please tell me explicitly -- I don't always notice social cues, and not out of malice, either. Being "polite" in such a case would probably not help either of us.

thank you again for sharing your knowledge/ insight

I'm glad you found it helpful.