scope puzzle

L

Len Lawrence

My understanding of Ruby scoping rules must be deficient in some way
because after three years coding in Ruby and reading numerous books about
the language I still cannot fathom why the following code works but with
a seemingly innocuous change it fails to run as expected.

u = [ ]
v = [ ]
which = [ ]
@subtypes.each_key { |k| which << [@subtypes[k], k] }
which.sort!
n = @subtypes.length - 1
0.upto( n ) { |jay| v[jay] = lambda { @extra.value = @subtypes[which
[jay][1]] } }
0.upto( n ) do |i|
category = which[1]
u = TkButton.new( altbar ) do
text category
font Helvetica
relief 'flat'
background Panel
foreground 'orange'
highlightthickness 0
command v
pack 'side' => 'left', 'padx' => 1
end
end

This snippet adds four buttons to a Tk interface. Clicking any one of
them is supposed to change the value of an entry field elsewhere in the
gui via a TkVariable. The code works as shown but if jay is replaced by j
in the definition of the lambdas the value of the Tk variable sticks at
the last value of j, in this case 3; i.e. clicking any one of the
labelled buttons returns 3 always. j is used elsewhere but here it is
local to the 0 to n loop. What I suspect is that it is not a scope
problem at all but something to do with the implementation of Tk in Ruby.

??
 
R

Robert Klemme

My understanding of Ruby scoping rules must be deficient in some way
because after three years coding in Ruby and reading numerous books about
the language I still cannot fathom why the following code works but with
a seemingly innocuous change it fails to run as expected.

u = [ ]
v = [ ]
which = [ ]
@subtypes.each_key { |k| which<< [@subtypes[k], k] }
which.sort!
n = @subtypes.length - 1
0.upto( n ) { |jay| v[jay] = lambda { @extra.value = @subtypes[which
[jay][1]] } }
0.upto( n ) do |i|
category = which[1]
u = TkButton.new( altbar ) do
text category
font Helvetica
relief 'flat'
background Panel
foreground 'orange'
highlightthickness 0
command v
pack 'side' => 'left', 'padx' => 1
end
end

This snippet adds four buttons to a Tk interface. Clicking any one of
them is supposed to change the value of an entry field elsewhere in the
gui via a TkVariable. The code works as shown but if jay is replaced by j
in the definition of the lambdas the value of the Tk variable sticks at
the last value of j, in this case 3; i.e. clicking any one of the
labelled buttons returns 3 always. j is used elsewhere but here it is
local to the 0 to n loop. What I suspect is that it is not a scope
problem at all but something to do with the implementation of Tk in Ruby.


$ allruby x.rb
ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux]
before 0
0
1
2
3
4
after 4
ruby 1.9.2p290 (2011-07-09) [i686-linux]
before 0
0
1
2
3
4
after 0
$ cat -n x.rb
1
2 j = 0
3 puts "before #{j}"
4 5.times {|j| puts j}
5 puts "after #{j}"
6
$

Does this help?

Kind regards

robert
 
L

Len Lawrence

My understanding of Ruby scoping rules must be deficient in some way
snipped

$ allruby x.rb
ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux] before 0
snipped
after 4
ruby 1.9.2p290 (2011-07-09) [i686-linux] before 0
0
snipped
after 0
$ cat -n x.rb
1
2 j = 0
3 puts "before #{j}"
4 5.times {|j| puts j}
5 puts "after #{j}"
6
$

Does this help?

Kind regards

robert

Yes, and thanks for pointing that out. I have a 1.9 installation on one
of my laptops. Will run the code under that.

Thanks

Len
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top