Bugs item #7680, was opened at 2007-01-08 22:53 You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=1698&aid=7680&group_id=426 Category: None Group: None Status: Open Resolution: None Priority: 3 Submitted By: Boris Schmid (bor_) Assigned to: Nobody (None) Summary: a block argument within a block which argument has the same name leaks Initial Comment: This is pasted from the oneclickinstaller of ruby on windows 2003. #irb(main):014:0> array = [1,2,3,4,5] #=> [1, 2, 3, 4, 5] #irb(main):015:0> array.each {|allele| #irb(main):016:1* puts allele #irb(main):017:1> [10,10,10].map {|allele| allele} #irb(main):018:1> puts allele #irb(main):019:1> } #1 #10 #2 #10 #3 #10 #4 #10 #5 #10 #=> [1, 2, 3, 4, 5] Normally, a block argument is no longer accessible outside its block (example below). For some reason it is capable of doing just that in the above example. I am not sure if that is a bug, a feature or bad coding on my part, but for me it was unexpected behaviour. #irb(main):015:0> [10,10,10].map {|allele| allele} #=> [10, 10, 10] #irb(main):016:0> allele #NameError: undefined local variable or method `allele' for #<Object:0x276fa3c#@allele=10> # from (irb):16 #irb(main):017:0> ---------------------------------------------------------------------- You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=1698&aid=7680&group_id=426
on 08.01.2007 22:53
on 08.01.2007 23:30
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Tue, 9 Jan 2007 06:53:40 +0900, <noreply@rubyforge.org> writes:
|Submitted By: Boris Schmid (bor_)
|Assigned to: Nobody (None)
|Summary: a block argument within a block which argument has the same name leaks
It is a expected behavior during 1.8. It will be fixed for 1.9.
matz.
on 09.01.2007 00:39
On Jan 8, 2007, at 2:30 PM, Yukihiro Matsumoto wrote: > > It is a expected behavior during 1.8. It will be fixed for 1.9. Really? What's the plan? I recall from rubyconf 2005 that block args were going to get totally reworked, but I thought that the revision planned had been thrown out in favor of leaving the current behavior.
on 09.01.2007 00:57
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Tue, 9 Jan 2007 08:38:25 +0900, Evan Webb <evan@fallingsnow.net>
writes:
|> It is a expected behavior during 1.8. It will be fixed for 1.9.
|
|Really? What's the plan? I recall from rubyconf 2005 that block args
|were going to get totally reworked, but I thought that the revision
|planned had been thrown out in favor of leaving the current behavior.
You can try it now via matzruby branch in the repository.
% cat test.rb
array = [1,2,3,4,5]
array.each {|allele|
puts allele
[10,10,10].map {|allele| allele}
puts allele
}
puts allele
% ruby -v test.rb
ruby 1.9.0 (2007-01-06 patchlevel 0) [i686-linux] - matz
/tmp/s.rb:7: warning: out-of-scope variable - allele
1
1
2
2
3
3
4
4
5
5
/tmp/s.rb:7: undefined local variable or method `allele' for
main:Object (NameError)
on 09.01.2007 01:24
On Jan 8, 2007, at 3:56 PM, Yukihiro Matsumoto wrote: > |were going to get totally reworked, but I thought that the revision > } > 4 > 4 > 5 > 5 > /tmp/s.rb:7: undefined local variable or method `allele' for > main:Object (NameError) Hrm. So it warns about usage outside the block, but it doesn't allow it to be overridden? I'd think there should have been a warning on line 4 that the 'deeper' allele isn't the same as the shallower one. Also, this implies that all 'deeper' block variables can't be pulled out of the block, is that true? Or are their special rules applied to the block arguments? - Evan
on 09.01.2007 02:35
Hi -- On Tue, 9 Jan 2007, Yukihiro Matsumoto wrote: > > % ruby -v test.rb > ruby 1.9.0 (2007-01-06 patchlevel 0) [i686-linux] - matz > /tmp/s.rb:7: warning: out-of-scope variable - allele I wonder about this though: $ cat warntest.rb #!/usr/local/lib/ruby-matz/bin/ruby -vcw def x puts "hi" end [1,2,3].each {|x| puts x } x $ ./warntest.rb ruby 1.9.0 (2007-01-07 patchlevel 0) [i686-linux] - matz ./warntest.rb:9: warning: out-of-scope variable - x Syntax OK David
on 09.01.2007 02:55
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Tue, 9 Jan 2007 09:23:01 +0900, Evan Phoenix
<evan@fallingsnow.net> writes:
|> /tmp/s.rb:7: warning: out-of-scope variable - allele
|> /tmp/s.rb:7: undefined local variable or method `allele' for main:Object (NameError)
|Hrm. So it warns about usage outside the block, but it doesn't allow
|it to be overridden?
If I understand you correctly, yes.
|I'd think there should have been a warning on
|line 4 that the 'deeper' allele isn't the same as the shallower one.
Try -w option to get a warning. You will get
/tmp/s.rb:4: warning: shadowing outer local variable - allele
matz.
on 09.01.2007 02:59
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Tue, 9 Jan 2007 10:34:53 +0900, dblack@wobblini.net writes:
|I wonder about this though:
|
|$ cat warntest.rb
|#!/usr/local/lib/ruby-matz/bin/ruby -vcw
|
|def x
| puts "hi"
|end
|
|[1,2,3].each {|x| puts x }
|
|x
|
|$ ./warntest.rb
|ruby 1.9.0 (2007-01-07 patchlevel 0) [i686-linux] - matz
|./warntest.rb:9: warning: out-of-scope variable - x
|Syntax OK
Well, it is difficult to warn it correctly. Don't tease the compiler.
;-)
It's not good manner anyway. It may be fixed in the future.
matz.
on 09.01.2007 03:58
Hi -- On Tue, 9 Jan 2007, Yukihiro Matsumoto wrote: > |def x > |Syntax OK > > Well, it is difficult to warn it correctly. Don't tease the compiler. ;-) > It's not good manner anyway. It may be fixed in the future. It's an interesting case, and I can definitely see that it wouldn't be easy to implement. What about just not having the warning? Mostly people wanted block-locals so that they could stop worrying about the names. So maybe it isn't necessary for the compiler to warn. David
on 09.01.2007 04:07
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Tue, 9 Jan 2007 11:57:56 +0900, dblack@wobblini.net writes:
|It's an interesting case, and I can definitely see that it wouldn't be
|easy to implement. What about just not having the warning? Mostly
|people wanted block-locals so that they could stop worrying about the
|names. So maybe it isn't necessary for the compiler to warn.
Using in-block variable outside is the biggest source of my mistakes
in Ruby. I'd like to address this issue in the future. Until then,
it will warn to reduce my headache.
matz.
on 09.01.2007 06:30
Hi, > |It's an interesting case, and I can definitely see that it wouldn't be > |easy to implement. What about just not having the warning? Mostly > |people wanted block-locals so that they could stop worrying about the > |names. So maybe it isn't necessary for the compiler to warn. > > Using in-block variable outside is the biggest source of my mistakes > in Ruby. I'd like to address this issue in the future. Until then, > it will warn to reduce my headache. I agree that it's a little troubling. :-) Even though I don't know the whole dimension of it like you do. :-) Cheers, Joao
on 09.01.2007 07:20
On Jan 8, 2007, at 7:06 PM, Yukihiro Matsumoto wrote: > |names. So maybe it isn't necessary for the compiler to warn. > > Using in-block variable outside is the biggest source of my mistakes > in Ruby. I'd like to address this issue in the future. Until then, > it will warn to reduce my headache. I agree they need work. Why not go back to the rubyconf 2005 proposal? I believe it was to allow new vars created in a block to be normal local variables (not dvars). I've discussed the expected behavior of local variables in ruby to new users and this is what they expect. The other expected behavior is that block arguments are seen to all code 'below' the block and not to any code above.. For example: a = [1,2] a.each do |i| m = "hello" i.upto(10) do |j| n = "evan" # i, j, n, m are seen here. end # j is NOT seen here. # i, m and n are seen here. end # i and j are not NOT seen here. # m and n are seen here. Thoughts?
on 09.01.2007 07:46
On Jan 8, 2007, at 11:19 PM, Evan Phoenix wrote: [snip] > > # j is NOT seen here. > # i, m and n are seen here. > end > > # i and j are not NOT seen here. > # m and n are seen here. I'm not sure how the above code corresponds with your statement above. Why are m and n seen at the end, but not i and j? Is the end of the code not 'below' the block? Why are block-local variables (m and n) going to be seen outside of their block? I certainly would find it very unintuitive (not expected) if this code worked: def foo bar = 12 end foo p bar #=> 12 which seems to be part of what you are suggesting above. The only way m and n should be 'seen' in your above example is if they are assigned values before the block is invoked, thus allowing them to be referenced by the closure. Finally...with respect to block variables i and j, I don't see anything that you are proposing above that is in conflict with either what Matz is suggesting for 2.0 or what exists currently in 1.8. (But perhaps I'm missing something; it is past my bedtime and my mind may be tired.)
on 09.01.2007 09:22
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Tue, 9 Jan 2007 15:19:10 +0900, Evan Phoenix
<evan@fallingsnow.net> writes:
|I agree they need work. Why not go back to the rubyconf 2005
|proposal? I believe it was to allow new vars created in a block to be
|normal local variables (not dvars).
It's 2003. I have not been confident about that idea even after three
years of time. Since blocks are closures, so they need to have their
local variables in any way. Can you imagine a function without local
variables?
matz.
on 09.01.2007 09:31
On Jan 9, 2007, at 12:22 AM, Yukihiro Matsumoto wrote: > > It's 2003. I have not been confident about that idea even after three > years of time. Since blocks are closures, so they need to have their > local variables in any way. Can you imagine a function without local > variables? Of course methods need local variables, but blocks would have local variables still, just all in the scope of their defining method. Why do closures need to have their own, unique variables outside of the scope that they enclose? Smalltalk gets along quite well with all blocks sharing the same local variable scope. The current scope rules are a problem for a lot of new ruby programmers. Lots of them see the current behavior as a bug that they have to work around. - Evan
on 09.01.2007 09:42
Evan Phoenix wrote: > Of course methods need local variables, but blocks would have local > variables still, just all in the scope of their defining method. Why do > closures need to have their own, unique variables outside of the scope > that they enclose? Smalltalk gets along quite well with all blocks > sharing the same local variable scope. The current scope rules are a > problem for a lot of new ruby programmers. Lots of them see the current > behavior as a bug that they have to work around. Evan and I discussed this at length on IRC and I came up with one area that could be damaged by a "flat local scope": DSLs In a large script using a complicated DSL, you would have to make sure all variables were named independently. Even worse, future revisions to that script would have to continue to maintain unique variable names across the entire script. Evan and I do not see eye-to-eye on this, but we agree on many other points: - no way to explicitly scope variables is confusing - bugs arise from missing explicit scoping And we disagree: - I believe lexical scoping is useful and necessary even with problems - I believe no lexical scoping would be far worse than not explicitly scoping variables But we both speak from the point of view of Ruby implementers, so we do not know how correct or incorrect we may be.
on 09.01.2007 16:16
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Tue, 9 Jan 2007 17:31:20 +0900, Evan Phoenix
<evan@fallingsnow.net> writes:
|Of course methods need local variables, but blocks would have local
|variables still, just all in the scope of their defining method. Why
|do closures need to have their own, unique variables outside of the
|scope that they enclose?
As for code blocks, they are rarely needed. But as for anonymous
functions, they are often used. Ruby's block serves both way.
|Smalltalk gets along quite well with all
|blocks sharing the same local variable scope.
Smalltalk have block local variables by explicit declaration (so does
Ruby 1.9), but I feel its blocks have less functional aspect.
|The current scope rules
|are a problem for a lot of new ruby programmers. Lots of them see the
|current behavior as a bug that they have to work around.
I am willing to address. I am a victim too. The point is choosing
_the best way_.
matz.
on 09.01.2007 16:20
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Tue, 9 Jan 2007 17:42:25 +0900, Charles Oliver Nutter
<charles.nutter@sun.com> writes:
|Evan and I do not see eye-to-eye on this, but we agree on many other points:
|
|- no way to explicitly scope variables is confusing
|- bugs arise from missing explicit scoping
For your information, Ruby2 has explicit scoping in blocks.
lambda {|a,b; v1, v2| ...}
Variables a, b (parameters), v1 and v2 are local to the lambda block.
matz.
on 09.01.2007 17:36
Hi -- On Tue, 9 Jan 2007, Charles Oliver Nutter wrote: > could be damaged by a "flat local scope": DSLs > > In a large script using a complicated DSL, you would have to make sure all > variables were named independently. Even worse, future revisions to that > script would have to continue to maintain unique variable names across the > entire script. I'm not quite following this. How does a script that defines a DSL differ from one that doesn't, in terms of scoping needs? David
on 09.01.2007 20:08
dblack@wobblini.net wrote: >>> are a problem for a lot of new ruby programmers. Lots of them see the > I'm not quite following this. How does a script that defines a DSL > differ from one that doesn't, in terms of scoping needs? Just size, I think. Consider a very long rakefile. Having so many blocks is unusual in "normal" ruby code.
on 10.01.2007 01:26
Yukihiro Matsumoto wrote: > For your information, Ruby2 has explicit scoping in blocks. > > lambda {|a,b; v1, v2| ...} > > Variables a, b (parameters), v1 and v2 are local to the lambda block. And otherwise 1.9 still uses the 1.8 lexical scoping semantics, yes?
on 10.01.2007 15:45
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Wed, 10 Jan 2007 09:25:09 +0900, Charles Oliver Nutter
<charles.nutter@sun.com> writes:
|> For your information, Ruby2 has explicit scoping in blocks.
|>
|> lambda {|a,b; v1, v2| ...}
|>
|> Variables a, b (parameters), v1 and v2 are local to the lambda block.
|
|And otherwise 1.9 still uses the 1.8 lexical scoping semantics, yes?
Yes, other local variables are local to innermost surrounding block.
At least until I make a big decision.
matz.
on 10.01.2007 15:49
On Jan 10, 2007, at 8:43 AM, Yukihiro Matsumoto wrote: > |> > |> Variables a, b (parameters), v1 and v2 are local to the lambda > block. > | > |And otherwise 1.9 still uses the 1.8 lexical scoping semantics, yes? > > Yes, other local variables are local to innermost surrounding block. > At least until I make a big decision. I really like this approach. What's the downside to this choice? James Edward Gray II
on 10.01.2007 16:06
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Wed, 10 Jan 2007 23:47:43 +0900, James Edward Gray II
<james@grayproductions.net> writes:
|> |And otherwise 1.9 still uses the 1.8 lexical scoping semantics, yes?
|>
|> Yes, other local variables are local to innermost surrounding block.
|> At least until I make a big decision.
|
|I really like this approach. What's the downside to this choice?
I sometimes want to take out values from the block and I hate to be
forced to assign only for "variable declaration", for example
ary.each {|x|
if cond(x)
val = func(x)
break
end
}
p val # val is out-of-scope
matz.
on 11.01.2007 09:52
On Wednesday 10 January 2007 16:04, Yukihiro Matsumoto wrote: > > matz. Well, out of my experience with other programming languages (and having experimented with building a compiler myself), I was always expecting that I have to declare a variable in the scope I want to use it in. I always would have prefixed your example with "val = nil" since that's how scoping works in almost all languages I know (with the lone exception of AWK ;-). And I think it would be dangerous if val would leak into the outer scope of your example. Although I understand that it's inconvenient to be forced to declare val in the outer scope first :-) Marc -- Marc Haisenko Comdasys AG Rüdesheimer Straße 7 D-80686 München Tel: +49 (0)89 - 548 43 33 21 Fax: +49 (0)89 - 548 43 33 29 e-mail: haisenko@comdasys.com http://www.comdasys.com
on 11.01.2007 10:13
Hi, > |> For your information, Ruby2 has explicit scoping in blocks. > |> > |> lambda {|a,b; v1, v2| ...} > |> > |> Variables a, b (parameters), v1 and v2 are local to the lambda block. > | > |And otherwise 1.9 still uses the 1.8 lexical scoping semantics, yes? > > Yes, other local variables are local to innermost surrounding block. > At least until I make a big decision. Why don't we let "Darwin" decide this? Here's my idea: - create another Kernel level method, called "scope", which created a Proc descendent (to keep backwards compatibility), and accepts a first parameter for the binding object (a la eval). The new scope method might accept the parameters you propose, as well. Ah, and the local variables declared in it remain local, unless it has a binding object to which it would bind the local variables. class Scope < Proc end Examples: a) scope {|a,b; v1, v2| ...} b) scope {|v1, v2| n = 10 } p n #error. unknown n c) scope(binding) {|v1, v2| n = 10 } p n #prints 10 Then backwards compatibility could be kept. Anyway, I don't know everything that has been discussed about this subject already, but I just needed to update some of my libraries because of probable scoping issues, and the sooner a fix to this appears, the better. :-) Because I still have a lot of library code that uses "anonymous functions" and that might possibly have some kind of issue. I still have more conversions ahead to protect code against "heisenbugs" caused by this. That's an idea to try to avoid the "bikeshed talks". hehe. :-) Cheers, Joao
on 19.01.2007 16:29
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Tue, 9 Jan 2007 15:19:10 +0900, Evan Phoenix
<evan@fallingsnow.net> writes:
|I agree they need work. Why not go back to the rubyconf 2005
|proposal? I believe it was to allow new vars created in a block to be
|normal local variables (not dvars). I've discussed the expected
|behavior of local variables in ruby to new users and this is what
|they expect.
Evan, I have considered your words for these days, and you gave me an
inspiration. I think I get an idea. Thank you. Stay tuned.
matz.
on 19.01.2007 16:30
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Thu, 11 Jan 2007 18:12:10 +0900, "Joao Pedrosa"
<joaopedrosa@gmail.com> writes:
|Here's my idea:
|- create another Kernel level method, called "scope", which created a Proc
|descendent (to keep backwards compatibility), and accepts a first parameter
|for the binding object (a la eval). The new scope method might accept the
|parameters you propose, as well. Ah, and the local variables declared in it
|remain local, unless it has a binding object to which it would bind
|the local variables.
|
|class Scope < Proc
|end
|
|Examples:
|
|a)
|scope {|a,b; v1, v2| ...}
|
|b)
|scope {|v1, v2| n = 10 }
|p n #error. unknown n
|
|c)
|scope(binding) {|v1, v2| n = 10 }
|p n #prints 10
|
|Then backwards compatibility could be kept.
Unfortunately, local variables scope are determined in compile-time,
so that run-time feature like scope you've proposed is too late to
modify local variable behavior.
|That's an idea to try to avoid the "bikeshed talks". hehe. :-)
Unlike FreeBSD people, I _love_ bikeshed talks. ;-)
matz.
on 19.01.2007 16:30
Yukihiro Matsumoto wrote: > > Evan, I have considered your words for these days, and you gave me an > inspiration. I think I get an idea. Thank you. Stay tuned. Just for the record, most folks I've polled expect variables to work the other way, where variables referenced only inner scopes aren't visible to outer scopes. But I mostly polled the folks I deal with every day...programmers with many years of experience in lexically-scoped languages. There's also no performance-related reason to flatten scope; JRuby's interpreter and compiler do not have any additional overhead for variables in different scopes. I believe there are enough down sides to having a flat scope that the few benefits would be greatly outweighed.
on 19.01.2007 16:30
Hi,
In message "Re: [ ruby-Bugs-7680 ] a block argument within a block which
argument has the same name leaks"
on Sat, 13 Jan 2007 10:44:49 +0900, Charles Oliver Nutter
<charles.nutter@sun.com> writes:
|Just for the record, most folks I've polled expect variables to work the
|other way, where variables referenced only inner scopes aren't visible
|to outer scopes. But I mostly polled the folks I deal with every
|day...programmers with many years of experience in lexically-scoped
|languages.
People would not have any problem with nested scopes for languages
with some kind of explicit variable declarations. But Ruby's variable
declaration (via mere assignment) does not appear like declaration (on
purpose of course), so that it is difficult to see the scope of a
variable at a glance.
|There's also no performance-related reason to flatten scope; JRuby's
|interpreter and compiler do not have any additional overhead for
|variables in different scopes.
Neither YARV, if I recall correctly.
|I believe there are enough down sides to having a flat scope that the
|few benefits would be greatly outweighed.
I am not going to remove block local variables. Removing them would
ruin programming with the closure etc.
matz.
on 19.01.2007 16:30
On Jan 12, 2007, at 4:38 PM, Yukihiro Matsumoto wrote: > |behavior of local variables in ruby to new users and this is what > |they expect. > > Evan, I have considered your words for these days, and you gave me an > inspiration. I think I get an idea. Thank you. Stay tuned. I eagerly await to here to hear what idea you have. The behavior I've described is the behavior that rubinius currently has, btw. - Evan
on 19.01.2007 16:30
Yukihiro Matsumoto <matz@ruby-lang.org> writes: > Unlike FreeBSD people, I _love_ bikeshed talks. ;-) > > matz. Incidentally, I just read your presentation and was very happy to see that you "get" what a bikeshed is. Too many people use it to mean something like "it's not an important issue, so go away and let your superiors (me) decide". The moral of the original story is only that it is sometimes easier to get approval for the design of a complex system (nuclear power plant) than a simple system (bikeshed), because more people understand the simple system so more people have an opinion. It's just a fact of life, not an infestation. Even if the common usage is appropriate for an OS kernel--where almost all users just want their device to work and never interact directly with the interface--it's not appropriate for programming language design where all users interact directly with the interface. In fact, the amount of "bikeshediness" a programming language feature has is probably proportional to the amount the feature is or will be used! Steve
on 25.09.2007 22:31
Hi, > |p n #error. unknown n > | > |c) > |scope(binding) {|v1, v2| n = 10 } > |p n #prints 10 > | > |Then backwards compatibility could be kept. > > Unfortunately, local variables scope are determined in compile-time, > so that run-time feature like scope you've proposed is too late to > modify local variable behavior. That's right. I anxiously submitted the email just so I could get the idea off of my chest. :-) The examples weren't complete, as the code blocks would need to be run at least once as you hint. > |That's an idea to try to avoid the "bikeshed talks". hehe. :-) > > Unlike FreeBSD people, I _love_ bikeshed talks. ;-) Just to let you even more at easy, my changes to remove some "dangerous anonymous functions" actually helped me to clear up some of my code, because I was able to use the underlying Module which hosted the anonymous functions as the holder of them, just as I was doing with a couple of Hashes before. Actually I still use some anonymous functions now in this same code/library, but they are a little bit safer as they are very targeted, small, and in a common library. The bigger and more dangerous functions have been taken care of for about 8 or so of my libraries. I still need to make the conversion in two more, though. They all follow the same standard/framework. :-) That is, I am not in a hurry anymore and things have been sorted out in my end. I hope you will be able to sort them in your own now. hehe. :-) With safer (local scope) anonymous functions, programmability will be even better soon. I'm looking forward to it. :-) Cheers, Joao
on 25.09.2007 22:38
Hi, (Replying to myself) > That is, I am not in a hurry anymore and things have been sorted out > in my end. I hope you will be able to sort them in your own now. hehe. :-) > With safer (local scope) anonymous functions, programmability will be even > better soon. I'm looking forward to it. :-) Just as I had foreseeing in my first email in this thread, I didn't know the real scope of the problem as much as you do. I am sorry Matz and all for having wasted your time, because I misunderstood the issue. Ruby is fine. The bug I was experiencing was probably unrelated to my use of "anonymous functions", but it had me scared for a while. It was not a "heisenbug". It was a Joaobug. Sorry. I just tested the scope of the functions and it's fine, work as expected for my use of it at least. Cheers, Joao