* 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
-~----------~----~----~----~------~----~------~--~---