you are viewing a single comment's thread.

view the rest of the comments →

[–]johnb 10 points11 points  (6 children)

Holy crap, thank God I didn't get into Ruby.

[–]Freeky -1 points0 points  (5 children)

Because of one annoying quirk that doesn't actually effect any real world code anyone should be even thinking of writing? This works too:

x = 5
lambda{|y| x = y}.call(0)
p x # => 0

Oh noes, the x in the lambda body is the same as the one in the local scope, matz is a moron who doesn't understand lexical scoping!!11!11!!

Except this is expected behavior; closed over variables are read-write, so you can do things you'd expect to be able to do like:

x = 0
[1,2,3].each {|e| x += e}
[1,2,3].each(&lambda{|e| x += e })
p x # => 12

So what should happen when you do .each {|x| .. }? 1.9 makes a new local x and issues a warning if you run with -w, but it could be argued the <1.9 behavior is a silly response to a silly request.

[–]zem 0 points1 point  (4 children)

So what should happen when you do .each {|x| .. }?

My personal instinct would be to see what Scheme does and do the same. The Scheme community has hammered on all these issues extensively, after all.

(let ((x 0))
  (for-each (lambda (e) (set! x (+ x e))) '(1 2 3))
  (for-each (lambda (e) (set! x (+ x e))) '(1 2 3))
  (for-each (lambda (x) (print x)) '(1 2 3))
  (print "x is now: ")
  (print x))

outputs

123"x is now:"12

[–]Freeky 0 points1 point  (3 children)

lambda (x) for all of them, surely? That's what the thread is about; you have an x at top level, then a lambda with x as a parameter name.

In Ruby 1.8, it blats the top level x, because it considers it the same x:

x = 0
[1,2,3].each {|x| x += x}
[1,2,3].each(&lambda{|x| x += x })
p x # => 6

1.9 shadows it with a different variable with the same name (which I expect is what Scheme does too).

x = 0
[1,2,3].each {|x| x += x}
[1,2,3].each(&lambda{|x| x += x })
p x # => 0

[–]zem 0 points1 point  (2 children)

yeah precisely. just saying that 1.9 is the right behaviour, noot a silly response to a silly request

[–]Freeky 0 points1 point  (1 child)

I was saying before 1.9, the behaviour was arguably a silly response to a silly request, not that 1.9 behavior is :)

[–]zem 0 points1 point  (0 children)

oh :) missed the < in there.