From: Josh Cheek Date: 2010-05-05T16:35:33+09:00 Subject: Re: for-in vs. map closures --0016364d26d3d1fcb00485d3ded8 Content-Type: text/plain; charset=ISO-8859-1 On Wed, May 5, 2010 at 1:35 AM, Mike Austin wrote: > I was experimenting with closures and JavaScript's and Ruby's > behavior. Ruby seems to close over its arguments automatically if > using map: > > [1, 2, 3].map { |n| lambda { n * n } }.map { |b| b.call() } # [1, 4, > 9] > > But using "for" iteration, returns a different result: > > a = [] > for n in [1, 2, 3] do a << lambda { n * n } end > a.map { |b| b.call() } # [9, 9, 9] > > This is also the behavior in JavaScript, which frequently catches > developers off guard when attaching event handlers to elements. > > Can anyone explain the difference? Is map creating a new anonymous > function every iteration? > > Mike > > I don't know, it seems like very peculiar behaviour. It does create new lambdas every time, but strangely, the objects created within the block are shared. a = Array.new for s in %w(a b c) s2 = s a << lambda { [ s2 , s , s2.object_id ] } end a.map { |b| b.call() } # => [["c", "c", 2148175880], ["c", "c", 2148175880], ["c", "c", 2148175880]] a[0].object_id # => 2148175860 a[1].object_id # => 2148175840 a[2].object_id # => 2148175820 --0016364d26d3d1fcb00485d3ded8--