* Ryan Gahl wrote (07/09/06 15:42):
> What Eric was saying was not that they are all using the same callback, 
> but that they are all referencing the same i variable at the same 
> address in memory, which at the end of your loop holds the value 6. You 
> would have been fine if you had created a locally scoped variable new_i 
> within the loop and used that in the callback (of course Eric's 
> alternative also works fine, but I'm just trying to clear this issue up 
> a little in your mind so you know next time)
> 
> This would have worked:
> 
> for (var i=1; i<=5;i++){
>    var new_i = i;
>    Event.observe($('star'+new_i), 'click',
> function(e){objRating.setRating(new_i)});
> }

I don't think even this works. new_i is in the same scope. When I tried 
it, I got all 5s (rather than 6s), which would correspond to all the 
closures using one value for new_i - the last one assigned.
Variable scoping in closures is hard (for me, anyway) to get to grips 
with, so I don't think I'll try an explanation - probably Ryan could doo 
better than me anyway.

These should both work, and are viable alternatives to Eric's solution:


// Solution One (simplest case of returning a closure from a function)

for (var i=1; i<=5;i++){
     Event.observe($('star'+(x)), 'click', myfunc(i));
}
// Return the closure from a new function that uses a variable in local 
// scope
function myfunc(x) {
     return function(e){objRating.setRating(x)}
}


// Two
// Use the prototype bind function to bind the "this" variable
for (var i=1; i<=5;i++){
     Event.observe(
        $('star'+(x)),
        'click',
        function(e){objRating.setRating(this)}.bind(i)
     );
}

Eric's solution does the same thing, but hides the detail behind more 
prototype cleverness.

Apologies if I've transcribed these wrong. They worked in a test page I 
made, but I just used alerts rather than objRating.setRating etc.

This is all a bit academic considering that the OP says he's happy now, 
but I find closure code fascinating. I also find the bind() and 
bindAsEventListener() methods to be some of the best things about prototype.

Chris

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Spinoffs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-spinoffs
-~----------~----~----~----~------~----~------~--~---

Reply via email to