Hello, Apologies in advance, but a newb question here: I am using Event.observe to add a simple function to the onclick event of an image. This works fine if i add it to each image that requires the function using: Event.observe($(''star1''), ''click'', function(e){objRating.setRating(1)}); However, as I am adding the same event to a set of images, I would like to iterate through a loop to do it like this: for (var i=1; i<=5;i++){ Event.observe($(''star''+i), ''click'', function(e){objRating.setRating(i)}); } Unfotunately this results in when you click any of the 5 images, the number 6 is returned. Is there any reason you can''t add event.observe in a loop like this or am i making a newb mistake? Thanks in advance, j --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
jumblesale wrote:> for (var i=1; i<=5;i++){ > Event.observe($(''star''+i), ''click'', > function(e){objRating.setRating(i)}); > }This is because the all callbacks are accessing the same "i" variable that is increased with each count. Perhaps something liek thsi would work better. 5.times(function(i) { Event.observe(''star''+i, ''click'', (function(event) { objRating.setRating(this.id.gsub(/\D/, '''')); }).bindAsEventListener($(''star''+i)); }); Of course this is off the top of my head and not tested. Eric --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
Eric Anderson wrote:> 5.times(function(i) { > Event.observe(''star''+i, ''click'', (function(event) { > objRating.setRating(this.id.gsub(/\D/, '''')); > }).bindAsEventListener($(''star''+i)); > });Actually I think this could be simplifiied since each iteration now has it''s own "i". So: 5.times(function(i) {Event.observe(''star''+i, ''click'', function() {objRating.setRating(i)}}); --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
Cheers for your quick reply - that''s really odd that they all use the same callback, I thought that as the app steps through the for loop, then as the ''i'' is incremented then it would also act as the input variable for the event it''s being assigned to. If i put: Event.observe($(''star1''), ''click'', function(e){objRating.setRating(1)}); Event.observe($(''star2''), ''click'', function(e){objRating.setRating(2)}); Event.observe($(''star3''), ''click'', function(e){objRating.setRating(3)}); Event.observe($(''star4''), ''click'', function(e){objRating.setRating(4)}); Event.observe($(''star5''), ''click'', function(e){objRating.setRating(5)}); then it all works ok. very odd - still trying to get my head around it! Sorry to ask, but in your example, do you suggest using that line 5 times or is that an indication to looping 5 times? Cheers, j --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
Actually, no worries, I figured it out from your example - thanks loads, that''s been causing me headaches! j --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
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)}); } On 9/7/06, jumblesale <mcgants-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > Actually, no worries, I figured it out from your example - thanks > loads, that''s been causing me headaches! > j > > > > >-- Ryan Gahl Application Development Consultant Athena Group, Inc. Inquire: 1-888-919-8700 x2903 Blog: http://www.someElement.com --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
* 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
Shouldn''t something like this work and provide more meaning: var stars = $(''star1'', ''star2'', ''star3'', ''star4'', ''star5''); stars.each(function(star, num) { star.observe(''click'', function(e){objRating.setRating(num);}); }); That of course is with the 1.5_rc1 of prototype and it is untested. Brandon On 9/7/06, Chris Lear <chris.lear-kZMsvDh4tCZWk0Htik3J/w@public.gmane.org> wrote:> > * 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
Interesting. I assumed new_i = i would be making a value copy to the new reference, which should be scoped each time through the loop... hmm. So I wonder if this is what I needed to do... (yes agreed it''s academic, but fun to carry on) for (var i=1; i<=5;i++){ var new_i = new Number(i); Event.observe($(''star''+new_i), ''click'', function(e){objRating.setRating(new_i)}); } ...or even... for (var i=1; i<=5;i++){ var new_i = i.toString(); Event.observe($(''star''+new_i), ''click'', function(e){objRating.setRating(new_i)}); } Now I would really assume either of those should work to force a value copy to the new variable with each iteration. If not, I give up :-) On 9/7/06, Chris Lear <chris.lear-kZMsvDh4tCZWk0Htik3J/w@public.gmane.org> wrote:> > > * 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 > > > >-- Ryan Gahl Application Development Consultant Athena Group, Inc. Inquire: 1-888-919-8700 x2903 Blog: http://www.someElement.com --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
On 9/7/06, Ryan Gahl <ryan.gahl-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Interesting. I assumed new_i = i would be making a value copy to the new > reference, which should be scoped each time through the loop... hmm. > > So I wonder if this is what I needed to do... (yes agreed it''s academic, > but fun to carry on) > > > for (var i=1; i<=5;i++){ > var new_i = new Number(i); > > Event.observe($(''star''+new_i), ''click'', > function(e){objRating.setRating(new_i)}); > } > > ...or even... > > > for (var i=1; i<=5;i++){ > var new_i = i.toString(); > > Event.observe($(''star''+new_i), ''click'', > function(e){objRating.setRating(new_i)}); > } > > Now I would really assume either of those should work to force a value > copy to the new variable with each iteration. If not, I give up :-) > >The two ways above both end up referencing the same execution context. In basic terms, new_i is the same place on the "stack" each time, and the created functions all point to it. (Using quotes because the implementation is not important, just the idea.) That''s why the "function returning a closure" bit mentioned previously works; each time that function is invoked, an new "stack frame"/execution context is created. Of course, in Lisp one rarely has these problems, as the loop is typically represented as a tail recursive procedure... I think that would really throw people off in JS. -- Matt Jones mdj.acme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org President/Technical Director, Acme Art Company (acmeartco.org) --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
As far as "providing more meaning"... you''re simply skinng the same cat another way. Not sure how much "meaning" you can give to a loop by doing way X instead of way Y. The meaning of the loop is still the same :-) But yes, your way is great as well. I was really just trying to shed some light on the reasons why the OP''s (and my) original ways weren''t working, so was avoiding the prototype magic. On 9/7/06, Brandon Aaron <brandon.aaron-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > Shouldn''t something like this work and provide more meaning: > > var stars = $(''star1'', ''star2'', ''star3'', ''star4'', ''star5''); > stars.each(function(star, num) { > star.observe(''click'', function(e){objRating.setRating(num);}); > }); > > That of course is with the 1.5_rc1 of prototype and it is untested. > > Brandon > > On 9/7/06, Chris Lear <chris.lear-kZMsvDh4tCZWk0Htik3J/w@public.gmane.org> wrote: > > > > * 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 > > > > > > > > > > >-- Ryan Gahl Application Development Consultant Athena Group, Inc. Inquire: 1-888-919-8700 x2903 Blog: http://www.someElement.com --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
Wow, that''s in sharp contrast to how I thought it worked, and in fact does work in most languages. For instance in C# or Java, the {} of the for loop would represent a new scope per iteration, so the declared variables would only apply to that iteration''s scope, and get garbage collected with each iteration, meaning a new address in memory would be used for the next one. Therefore, it would be possible to force a value copy of a referenced object, possibly using a boxing method if required (like .toString()) or of course constructing a new object using the value of the referenced one. Obviously, I''ve been babied now for a while with the $A().each() iterators of prototype, so haven''t had to face this problem for a little while in the javascript domain. Ok, so how about these? I''m moving the variable declaration around the lexical pads here to see where the contexts are actually being recreated, so to speak... (still academic discussion for the sole purpose of getting smarter :-)) for the "new_i = i" assignment, I''d try any of the three options to try to achieve the desired result, but won''t write all the permutations here. (the options being "new_i = i", "new_i = new Number(i)" and "new_i = i.toString ()") var new_i; for (var i=1; i<=5;i++){ new_i = i; Event.observe($(''star''+new_i), ''click'', function(e){objRating.setRating(new_i)}); } or... (in this one, the regular i in the first argument of the Event.observefunction is fine, and actually I''m assuming that part has worked fine all along) -- now, this one should really work because the var new_i is being declared in the closure, which should be a brand new scope per iteration of the loop, so one of the 3 assignment options cited above should be able to coerce the value copy we''re looking for. for (var i=1; i<=5;i++){ Event.observe($(''star''+i), ''click'', function(e){var new_i = i; objRating.setRating(new_i)}); } On 9/7/06, Matt Jones <mdj.acme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > > On 9/7/06, Ryan Gahl <ryan.gahl-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > Interesting. I assumed new_i = i would be making a value copy to the new > > reference, which should be scoped each time through the loop... hmm. > > > > So I wonder if this is what I needed to do... (yes agreed it''s academic, > > but fun to carry on) > > > > > > for (var i=1; i<=5;i++){ > > var new_i = new Number(i); > > > > Event.observe($(''star''+new_i), ''click'', > > function(e){objRating.setRating (new_i)}); > > } > > > > ...or even... > > > > > > for (var i=1; i<=5;i++){ > > var new_i = i.toString(); > > > > Event.observe($(''star''+new_i), ''click'', > > function(e){objRating.setRating(new_i)}); > > } > > > > Now I would really assume either of those should work to force a value > > copy to the new variable with each iteration. If not, I give up :-) > > > > > The two ways above both end up referencing the same execution context. In > basic terms, > new_i is the same place on the "stack" each time, and the created > functions all point to it. > (Using quotes because the implementation is not important, just the idea.) > That''s why the "function returning a closure" bit mentioned previously > works; each time > that function is invoked, an new "stack frame"/execution context is > created. > > Of course, in Lisp one rarely has these problems, as the loop is typically > represented as > a tail recursive procedure... I think that would really throw people off > in JS. > > -- > Matt Jones > mdj.acme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org > President/Technical Director, Acme Art Company (acmeartco.org) > > >-- Ryan Gahl Application Development Consultant Athena Group, Inc. Inquire: 1-888-919-8700 x2903 Blog: http://www.someElement.com --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
On 9/7/06, Ryan Gahl <ryan.gahl-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Wow, that''s in sharp contrast to how I thought it worked, and in fact does > work in most languages. For instance in C# or Java, the {} of the for loop > would represent a new scope per iteration, so the declared variables would > only apply to that iteration''s scope, and get garbage collected with each > iteration, meaning a new address in memory would be used for the next one. > Therefore, it would be possible to force a value copy of a referenced > object, possibly using a boxing method if required (like .toString()) or of > course constructing a new object using the value of the referenced one. > > Obviously, I''ve been babied now for a while with the $A().each() iterators > of prototype, so haven''t had to face this problem for a little while in the > javascript domain. > > Ok, so how about these? I''m moving the variable declaration around the > lexical pads here to see where the contexts are actually being recreated, so > to speak... (still academic discussion for the sole purpose of getting > smarter :-)) > > for the "new_i = i" assignment, I''d try any of the three options to try to > achieve the desired result, but won''t write all the permutations here. (the > options being "new_i = i", "new_i = new Number(i)" and "new_i = i.toString > ()") > >The big difference is that Javascript only creates a new execution context for each function, not each block (different from C++). I found this reference: http://www.jibbering.com/faq/faq_notes/closures.html The explanation I found was that Javascript "does not have block scoping". As a very short example, this code: if (true) { var i=1; } alert(i); will show 1, not undefined. (Example from http://overstimulate.com/articles/2006/02/06/javascript-scoping.html ) Hope this helps! -- Matt Jones mdj.acme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org President/Technical Director, Acme Art Company (acmeartco.org) --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---
* Ryan Gahl wrote (07/09/06 17:53):> As far as "providing more meaning"... you''re simply skinng the same cat > another way. Not sure how much "meaning" you can give to a loop by doing > way X instead of way Y. The meaning of the loop is still the same :-)I personally don''t really like the solution using each(), because it relies on the generation of a sequence of numbers that is a bit obscure. The same goes for the times() solution. Neither of those functions seems to be designed primarily with counting in mind. [The times function is mainly a wrapper for the each function anyway]. But that''s just me, and I''ll probably change my mind tomorrow.> > But yes, your way is great as well. I was really just trying to shed > some light on the reasons why the OP''s (and my) original ways weren''t > working, so was avoiding the prototype magic.Perhaps I can bring some closure to the closure discussion with the attached test page. Put it somewhere where it can reach prototype.js, and play with the onload="runX()" to see what happens. I had to fix Brandon''s and Eric''s solutions slightly, because each() and times() use zero-based counters (and 5.times gives a js parse error). I think the article on closures Matt linked to is probably as good as you''re likely to get in terms of actually explaining it all. 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 rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs -~----------~----~----~----~------~----~------~--~---