Fredrik Jagenheim wrote:
> Hi,
>
> I tried using connect like this:
>
> 8<
>
> j = 0
> 3.times { |i|
> FXButton.new(self, "Button#{j}").connect(SEL_COMMAND) {
> puts "#{j} pressed"
> }
> j += 1
> }
>
>
>>8
>
>
> This doesn't work as intended, but if I use the 'i' variable, it does.
> I figured it had to do with global/local scope, but I don't grok it
> fully.
As you guessed, it's not particularly an effect of #connect. It has to
do with the way ruby associates bindings with code blocks. Your code
generates three closures (closure=code+binding) of the block
{
puts "#{j} pressed"
}
and all three of them refer to the same j variable. The string isn't
interpolated until you execute the code. By the time the code executes
(when you press a button), the value of j is 3. So a "3" gets
interpolated in all three strings.
I didn't run the code (so I may be completely wrong ;) ), but I've been
bitten by this before.
Using just "i" instead of "j" is one way around, as you noticed. Another
way is to assign the value of j to a new local variable ("k", say)
inside the #times block, and use that in the string interpolation.
HTH.
|