Hi everybody, I''m just getting kicked off on prototype and I''m having a problem that I''m hoping to get some help on.. I''ve had good success with Ajax.Updater, but now I''m trying to use Ajax.Request with the use of its callback abilities. My issue is that I''m trying to get a hold of one of the Element objects in the DOM using $(''element''), however the name of the element can vary and so I have to assemble the name using the value in an array. It''s almost like the siteListArray[x] does not work in the callback. Is it possible that the callback cannot see a variable that was declared earlier in my code at a global scope? Thanks in advance. for (x in siteListArray) { var url = ''functions.php?command=numberOfErrors&site='' + siteListArray[x]; new Ajax.Request(url, { asynchronous:true, onComplete: function(transport) { $(''sidebar_site_div_'' + siteListArray[x]).update(transport.responseText); } }); } --~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
On Fri, Feb 22, 2008 at 2:02 PM, Chach <carterharrison-ee4meeAH724@public.gmane.org> wrote:> > Hi everybody,Hello!> for (x in siteListArray)This is your problem right here. What that lil'' "for ... in" does is iterate over every property in the object. Arrays are objects in Javascript, and Prototype takes advantage of that to add a ton of very useful methods to arrays. The unfortunate side effect of this is that using "for ... in" on a Prototype-enhanced array also iterates over _all the extra methods_ that Prototype so considerately added to the array. Take a look in Firebug: are there a bunch more calls to Ajax.Request than you thought you were making? However, _because_ you''re using Prototype, you''ve got something at least as cool as "for ... in," and that''s each(). For example, you could rewrite your code as follows: siteList.each(function(site) { var url = ''functions.php?command=numberOfErrors&site='' + site; new Ajax.Request(url, { // asynchronous: true is the default and can be omitted unless you''re setting it to false onComplete: function(transport) { $(''sidebar_site_div_'' + site).update(transport.responseText); } }); }); // <-- note that extra paren! Remember this whole function is inside the call to each() Give that a shot! :Dan Dorman --~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Looks like a closure issue to me (solved with another closure). Also, is that an array you are iterating over using "for..in" ? siteListArray.each(function(item) { var url = ''functions.php?command=numberOfErrors&site='' + item; new Ajax.Request(url, { onSuccess: (function(item) { return function(t) { $(''sidebar_site_div_'' + item).update(t.responseText); }})(item) }) }) - kangax On Feb 22, 4:02 pm, Chach <carterharri...-ee4meeAH724@public.gmane.org> wrote:> Hi everybody, > > I''m just getting kicked off on prototype and I''m having a problem that > I''m hoping to get some help on.. I''ve had good success with > Ajax.Updater, but now I''m trying to use Ajax.Request with the use of > its callback abilities. My issue is that I''m trying to get a hold of > one of the Element objects in the DOM using $(''element''), however the > name of the element can vary and so I have to assemble the name using > the value in an array. It''s almost like the siteListArray[x] does not > work in the callback. Is it possible that the callback cannot see a > variable that was declared earlier in my code at a global scope? > Thanks in advance. > > for (x in siteListArray) > { > var url = ''functions.php?command=numberOfErrors&site='' + > siteListArray[x]; > new Ajax.Request(url, { > asynchronous:true, > onComplete: function(transport) { > $(''sidebar_site_div_'' + > siteListArray[x]).update(transport.responseText); > } > }); > > }--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Hi, Closures is something that (can) cause memory leaks, right? kangax, would you mind explaining in a bit more detail why you wrote the code like you wrote it? I''m a bit lost in it. I restructured the code you wrote a bit... http://pastie.caboo.se/156248 - Is there a reason why you don''t write a '';'' after the new Ajax.Request (...)? - Is there a reason why you don''t write a '';'' after the someArray.each(function(item) { ... })? - I''m getting lost in how you constructed the onSuccess callback... Thx... Manu. On Fri, Feb 22, 2008 at 11:11 PM, kangax <kangax-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Looks like a closure issue to me (solved with another closure). > Also, is that an array you are iterating over using "for..in" ? > > siteListArray.each(function(item) { > var url = ''functions.php?command=numberOfErrors&site='' + item; > new Ajax.Request(url, { > onSuccess: (function(item) { return function(t) { > $(''sidebar_site_div_'' + item).update(t.responseText); > }})(item) > }) > }) > > - kangax > > On Feb 22, 4:02 pm, Chach <carterharri...-ee4meeAH724@public.gmane.org> wrote: > > Hi everybody, > > > > I''m just getting kicked off on prototype and I''m having a problem that > > I''m hoping to get some help on.. I''ve had good success with > > Ajax.Updater, but now I''m trying to use Ajax.Request with the use of > > its callback abilities. My issue is that I''m trying to get a hold of > > one of the Element objects in the DOM using $(''element''), however the > > name of the element can vary and so I have to assemble the name using > > the value in an array. It''s almost like the siteListArray[x] does not > > work in the callback. Is it possible that the callback cannot see a > > variable that was declared earlier in my code at a global scope? > > Thanks in advance. > > > > for (x in siteListArray) > > { > > var url = ''functions.php?command=numberOfErrors&site='' + > > siteListArray[x]; > > new Ajax.Request(url, { > > asynchronous:true, > > onComplete: function(transport) { > > $(''sidebar_site_div_'' + > > siteListArray[x]).update(transport.responseText); > > } > > }); > > > > } > > >--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Hi,> Closures is something that (can) cause memory leaks, right?That''s a complex topic. :-) Closures inherit, and therefore preserve for their lifecycles, all of the local variables and parameters of the functions they''re defined in. If the closure is used immediately and discarded, you don''t much care. If you''re going to retain a reference to the closure (for instance, an event handler, or a dynamically- created instance method), then you want to be aware of this. Here''s an example of the latter case: function myNiftyMethod(param) { var v1, v2, v3; // ... do something ... // create and retain a closure to do something this.thingy = function() { // ... some code for the closure ... }; } When myNiftyMethod is executed, it creates a closure and remembers it on the object instance as this.thingy. Since the closure holds a reference to all of myNiftyMethods local variables and params (even though it doesn''t use them), and since the object instance keeps a reference to the closure, ''param'', ''v1'', ''v2'', and ''v3'' all live on for as long as the closure does. (Modulo cool JavaScript engine optimisations, which I don''t think are common yet and are harder for the engine to do than it would at first seem.) So closures can have memory *implications*; if you understand how they work, though, and get used to some idioms around them, you won''t cause memory leaks (barring JavaScript engine bugs). This is rambling a bit, but here''s an example of the case where you''re using the closure immediately and discarding it: function myNiftyMethod(someArray) { var v1, v2, v3; // ... do something ... // create and retain a closure to do something someArray.each(function(item) { item.doSomethingCool(); }); } You don''t keep a reference to the closure used in the each() method, so you don''t have to consider the implications of myNiftyMethod''s parameters and variables being retained. And it''s a very powerful and expressive way to deal with each item in the array.> - I''m getting lost in how you constructed the onSuccess callback...That''s easy to do. :-) He''s using a closure to construct and return another closure; it''s the inner one that gets assigned to the onSuccess handler and retained, the outer one is run immediately and discarded. If you look carefully at the code defining the onSuccess handler, you''ll see that the entire outer closure is wrapped in parens -- the opening paren is right after "onSuccess:", and then right at the end of the closure you see the closing paren followed by "(item)" -- that "(item)" tells you he''s *executing* the outer closure right then, not just creating it. When it runs, the outer closure creates the inner closure and returns it. *That''s* what gets assigned to onSuccess, the reference to the inner closure. The outer closure has only the param it needs (item) and no local variables, so the inner closure only preserves the information it really needs, not all of the local variables where all of this is running. Hope this helps, -- T.J. Crowder tj /crowder software / com On Feb 23, 7:34 am, "Manu Temmerman-Uyttenbroeck" <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > Closures is something that (can) cause memory leaks, right? > kangax, would you mind explaining in a bit more detail why you wrote the > code like you wrote it? I''m a bit lost in it. I restructured the code you > wrote a bit...http://pastie.caboo.se/156248 > - Is there a reason why you don''t write a '';'' after the new Ajax.Request > (...)? > - Is there a reason why you don''t write a '';'' after the > someArray.each(function(item) > { ... })? > - I''m getting lost in how you constructed the onSuccess callback... > > Thx... > > Manu. > > On Fri, Feb 22, 2008 at 11:11 PM, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Looks like a closure issue to me (solved with another closure). > > Also, is that an array you are iterating over using "for..in" ? > > > siteListArray.each(function(item) { > > var url = ''functions.php?command=numberOfErrors&site='' + item; > > new Ajax.Request(url, { > > onSuccess: (function(item) { return function(t) { > > $(''sidebar_site_div_'' + item).update(t.responseText); > > }})(item) > > }) > > }) > > > - kangax > > > On Feb 22, 4:02 pm, Chach <carterharri...-ee4meeAH724@public.gmane.org> wrote: > > > Hi everybody, > > > > I''m just getting kicked off on prototype and I''m having a problem that > > > I''m hoping to get some help on.. I''ve had good success with > > > Ajax.Updater, but now I''m trying to use Ajax.Request with the use of > > > its callback abilities. My issue is that I''m trying to get a hold of > > > one of the Element objects in the DOM using $(''element''), however the > > > name of the element can vary and so I have to assemble the name using > > > the value in an array. It''s almost like the siteListArray[x] does not > > > work in the callback. Is it possible that the callback cannot see a > > > variable that was declared earlier in my code at a global scope? > > > Thanks in advance. > > > > for (x in siteListArray) > > > { > > > var url = ''functions.php?command=numberOfErrors&site='' + > > > siteListArray[x]; > > > new Ajax.Request(url, { > > > asynchronous:true, > > > onComplete: function(transport) { > > > $(''sidebar_site_div_'' + > > > siteListArray[x]).update(transport.responseText); > > > } > > > }); > > > > }--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Oops, this:> Since the closure holds a > reference to all of myNiftyMethods local variables and params (even > though it doesn''t use them), and since the object instance keeps a > reference to the closure, ''param'', ''v1'', ''v2'', and ''v3'' all live on > for as long as the closure does....should end with "as long as the object instance does, or until this.thingy is cleared." (Proofread, *then* post.) -- T.J. ;-) On Feb 23, 10:01 am, "T.J. Crowder" <tjcrow...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > > Closures is something that (can) cause memory leaks, right? > > That''s a complex topic. :-) Closures inherit, and therefore preserve > for their lifecycles, all of the local variables and parameters of the > functions they''re defined in. If the closure is used immediately and > discarded, you don''t much care. If you''re going to retain a reference > to the closure (for instance, an event handler, or a dynamically- > created instance method), then you want to be aware of this. Here''s > an example of the latter case: > > function myNiftyMethod(param) > { > var v1, v2, v3; > > // ... do something ... > > // create and retain a closure to do something > this.thingy = function() { > // ... some code for the closure ... > }; > > } > > When myNiftyMethod is executed, it creates a closure and remembers it > on the object instance as this.thingy. Since the closure holds a > reference to all of myNiftyMethods local variables and params (even > though it doesn''t use them), and since the object instance keeps a > reference to the closure, ''param'', ''v1'', ''v2'', and ''v3'' all live on > for as long as the closure does. (Modulo cool JavaScript engine > optimisations, which I don''t think are common yet and are harder for > the engine to do than it would at first seem.) > > So closures can have memory *implications*; if you understand how they > work, though, and get used to some idioms around them, you won''t cause > memory leaks (barring JavaScript engine bugs). > > This is rambling a bit, but here''s an example of the case where you''re > using the closure immediately and discarding it: > > function myNiftyMethod(someArray) > { > var v1, v2, v3; > > // ... do something ... > > // create and retain a closure to do something > someArray.each(function(item) { > item.doSomethingCool(); > }); > > } > > You don''t keep a reference to the closure used in the each() method, > so you don''t have to consider the implications of myNiftyMethod''s > parameters and variables being retained. And it''s a very powerful and > expressive way to deal with each item in the array. > > > - I''m getting lost in how you constructed the onSuccess callback... > > That''s easy to do. :-) He''s using a closure to construct and return > another closure; it''s the inner one that gets assigned to the > onSuccess handler and retained, the outer one is run immediately and > discarded. If you look carefully at the code defining the onSuccess > handler, you''ll see that the entire outer closure is wrapped in parens > -- the opening paren is right after "onSuccess:", and then right at > the end of the closure you see the closing paren followed by "(item)" > -- that "(item)" tells you he''s *executing* the outer closure right > then, not just creating it. When it runs, the outer closure creates > the inner closure and returns it. *That''s* what gets assigned to > onSuccess, the reference to the inner closure. The outer closure has > only the param it needs (item) and no local variables, so the inner > closure only preserves the information it really needs, not all of the > local variables where all of this is running. > > Hope this helps, > -- > T.J. Crowder > tj /crowder software / com > > On Feb 23, 7:34 am, "Manu Temmerman-Uyttenbroeck" > > <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Hi, > > > Closures is something that (can) cause memory leaks, right? > > kangax, would you mind explaining in a bit more detail why you wrote the > > code like you wrote it? I''m a bit lost in it. I restructured the code you > > wrote a bit...http://pastie.caboo.se/156248 > > - Is there a reason why you don''t write a '';'' after the new Ajax.Request > > (...)? > > - Is there a reason why you don''t write a '';'' after the > > someArray.each(function(item) > > { ... })? > > - I''m getting lost in how you constructed the onSuccess callback... > > > Thx... > > > Manu. > > > On Fri, Feb 22, 2008 at 11:11 PM, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > Looks like a closure issue to me (solved with another closure). > > > Also, is that an array you are iterating over using "for..in" ? > > > > siteListArray.each(function(item) { > > > var url = ''functions.php?command=numberOfErrors&site='' + item; > > > new Ajax.Request(url, { > > > onSuccess: (function(item) { return function(t) { > > > $(''sidebar_site_div_'' + item).update(t.responseText); > > > }})(item) > > > }) > > > }) > > > > - kangax > > > > On Feb 22, 4:02 pm, Chach <carterharri...-ee4meeAH724@public.gmane.org> wrote: > > > > Hi everybody, > > > > > I''m just getting kicked off on prototype and I''m having a problem that > > > > I''m hoping to get some help on.. I''ve had good success with > > > > Ajax.Updater, but now I''m trying to use Ajax.Request with the use of > > > > its callback abilities. My issue is that I''m trying to get a hold of > > > > one of the Element objects in the DOM using $(''element''), however the > > > > name of the element can vary and so I have to assemble the name using > > > > the value in an array. It''s almost like the siteListArray[x] does not > > > > work in the callback. Is it possible that the callback cannot see a > > > > variable that was declared earlier in my code at a global scope? > > > > Thanks in advance. > > > > > for (x in siteListArray) > > > > { > > > > var url = ''functions.php?command=numberOfErrors&site='' + > > > > siteListArray[x]; > > > > new Ajax.Request(url, { > > > > asynchronous:true, > > > > onComplete: function(transport) { > > > > $(''sidebar_site_div_'' + > > > > siteListArray[x]).update(transport.responseText); > > > > } > > > > }); > > > > > }--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
thx for the great explanation! On Sat, Feb 23, 2008 at 11:07 AM, T.J. Crowder <tjcrowder-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Oops, this: > > > Since the closure holds a > > reference to all of myNiftyMethods local variables and params (even > > though it doesn''t use them), and since the object instance keeps a > > reference to the closure, ''param'', ''v1'', ''v2'', and ''v3'' all live on > > for as long as the closure does. > > ...should end with "as long as the object instance does, or until > this.thingy is cleared." > > (Proofread, *then* post.) > > -- T.J. ;-) > > On Feb 23, 10:01 am, "T.J. Crowder" <tjcrow...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Hi, > > > > > Closures is something that (can) cause memory leaks, right? > > > > That''s a complex topic. :-) Closures inherit, and therefore preserve > > for their lifecycles, all of the local variables and parameters of the > > functions they''re defined in. If the closure is used immediately and > > discarded, you don''t much care. If you''re going to retain a reference > > to the closure (for instance, an event handler, or a dynamically- > > created instance method), then you want to be aware of this. Here''s > > an example of the latter case: > > > > function myNiftyMethod(param) > > { > > var v1, v2, v3; > > > > // ... do something ... > > > > // create and retain a closure to do something > > this.thingy = function() { > > // ... some code for the closure ... > > }; > > > > } > > > > When myNiftyMethod is executed, it creates a closure and remembers it > > on the object instance as this.thingy. Since the closure holds a > > reference to all of myNiftyMethods local variables and params (even > > though it doesn''t use them), and since the object instance keeps a > > reference to the closure, ''param'', ''v1'', ''v2'', and ''v3'' all live on > > for as long as the closure does. (Modulo cool JavaScript engine > > optimisations, which I don''t think are common yet and are harder for > > the engine to do than it would at first seem.) > > > > So closures can have memory *implications*; if you understand how they > > work, though, and get used to some idioms around them, you won''t cause > > memory leaks (barring JavaScript engine bugs). > > > > This is rambling a bit, but here''s an example of the case where you''re > > using the closure immediately and discarding it: > > > > function myNiftyMethod(someArray) > > { > > var v1, v2, v3; > > > > // ... do something ... > > > > // create and retain a closure to do something > > someArray.each(function(item) { > > item.doSomethingCool(); > > }); > > > > } > > > > You don''t keep a reference to the closure used in the each() method, > > so you don''t have to consider the implications of myNiftyMethod''s > > parameters and variables being retained. And it''s a very powerful and > > expressive way to deal with each item in the array. > > > > > - I''m getting lost in how you constructed the onSuccess callback... > > > > That''s easy to do. :-) He''s using a closure to construct and return > > another closure; it''s the inner one that gets assigned to the > > onSuccess handler and retained, the outer one is run immediately and > > discarded. If you look carefully at the code defining the onSuccess > > handler, you''ll see that the entire outer closure is wrapped in parens > > -- the opening paren is right after "onSuccess:", and then right at > > the end of the closure you see the closing paren followed by "(item)" > > -- that "(item)" tells you he''s *executing* the outer closure right > > then, not just creating it. When it runs, the outer closure creates > > the inner closure and returns it. *That''s* what gets assigned to > > onSuccess, the reference to the inner closure. The outer closure has > > only the param it needs (item) and no local variables, so the inner > > closure only preserves the information it really needs, not all of the > > local variables where all of this is running. > > > > Hope this helps, > > -- > > T.J. Crowder > > tj /crowder software / com > > > > On Feb 23, 7:34 am, "Manu Temmerman-Uyttenbroeck" > > > > <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Hi, > > > > > Closures is something that (can) cause memory leaks, right? > > > kangax, would you mind explaining in a bit more detail why you wrote > the > > > code like you wrote it? I''m a bit lost in it. I restructured the code > you > > > wrote a bit...http://pastie.caboo.se/156248 > > > - Is there a reason why you don''t write a '';'' after the new > Ajax.Request > > > (...)? > > > - Is there a reason why you don''t write a '';'' after the > > > someArray.each(function(item) > > > { ... })? > > > - I''m getting lost in how you constructed the onSuccess callback... > > > > > Thx... > > > > > Manu. > > > > > On Fri, Feb 22, 2008 at 11:11 PM, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > Looks like a closure issue to me (solved with another closure). > > > > Also, is that an array you are iterating over using "for..in" ? > > > > > > siteListArray.each(function(item) { > > > > var url = ''functions.php?command=numberOfErrors&site='' + item; > > > > new Ajax.Request(url, { > > > > onSuccess: (function(item) { return function(t) { > > > > $(''sidebar_site_div_'' + item).update(t.responseText); > > > > }})(item) > > > > }) > > > > }) > > > > > > - kangax > > > > > > On Feb 22, 4:02 pm, Chach <carterharri...-ee4meeAH724@public.gmane.org> wrote: > > > > > Hi everybody, > > > > > > > I''m just getting kicked off on prototype and I''m having a problem > that > > > > > I''m hoping to get some help on.. I''ve had good success with > > > > > Ajax.Updater, but now I''m trying to use Ajax.Request with the use > of > > > > > its callback abilities. My issue is that I''m trying to get a hold > of > > > > > one of the Element objects in the DOM using $(''element''), however > the > > > > > name of the element can vary and so I have to assemble the name > using > > > > > the value in an array. It''s almost like the siteListArray[x] does > not > > > > > work in the callback. Is it possible that the callback cannot see > a > > > > > variable that was declared earlier in my code at a global scope? > > > > > Thanks in advance. > > > > > > > for (x in siteListArray) > > > > > { > > > > > var url = ''functions.php?command=numberOfErrors&site='' + > > > > > siteListArray[x]; > > > > > new Ajax.Request(url, { > > > > > asynchronous:true, > > > > > onComplete: function(transport) { > > > > > $(''sidebar_site_div_'' + > > > > > siteListArray[x]).update(transport.responseText); > > > > > } > > > > > }); > > > > > > > } > > >--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Wow, that''s one thorough explanation. Thanks T.J. On Feb 23, 5:01 am, "T.J. Crowder" <tjcrow...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > > Closures is something that (can) cause memory leaks, right? > > That''s a complex topic. :-) Closures inherit, and therefore preserve > for their lifecycles, all of the local variables and parameters of the > functions they''re defined in. If the closure is used immediately and > discarded, you don''t much care. If you''re going to retain a reference > to the closure (for instance, an event handler, or a dynamically- > created instance method), then you want to be aware of this. Here''s > an example of the latter case: > > function myNiftyMethod(param) > { > var v1, v2, v3; > > // ... do something ... > > // create and retain a closure to do something > this.thingy = function() { > // ... some code for the closure ... > }; > > } > > When myNiftyMethod is executed, it creates a closure and remembers it > on the object instance as this.thingy. Since the closure holds a > reference to all of myNiftyMethods local variables and params (even > though it doesn''t use them), and since the object instance keeps a > reference to the closure, ''param'', ''v1'', ''v2'', and ''v3'' all live on > for as long as the closure does. (Modulo cool JavaScript engine > optimisations, which I don''t think are common yet and are harder for > the engine to do than it would at first seem.) > > So closures can have memory *implications*; if you understand how they > work, though, and get used to some idioms around them, you won''t cause > memory leaks (barring JavaScript engine bugs). > > This is rambling a bit, but here''s an example of the case where you''re > using the closure immediately and discarding it: > > function myNiftyMethod(someArray) > { > var v1, v2, v3; > > // ... do something ... > > // create and retain a closure to do something > someArray.each(function(item) { > item.doSomethingCool(); > }); > > } > > You don''t keep a reference to the closure used in the each() method, > so you don''t have to consider the implications of myNiftyMethod''s > parameters and variables being retained. And it''s a very powerful and > expressive way to deal with each item in the array. > > > - I''m getting lost in how you constructed the onSuccess callback... > > That''s easy to do. :-) He''s using a closure to construct and return > another closure; it''s the inner one that gets assigned to the > onSuccess handler and retained, the outer one is run immediately and > discarded. If you look carefully at the code defining the onSuccess > handler, you''ll see that the entire outer closure is wrapped in parens > -- the opening paren is right after "onSuccess:", and then right at > the end of the closure you see the closing paren followed by "(item)" > -- that "(item)" tells you he''s *executing* the outer closure right > then, not just creating it. When it runs, the outer closure creates > the inner closure and returns it. *That''s* what gets assigned to > onSuccess, the reference to the inner closure. The outer closure has > only the param it needs (item) and no local variables, so the inner > closure only preserves the information it really needs, not all of the > local variables where all of this is running. > > Hope this helps, > -- > T.J. Crowder > tj /crowder software / com > > On Feb 23, 7:34 am, "Manu Temmerman-Uyttenbroeck" > > <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Hi, > > > Closures is something that (can) cause memory leaks, right? > > kangax, would you mind explaining in a bit more detail why you wrote the > > code like you wrote it? I''m a bit lost in it. I restructured the code you > > wrote a bit...http://pastie.caboo.se/156248 > > - Is there a reason why you don''t write a '';'' after the new Ajax.Request > > (...)? > > - Is there a reason why you don''t write a '';'' after the > > someArray.each(function(item) > > { ... })? > > - I''m getting lost in how you constructed the onSuccess callback... > > > Thx... > > > Manu. > > > On Fri, Feb 22, 2008 at 11:11 PM, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > Looks like a closure issue to me (solved with another closure). > > > Also, is that an array you are iterating over using "for..in" ? > > > > siteListArray.each(function(item) { > > > var url = ''functions.php?command=numberOfErrors&site='' + item; > > > new Ajax.Request(url, { > > > onSuccess: (function(item) { return function(t) { > > > $(''sidebar_site_div_'' + item).update(t.responseText); > > > }})(item) > > > }) > > > }) > > > > - kangax > > > > On Feb 22, 4:02 pm, Chach <carterharri...-ee4meeAH724@public.gmane.org> wrote: > > > > Hi everybody, > > > > > I''m just getting kicked off on prototype and I''m having a problem that > > > > I''m hoping to get some help on.. I''ve had good success with > > > > Ajax.Updater, but now I''m trying to use Ajax.Request with the use of > > > > its callback abilities. My issue is that I''m trying to get a hold of > > > > one of the Element objects in the DOM using $(''element''), however the > > > > name of the element can vary and so I have to assemble the name using > > > > the value in an array. It''s almost like the siteListArray[x] does not > > > > work in the callback. Is it possible that the callback cannot see a > > > > variable that was declared earlier in my code at a global scope? > > > > Thanks in advance. > > > > > for (x in siteListArray) > > > > { > > > > var url = ''functions.php?command=numberOfErrors&site='' + > > > > siteListArray[x]; > > > > new Ajax.Request(url, { > > > > asynchronous:true, > > > > onComplete: function(transport) { > > > > $(''sidebar_site_div_'' + > > > > siteListArray[x]).update(transport.responseText); > > > > } > > > > }); > > > > > }--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
@kangax: :-) @all: I should mention that I don''t know for sure that this create-a- closure-within-a-closure idiom works in terms of the garbage collectors out there; I''ve always intended to go find out because it seems like there''s a chain involved and it wouldn''t necessarily be broken by doing that. I''d be really interested in any references folks have to empirical results on that, since as Manu points out, it might matter in terms of memory use. A quick-and-dirty test in FF2 for Windows suggests that FF doesn''t release the context in this scenario: var keeper = null; function executionContextTest() { var a; var n; a = new Array(); for (n = 200000; n > 0; --n) { a[n] = new Date(); } // keeper = function() { // alert(''This is the keeper function''); // }; keeper = (function() { return function() { alert(''This is the keeper function''); } })(); } (Where I trigger executionContextTest via a button.) The commented- out code would definitely preserve the execution context and therefore the array, but the second example is using the closure-creates-a- closure idiom. FF seems to keep all of the execution contexts alive (and therefore preserve the array) in this case as well. When I run this, FF''s memory use goes up by about 19MB, and doesn''t come down again until I use another button to release the keeper reference (and then an alert to jog the garbage collector). If I don''t create the closure at all, the memory is reclaimed as soon as executionContextTest completes (without having to jog the garbage collector). But again, this was not in any way a scientific test. If anyone can point me at some... :-) @Manu: Don''t let this bother you in cases where you''re not keeping a reference to the closure, that''s the only time the issue of keeping the execution contexts alive comes up. Use-and-discard closures are not a problem (and very useful). -- T.J. Crowder tj /crowder software / com On Feb 23, 12:43 pm, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Wow, that''s one thorough explanation. > Thanks T.J. > > On Feb 23, 5:01 am, "T.J. Crowder" <tjcrow...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Hi, > > > > Closures is something that (can) cause memory leaks, right? > > > That''s a complex topic. :-) Closures inherit, and therefore preserve > > for their lifecycles, all of the local variables and parameters of the > > functions they''re defined in. If the closure is used immediately and > > discarded, you don''t much care. If you''re going to retain a reference > > to the closure (for instance, an event handler, or a dynamically- > > created instance method), then you want to be aware of this. Here''s > > an example of the latter case: > > > function myNiftyMethod(param) > > { > > var v1, v2, v3; > > > // ... do something ... > > > // create and retain a closure to do something > > this.thingy = function() { > > // ... some code for the closure ... > > }; > > > } > > > When myNiftyMethod is executed, it creates a closure and remembers it > > on the object instance as this.thingy. Since the closure holds a > > reference to all of myNiftyMethods local variables and params (even > > though it doesn''t use them), and since the object instance keeps a > > reference to the closure, ''param'', ''v1'', ''v2'', and ''v3'' all live on > > for as long as the closure does. (Modulo cool JavaScript engine > > optimisations, which I don''t think are common yet and are harder for > > the engine to do than it would at first seem.) > > > So closures can have memory *implications*; if you understand how they > > work, though, and get used to some idioms around them, you won''t cause > > memory leaks (barring JavaScript engine bugs). > > > This is rambling a bit, but here''s an example of the case where you''re > > using the closure immediately and discarding it: > > > function myNiftyMethod(someArray) > > { > > var v1, v2, v3; > > > // ... do something ... > > > // create and retain a closure to do something > > someArray.each(function(item) { > > item.doSomethingCool(); > > }); > > > } > > > You don''t keep a reference to the closure used in the each() method, > > so you don''t have to consider the implications of myNiftyMethod''s > > parameters and variables being retained. And it''s a very powerful and > > expressive way to deal with each item in the array. > > > > - I''m getting lost in how you constructed the onSuccess callback... > > > That''s easy to do. :-) He''s using a closure to construct and return > > another closure; it''s the inner one that gets assigned to the > > onSuccess handler and retained, the outer one is run immediately and > > discarded. If you look carefully at the code defining the onSuccess > > handler, you''ll see that the entire outer closure is wrapped in parens > > -- the opening paren is right after "onSuccess:", and then right at > > the end of the closure you see the closing paren followed by "(item)" > > -- that "(item)" tells you he''s *executing* the outer closure right > > then, not just creating it. When it runs, the outer closure creates > > the inner closure and returns it. *That''s* what gets assigned to > > onSuccess, the reference to the inner closure. The outer closure has > > only the param it needs (item) and no local variables, so the inner > > closure only preserves the information it really needs, not all of the > > local variables where all of this is running. > > > Hope this helps, > > -- > > T.J. Crowder > > tj /crowder software / com > > > On Feb 23, 7:34 am, "Manu Temmerman-Uyttenbroeck" > > > <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Hi, > > > > Closures is something that (can) cause memory leaks, right? > > > kangax, would you mind explaining in a bit more detail why you wrote the > > > code like you wrote it? I''m a bit lost in it. I restructured the code you > > > wrote a bit...http://pastie.caboo.se/156248 > > > - Is there a reason why you don''t write a '';'' after the new Ajax.Request > > > (...)? > > > - Is there a reason why you don''t write a '';'' after the > > > someArray.each(function(item) > > > { ... })? > > > - I''m getting lost in how you constructed the onSuccess callback... > > > > Thx... > > > > Manu. > > > > On Fri, Feb 22, 2008 at 11:11 PM, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > Looks like a closure issue to me (solved with another closure). > > > > Also, is that an array you are iterating over using "for..in" ? > > > > > siteListArray.each(function(item) { > > > > var url = ''functions.php?command=numberOfErrors&site='' + item; > > > > new Ajax.Request(url, { > > > > onSuccess: (function(item) { return function(t) { > > > > $(''sidebar_site_div_'' + item).update(t.responseText); > > > > }})(item) > > > > }) > > > > }) > > > > > - kangax > > > > > On Feb 22, 4:02 pm, Chach <carterharri...-ee4meeAH724@public.gmane.org> wrote: > > > > > Hi everybody, > > > > > > I''m just getting kicked off on prototype and I''m having a problem that > > > > > I''m hoping to get some help on.. I''ve had good success with > > > > > Ajax.Updater, but now I''m trying to use Ajax.Request with the use of > > > > > its callback abilities. My issue is that I''m trying to get a hold of > > > > > one of the Element objects in the DOM using $(''element''), however the > > > > > name of the element can vary and so I have to assemble the name using > > > > > the value in an array. It''s almost like the siteListArray[x] does not > > > > > work in the callback. Is it possible that the callback cannot see a > > > > > variable that was declared earlier in my code at a global scope? > > > > > Thanks in advance. > > > > > > for (x in siteListArray) > > > > > { > > > > > var url = ''functions.php?command=numberOfErrors&site='' + > > > > > siteListArray[x]; > > > > > new Ajax.Request(url, { > > > > > asynchronous:true, > > > > > onComplete: function(transport) { > > > > > $(''sidebar_site_div_'' + > > > > > siteListArray[x]).update(transport.responseText); > > > > > } > > > > > }); > > > > > > }--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Man this is complex :) I just want to see if I start to understand... The basic example on http://prototypejs.org/api/ajax/request also has a closure, because the onSuccess callback function is defined inline, correct? So if that ''new Ajax.Request'' is in a function, then that url variable will not be released until that ajax request successfully finishes and that onSuccess function runs? What happens then when the ajax request is not successfull and throws an exception. That url value will stay in memory until you navigate away from the page? What happens when you didn''t only store a url string, but let''s say a reference to a collection of 200 dom objects and the ajax request fails. Circular reference? Meaning a ''real'' memory leak. That memory won''t be released even after navigating away from the page. Manu. ps: Do you give private lessons? :D On Sat, Feb 23, 2008 at 2:37 PM, T.J. Crowder <tjcrowder-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > @kangax: :-) > > @all: I should mention that I don''t know for sure that this create-a- > closure-within-a-closure idiom works in terms of the garbage > collectors out there; I''ve always intended to go find out because it > seems like there''s a chain involved and it wouldn''t necessarily be > broken by doing that. I''d be really interested in any references > folks have to empirical results on that, since as Manu points out, it > might matter in terms of memory use. A quick-and-dirty test in FF2 > for Windows suggests that FF doesn''t release the context in this > scenario: > > var keeper = null; > function executionContextTest() > { > var a; > var n; > > a = new Array(); > for (n = 200000; n > 0; --n) > { > a[n] = new Date(); > } > > // keeper = function() { > // alert(''This is the keeper function''); > // }; > > keeper = (function() { > return function() { > alert(''This is the keeper function''); > } > })(); > } > > (Where I trigger executionContextTest via a button.) The commented- > out code would definitely preserve the execution context and therefore > the array, but the second example is using the closure-creates-a- > closure idiom. FF seems to keep all of the execution contexts alive > (and therefore preserve the array) in this case as well. When I run > this, FF''s memory use goes up by about 19MB, and doesn''t come down > again until I use another button to release the keeper reference (and > then an alert to jog the garbage collector). If I don''t create the > closure at all, the memory is reclaimed as soon as > executionContextTest completes (without having to jog the garbage > collector). > > But again, this was not in any way a scientific test. If anyone can > point me at some... :-) > > @Manu: Don''t let this bother you in cases where you''re not keeping a > reference to the closure, that''s the only time the issue of keeping > the execution contexts alive comes up. Use-and-discard closures are > not a problem (and very useful). > -- > T.J. Crowder > tj /crowder software / com > > On Feb 23, 12:43 pm, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Wow, that''s one thorough explanation. > > Thanks T.J. > > > > On Feb 23, 5:01 am, "T.J. Crowder" <tjcrow...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > Hi, > > > > > > Closures is something that (can) cause memory leaks, right? > > > > > That''s a complex topic. :-) Closures inherit, and therefore preserve > > > for their lifecycles, all of the local variables and parameters of the > > > functions they''re defined in. If the closure is used immediately and > > > discarded, you don''t much care. If you''re going to retain a reference > > > to the closure (for instance, an event handler, or a dynamically- > > > created instance method), then you want to be aware of this. Here''s > > > an example of the latter case: > > > > > function myNiftyMethod(param) > > > { > > > var v1, v2, v3; > > > > > // ... do something ... > > > > > // create and retain a closure to do something > > > this.thingy = function() { > > > // ... some code for the closure ... > > > }; > > > > > } > > > > > When myNiftyMethod is executed, it creates a closure and remembers it > > > on the object instance as this.thingy. Since the closure holds a > > > reference to all of myNiftyMethods local variables and params (even > > > though it doesn''t use them), and since the object instance keeps a > > > reference to the closure, ''param'', ''v1'', ''v2'', and ''v3'' all live on > > > for as long as the closure does. (Modulo cool JavaScript engine > > > optimisations, which I don''t think are common yet and are harder for > > > the engine to do than it would at first seem.) > > > > > So closures can have memory *implications*; if you understand how they > > > work, though, and get used to some idioms around them, you won''t cause > > > memory leaks (barring JavaScript engine bugs). > > > > > This is rambling a bit, but here''s an example of the case where you''re > > > using the closure immediately and discarding it: > > > > > function myNiftyMethod(someArray) > > > { > > > var v1, v2, v3; > > > > > // ... do something ... > > > > > // create and retain a closure to do something > > > someArray.each(function(item) { > > > item.doSomethingCool(); > > > }); > > > > > } > > > > > You don''t keep a reference to the closure used in the each() method, > > > so you don''t have to consider the implications of myNiftyMethod''s > > > parameters and variables being retained. And it''s a very powerful and > > > expressive way to deal with each item in the array. > > > > > > - I''m getting lost in how you constructed the onSuccess callback... > > > > > That''s easy to do. :-) He''s using a closure to construct and return > > > another closure; it''s the inner one that gets assigned to the > > > onSuccess handler and retained, the outer one is run immediately and > > > discarded. If you look carefully at the code defining the onSuccess > > > handler, you''ll see that the entire outer closure is wrapped in parens > > > -- the opening paren is right after "onSuccess:", and then right at > > > the end of the closure you see the closing paren followed by "(item)" > > > -- that "(item)" tells you he''s *executing* the outer closure right > > > then, not just creating it. When it runs, the outer closure creates > > > the inner closure and returns it. *That''s* what gets assigned to > > > onSuccess, the reference to the inner closure. The outer closure has > > > only the param it needs (item) and no local variables, so the inner > > > closure only preserves the information it really needs, not all of the > > > local variables where all of this is running. > > > > > Hope this helps, > > > -- > > > T.J. Crowder > > > tj /crowder software / com > > > > > On Feb 23, 7:34 am, "Manu Temmerman-Uyttenbroeck" > > > > > <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > Hi, > > > > > > Closures is something that (can) cause memory leaks, right? > > > > kangax, would you mind explaining in a bit more detail why you wrote > the > > > > code like you wrote it? I''m a bit lost in it. I restructured the > code you > > > > wrote a bit...http://pastie.caboo.se/156248 > > > > - Is there a reason why you don''t write a '';'' after the new > Ajax.Request > > > > (...)? > > > > - Is there a reason why you don''t write a '';'' after the > > > > someArray.each(function(item) > > > > { ... })? > > > > - I''m getting lost in how you constructed the onSuccess callback... > > > > > > Thx... > > > > > > Manu. > > > > > > On Fri, Feb 22, 2008 at 11:11 PM, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > > Looks like a closure issue to me (solved with another closure). > > > > > Also, is that an array you are iterating over using "for..in" ? > > > > > > > siteListArray.each(function(item) { > > > > > var url = ''functions.php?command=numberOfErrors&site='' + item; > > > > > new Ajax.Request(url, { > > > > > onSuccess: (function(item) { return function(t) { > > > > > $(''sidebar_site_div_'' + item).update(t.responseText); > > > > > }})(item) > > > > > }) > > > > > }) > > > > > > > - kangax > > > > > > > On Feb 22, 4:02 pm, Chach <carterharri...-ee4meeAH724@public.gmane.org> wrote: > > > > > > Hi everybody, > > > > > > > > I''m just getting kicked off on prototype and I''m having a > problem that > > > > > > I''m hoping to get some help on.. I''ve had good success with > > > > > > Ajax.Updater, but now I''m trying to use Ajax.Request with the > use of > > > > > > its callback abilities. My issue is that I''m trying to get a > hold of > > > > > > one of the Element objects in the DOM using $(''element''), > however the > > > > > > name of the element can vary and so I have to assemble the name > using > > > > > > the value in an array. It''s almost like the siteListArray[x] > does not > > > > > > work in the callback. Is it possible that the callback cannot > see a > > > > > > variable that was declared earlier in my code at a global scope? > > > > > > Thanks in advance. > > > > > > > > for (x in siteListArray) > > > > > > { > > > > > > var url = ''functions.php?command=numberOfErrors&site='' + > > > > > > siteListArray[x]; > > > > > > new Ajax.Request(url, { > > > > > > asynchronous:true, > > > > > > onComplete: function(transport) { > > > > > > $(''sidebar_site_div_'' + > > > > > > siteListArray[x]).update(transport.responseText); > > > > > > } > > > > > > }); > > > > > > > > } > > >--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 24, 1:31 am, "Manu Temmerman-Uyttenbroeck" <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> The basic example onhttp://prototypejs.org/api/ajax/requestalso has a > closure, because the onSuccess callback function is defined inline, correct? > So if that ''new Ajax.Request'' is in a function, then that url variable will > not be released until that ajax request successfully finishes and that > onSuccess function runs? > What happens then when the ajax request is not successfull and throws an > exception. That url value will stay in memory until you navigate away from > the page?Unless the request object itself gets dereferenced. If I''m inside a function and I say... var foo = new Ajax.Request(/*...*/); ... then once the function goes out of scope, I won''t be able to obtain a reference to it again. (This is assuming that variable isn''t a part of *some other* closure created inside the function. The browser knows this, so when the request has completed its life-cycle (even by throwing exception), it''ll GC the object if nothing references it. And that would also GC the closure formed by attaching that anonymous function to the object. Now, if I say... window.foo = new Ajax.Request(/*... */); ... then I''ve set a global reference that will never go out of scope. That means my request object won''t be GC''ed unless I explicitly dereference later on (window.foo = null). Let''s make a diagram. Think of "window" (the global scope) as a big circle in the middle of the page. Imagine everything -- strings, numbers, objects, etc. -- as nodes. Now draw lines between nodes to make references. (window connects to Ajax, Ajax connects to Ajax.Request, etc.) Anything that can be traced back to "window" must be kept in memory. If I remove a reference to something, that erases a line from the diagram, and any resulting "node island" can be GC''d. Even if you''ve got two objects that reference one another, if neither one of them can be referenced from the global scope, they can be purged from memory, since it''s impossible to refer to them. (Of course, IE has its own problem with circular references, which brings me to your next question...)> What happens when you didn''t only store a url string, but let''s say a > reference to a collection of 200 dom objects and the ajax request fails. > Circular reference? Meaning a ''real'' memory leak. That memory won''t be > released even after navigating away from the page.Yeah, and that''s the sort of thing that can''t easily be solved inside the JS environment (except through cautious coding). Of course, IE7 claims to have fixed many of those leaks, so maybe you should make a test page and find out. ;-) Cheers, Andrew --~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Thx a lot for helping me visualize it! On Sun, Feb 24, 2008 at 11:08 AM, Andrew Dupont <google-TiabPMV39B5K4mp1Ns0Z8Q@public.gmane.org> wrote:> > > > On Feb 24, 1:31 am, "Manu Temmerman-Uyttenbroeck" > <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > The basic example onhttp://prototypejs.org/api/ajax/requestalso has a > > closure, because the onSuccess callback function is defined inline, > correct? > > So if that ''new Ajax.Request'' is in a function, then that url variable > will > > not be released until that ajax request successfully finishes and that > > onSuccess function runs? > > What happens then when the ajax request is not successfull and throws an > > exception. That url value will stay in memory until you navigate away > from > > the page? > > Unless the request object itself gets dereferenced. > > If I''m inside a function and I say... > > var foo = new Ajax.Request(/*...*/); > > ... then once the function goes out of scope, I won''t be able to > obtain a reference to it again. (This is assuming that variable isn''t > a part of *some other* closure created inside the function. The > browser knows this, so when the request has completed its life-cycle > (even by throwing exception), it''ll GC the object if nothing > references it. And that would also GC the closure formed by attaching > that anonymous function to the object. > > Now, if I say... > > window.foo = new Ajax.Request(/*... */); > > ... then I''ve set a global reference that will never go out of scope. > That means my request object won''t be GC''ed unless I explicitly > dereference later on (window.foo = null). > > Let''s make a diagram. Think of "window" (the global scope) as a big > circle in the middle of the page. Imagine everything -- strings, > numbers, objects, etc. -- as nodes. Now draw lines between nodes to > make references. (window connects to Ajax, Ajax connects to > Ajax.Request, etc.) > > Anything that can be traced back to "window" must be kept in memory. > If I remove a reference to something, that erases a line from the > diagram, and any resulting "node island" can be GC''d. Even if you''ve > got two objects that reference one another, if neither one of them can > be referenced from the global scope, they can be purged from memory, > since it''s impossible to refer to them. > > (Of course, IE has its own problem with circular references, which > brings me to your next question...) > > > > What happens when you didn''t only store a url string, but let''s say a > > reference to a collection of 200 dom objects and the ajax request fails. > > Circular reference? Meaning a ''real'' memory leak. That memory won''t be > > released even after navigating away from the page. > > Yeah, and that''s the sort of thing that can''t easily be solved inside > the JS environment (except through cautious coding). Of course, IE7 > claims to have fixed many of those leaks, so maybe you should make a > test page and find out. ;-) > > Cheers, > Andrew > > >--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Just reporting back, as I suspected, you won''t avoid preserving the outer function''s context by creating an anonymous closure to create the closure, the entire scope chain is preserved until the request completes and the reference to the request is released (which allows the references to the closures to be released, which releases the scope chain of call objects -- "activation objects" in ECMA parlance -- since the only remaining references are circular). Sorry for giving the wrong impression earlier, even if it did come with a caveat. :) But in any case, since the XHR call *will* complete (successfully or otherwise), and the request will be released, this isn''t a memory leak. It uses memory for a little while (for a good purpose), but doesn''t leak it. -- T.J. Crowder tj / crowder software / com On Feb 24, 11:25 am, "Manu Temmerman-Uyttenbroeck" <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Thx a lot for helping me visualize it! > > On Sun, Feb 24, 2008 at 11:08 AM, Andrew Dupont <goo...-TiabPMV39B5K4mp1Ns0Z8Q@public.gmane.org> > wrote: > > > > > On Feb 24, 1:31 am, "Manu Temmerman-Uyttenbroeck" > > <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > The basic example onhttp://prototypejs.org/api/ajax/requestalsohas a > > > closure, because the onSuccess callback function is defined inline, > > correct? > > > So if that ''new Ajax.Request'' is in a function, then that url variable > > will > > > not be released until that ajax request successfully finishes and that > > > onSuccess function runs? > > > What happens then when the ajax request is not successfull and throws an > > > exception. That url value will stay in memory until you navigate away > > from > > > the page? > > > Unless the request object itself gets dereferenced. > > > If I''m inside a function and I say... > > > var foo = new Ajax.Request(/*...*/); > > > ... then once the function goes out of scope, I won''t be able to > > obtain a reference to it again. (This is assuming that variable isn''t > > a part of *some other* closure created inside the function. The > > browser knows this, so when the request has completed its life-cycle > > (even by throwing exception), it''ll GC the object if nothing > > references it. And that would also GC the closure formed by attaching > > that anonymous function to the object. > > > Now, if I say... > > > window.foo = new Ajax.Request(/*... */); > > > ... then I''ve set a global reference that will never go out of scope. > > That means my request object won''t be GC''ed unless I explicitly > > dereference later on (window.foo = null). > > > Let''s make a diagram. Think of "window" (the global scope) as a big > > circle in the middle of the page. Imagine everything -- strings, > > numbers, objects, etc. -- as nodes. Now draw lines between nodes to > > make references. (window connects to Ajax, Ajax connects to > > Ajax.Request, etc.) > > > Anything that can be traced back to "window" must be kept in memory. > > If I remove a reference to something, that erases a line from the > > diagram, and any resulting "node island" can be GC''d. Even if you''ve > > got two objects that reference one another, if neither one of them can > > be referenced from the global scope, they can be purged from memory, > > since it''s impossible to refer to them. > > > (Of course, IE has its own problem with circular references, which > > brings me to your next question...) > > > > What happens when you didn''t only store a url string, but let''s say a > > > reference to a collection of 200 dom objects and the ajax request fails. > > > Circular reference? Meaning a ''real'' memory leak. That memory won''t be > > > released even after navigating away from the page. > > > Yeah, and that''s the sort of thing that can''t easily be solved inside > > the JS environment (except through cautious coding). Of course, IE7 > > claims to have fixed many of those leaks, so maybe you should make a > > test page and find out. ;-) > > > Cheers, > > Andrew--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Thought this one might come in handy for some of us closure noobs: http://blog.morrisjohns.com/javascript_closures_for_dummies On Mon, Feb 25, 2008 at 1:58 PM, T.J. Crowder <tjcrowder-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Just reporting back, as I suspected, you won''t avoid preserving the > outer function''s context by creating an anonymous closure to create > the closure, the entire scope chain is preserved until the request > completes and the reference to the request is released (which allows > the references to the closures to be released, which releases the > scope chain of call objects -- "activation objects" in ECMA parlance > -- since the only remaining references are circular). Sorry for > giving the wrong impression earlier, even if it did come with a > caveat. :) > > But in any case, since the XHR call *will* complete (successfully or > otherwise), and the request will be released, this isn''t a memory > leak. It uses memory for a little while (for a good purpose), but > doesn''t leak it. > -- > T.J. Crowder > tj / crowder software / com > > On Feb 24, 11:25 am, "Manu Temmerman-Uyttenbroeck" > <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Thx a lot for helping me visualize it! > > > > On Sun, Feb 24, 2008 at 11:08 AM, Andrew Dupont <goo...-TiabPMV39B5K4mp1Ns0Z8Q@public.gmane.org > > > > wrote: > > > > > > > > > On Feb 24, 1:31 am, "Manu Temmerman-Uyttenbroeck" > > > <manu.temmermanuyttenbro...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > The basic example onhttp://prototypejs.org/api/ajax/requestalsohas a > > > > closure, because the onSuccess callback function is defined inline, > > > correct? > > > > So if that ''new Ajax.Request'' is in a function, then that url > variable > > > will > > > > not be released until that ajax request successfully finishes and > that > > > > onSuccess function runs? > > > > What happens then when the ajax request is not successfull and > throws an > > > > exception. That url value will stay in memory until you navigate > away > > > from > > > > the page? > > > > > Unless the request object itself gets dereferenced. > > > > > If I''m inside a function and I say... > > > > > var foo = new Ajax.Request(/*...*/); > > > > > ... then once the function goes out of scope, I won''t be able to > > > obtain a reference to it again. (This is assuming that variable isn''t > > > a part of *some other* closure created inside the function. The > > > browser knows this, so when the request has completed its life-cycle > > > (even by throwing exception), it''ll GC the object if nothing > > > references it. And that would also GC the closure formed by attaching > > > that anonymous function to the object. > > > > > Now, if I say... > > > > > window.foo = new Ajax.Request(/*... */); > > > > > ... then I''ve set a global reference that will never go out of scope. > > > That means my request object won''t be GC''ed unless I explicitly > > > dereference later on (window.foo = null). > > > > > Let''s make a diagram. Think of "window" (the global scope) as a big > > > circle in the middle of the page. Imagine everything -- strings, > > > numbers, objects, etc. -- as nodes. Now draw lines between nodes to > > > make references. (window connects to Ajax, Ajax connects to > > > Ajax.Request, etc.) > > > > > Anything that can be traced back to "window" must be kept in memory. > > > If I remove a reference to something, that erases a line from the > > > diagram, and any resulting "node island" can be GC''d. Even if you''ve > > > got two objects that reference one another, if neither one of them can > > > be referenced from the global scope, they can be purged from memory, > > > since it''s impossible to refer to them. > > > > > (Of course, IE has its own problem with circular references, which > > > brings me to your next question...) > > > > > > What happens when you didn''t only store a url string, but let''s say > a > > > > reference to a collection of 200 dom objects and the ajax request > fails. > > > > Circular reference? Meaning a ''real'' memory leak. That memory won''t > be > > > > released even after navigating away from the page. > > > > > Yeah, and that''s the sort of thing that can''t easily be solved inside > > > the JS environment (except through cautious coding). Of course, IE7 > > > claims to have fixed many of those leaks, so maybe you should make a > > > test page and find out. ;-) > > > > > Cheers, > > > Andrew > > >--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
T.J. Crowder wrote:> That''s easy to do. :-) He''s using a closure to construct and return > another closure; it''s the inner one that gets assigned to the > onSuccess handler and retained, the outer one is run immediately and > discarded. If you look carefully at the code defining the onSuccess > handler, you''ll see that the entire outer closure is wrapped in parens > -- the opening paren is right after "onSuccess:", and then right at > the end of the closure you see the closing paren followed by "(item)" > -- that "(item)" tells you he''s *executing* the outer closure right > then, not just creating it. When it runs, the outer closure creates > the inner closure and returns it. *That''s* what gets assigned to > onSuccess, the reference to the inner closure. The outer closure has > only the param it needs (item) and no local variables, so the inner > closure only preserves the information it really needs, not all of the > local variables where all of this is running.I do not believe that this loses any references to local variables. For example, consider: javascript:function%20t(){var%20a=1;return(function(x){return%20function (y){alert(x+y+a)}})(2);}t()(3); The value of a is retained, and if you change the value of a you will see different results in the alert. Have I overlooked an important issue? -- Raul --~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Raul, No, you haven''t -- see my follow-up post from a couple of days back. All of the intervening stuff is retained. I''ve actually been into this in some detail now with Flanagan''s book, the ECMA spec, and a few other places, and I''m working up a blog entry de-mystifying closures, call objects, and the scope chain. I''ll post a link when I finally get it done -- 8-week-old babies *really* eat up your spare time! :-) (But they''re worth it.) -- T.J. :-) On Feb 27, 4:44 pm, "Miller, Raul D" <rdmil...-b1liDLKdkLdWk0Htik3J/w@public.gmane.org> wrote:> T.J. Crowder wrote: > > That''s easy to do. :-) He''s using a closure to construct and return > > another closure; it''s the inner one that gets assigned to the > > onSuccess handler and retained, the outer one is run immediately and > > discarded. If you look carefully at the code defining the onSuccess > > handler, you''ll see that the entire outer closure is wrapped in parens > > -- the opening paren is right after "onSuccess:", and then right at > > the end of the closure you see the closing paren followed by "(item)" > > -- that "(item)" tells you he''s *executing* the outer closure right > > then, not just creating it. When it runs, the outer closure creates > > the inner closure and returns it. *That''s* what gets assigned to > > onSuccess, the reference to the inner closure. The outer closure has > > only the param it needs (item) and no local variables, so the inner > > closure only preserves the information it really needs, not all of the > > local variables where all of this is running. > > I do not believe that this loses any references to local variables. > > For example, consider: > javascript:function%20t(){var%20a=1;return(function(x){return%20function > (y){alert(x+y+a)}})(2);}t()(3); > > The value of a is retained, and if you change the value of a you will > see different results in the alert. > > Have I overlooked an important issue? > > -- > Raul--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 28, 7:59 am, "T.J. Crowder" <tjcrow...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: [...]> I''ve actually been into this > in some detail now with Flanagan''s book,Flanagan is OK, but not great.> the ECMA spec, and a few > other places, and I''m working up a blog entry de-mystifying closures,You could do worse than to start here: <URL; http://www.jibbering.com/faq/faq_notes/closures.html >> call objectsThe call property of Function.prototype is *an* object - a specific kind of object: a function.> and the scope chain.I think the above reference covers that pretty well too, as well as the resolution of identifiers and property names. You might also like the link below, which does a pretty good job of explaining prototype inheritance with diagrams: <URL: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html>-- Rob --~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 28, 2:44 am, "Miller, Raul D" <rdmil...-b1liDLKdkLdWk0Htik3J/w@public.gmane.org> wrote:> T.J. Crowder wrote: > > That''s easy to do. :-) He''s using a closure to construct and return > > another closure; it''s the inner one that gets assigned to the > > onSuccess handler and retained, the outer one is run immediately and > > discarded. If you look carefully at the code defining the onSuccess > > handler, you''ll see that the entire outer closure is wrapped in parens > > -- the opening paren is right after "onSuccess:", and then right at > > the end of the closure you see the closing paren followed by "(item)" > > -- that "(item)" tells you he''s *executing* the outer closure right > > then, not just creating it. When it runs, the outer closure creates > > the inner closure and returns it. *That''s* what gets assigned to > > onSuccess, the reference to the inner closure. The outer closure has > > only the param it needs (item) and no local variables, so the inner > > closure only preserves the information it really needs, not all of the > > local variables where all of this is running.A function declaration or statement within another function declaration or statement forms a closure with the outer function''s execution object when the code is executed. You don''t have to actually reference any of the outer function''s local variables to create the closure, it''s added to the inner function''s scope chain always. function foo() { var x = function(){}; } The function assigned to x has a closure to the execution object created when foo() is called. There are no references to foo''s local variables so there is no way to access them, but the closure is still created. This technique is used to create private variables in javascript. <URL: http://javascript.crockford.com/private.html > [...]> Have I overlooked an important issue?Perhaps. -- Rob --~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
@Rob: Thanks for the links. @All: I promised to write back when I finally finished that post; here it is for what it''s worth: http://niftysnippets.blogspot.com/2008/02/closures-are-not-complicated.html -- T.J. :-) On Feb 27, 11:24 pm, RobG <rg...-AFFH1GffN5hPR4JQBCEnsQ@public.gmane.org> wrote:> On Feb 28, 2:44 am, "Miller, Raul D" <rdmil...-b1liDLKdkLdWk0Htik3J/w@public.gmane.org> wrote: > > > T.J. Crowder wrote: > > > That''s easy to do. :-) He''s using a closure to construct and return > > > another closure; it''s the inner one that gets assigned to the > > > onSuccess handler and retained, the outer one is run immediately and > > > discarded. If you look carefully at the code defining the onSuccess > > > handler, you''ll see that the entire outer closure is wrapped in parens > > > -- the opening paren is right after "onSuccess:", and then right at > > > the end of the closure you see the closing paren followed by "(item)" > > > -- that "(item)" tells you he''s *executing* the outer closure right > > > then, not just creating it. When it runs, the outer closure creates > > > the inner closure and returns it. *That''s* what gets assigned to > > > onSuccess, the reference to the inner closure. The outer closure has > > > only the param it needs (item) and no local variables, so the inner > > > closure only preserves the information it really needs, not all of the > > > local variables where all of this is running. > > A function declaration or statement within another function > declaration or statement forms a closure with the outer function''s > execution object when the code is executed. You don''t have to > actually reference any of the outer function''s local variables to > create the closure, it''s added to the inner function''s scope chain > always. > > function foo() { > var x = function(){}; > > } > > The function assigned to x has a closure to the execution object > created when foo() is called. There are no references to foo''s local > variables so there is no way to access them, but the closure is still > created. This technique is used to create private variables in > javascript. > > <URL:http://javascript.crockford.com/private.html> > > [...] > > > Have I overlooked an important issue? > > Perhaps. > > -- > Rob--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Great article! I''m looking forward to the next post. Manu. On Fri, Feb 29, 2008 at 2:28 PM, T.J. Crowder <tjcrowder-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > @Rob: Thanks for the links. > > @All: I promised to write back when I finally finished that post; > here it is for what it''s worth: > http://niftysnippets.blogspot.com/2008/02/closures-are-not-complicated.html > > -- T.J. :-) > > On Feb 27, 11:24 pm, RobG <rg...-AFFH1GffN5hPR4JQBCEnsQ@public.gmane.org> wrote: > > On Feb 28, 2:44 am, "Miller, Raul D" <rdmil...-b1liDLKdkLdWk0Htik3J/w@public.gmane.org> wrote: > > > > > T.J. Crowder wrote: > > > > That''s easy to do. :-) He''s using a closure to construct and return > > > > another closure; it''s the inner one that gets assigned to the > > > > onSuccess handler and retained, the outer one is run immediately and > > > > discarded. If you look carefully at the code defining the onSuccess > > > > handler, you''ll see that the entire outer closure is wrapped in > parens > > > > -- the opening paren is right after "onSuccess:", and then right at > > > > the end of the closure you see the closing paren followed by > "(item)" > > > > -- that "(item)" tells you he''s *executing* the outer closure right > > > > then, not just creating it. When it runs, the outer closure creates > > > > the inner closure and returns it. *That''s* what gets assigned to > > > > onSuccess, the reference to the inner closure. The outer closure > has > > > > only the param it needs (item) and no local variables, so the inner > > > > closure only preserves the information it really needs, not all of > the > > > > local variables where all of this is running. > > > > A function declaration or statement within another function > > declaration or statement forms a closure with the outer function''s > > execution object when the code is executed. You don''t have to > > actually reference any of the outer function''s local variables to > > create the closure, it''s added to the inner function''s scope chain > > always. > > > > function foo() { > > var x = function(){}; > > > > } > > > > The function assigned to x has a closure to the execution object > > created when foo() is called. There are no references to foo''s local > > variables so there is no way to access them, but the closure is still > > created. This technique is used to create private variables in > > javascript. > > > > <URL:http://javascript.crockford.com/private.html> > > > > [...] > > > > > Have I overlooked an important issue? > > > > Perhaps. > > > > -- > > Rob > > >--~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---