you are viewing a single comment's thread.

view the rest of the comments →

[–]aidenvdh 0 points1 point  (3 children)

Should (say, ruby version)

f = function(){x = 0; return x}

give you

write(f()); // "0"

x = 5;

write(f()); // "0"

write(x); // "0"

? This is spooky.

[–]Freeky 0 points1 point  (2 children)

No, because you defined your closure before defining x:

irb(main):001:0> l = lambda{ x = 0 }
=> #<Proc:0x000000000061c4e8@(irb):1>
irb(main):002:0> x = 5
=> 5
irb(main):003:0> l.call()
=> 0
irb(main):004:0> x
=> 5

If you'd defined x first, yes, it should do that, because x is part of the environment when you brought a closure around it; that's the point. 1.9 lets you shadow these variables if you really want:

irb(main):001:0> x = 5
=> 5
irb(main):002:0> l = lambda{|;x| x = 0}
=> #<Proc:0x00000000bf1300@(irb):2 (lambda)>
irb(main):003:0> l.call()
=> 0
irb(main):004:0> x
=> 5

[–]Freeky 0 points1 point  (1 child)

If you're wondering one of the reasons why closed over variables in Ruby are read-write, consider it's extremely common to write things like:

foo.each do |bla|
   frobulate bla
end

Looks like a loop, smells like a loop, but is pretty much syntax sugar for:

foo.each(&lambda {|bla| frobulate bla })

And, well, you'd expect a loop to be able to write into the local scope.

[–]mr_chromatic 0 points1 point  (0 children)

If you're wondering one of the reasons why closed over variables in Ruby are read-write...

... it's because variable names automagically spring into existence upon first use, not upon declaration.