Working with super?

Folks:
The following doesn’t produce a visible scroll bar, but if I rewrite it
slighlty so that it calls TkListbox directly, it shows it. What am I doing
wrong here?

···

require 'tk’
class FontBox < TkListbox
def initialize(parent = nil, keys=nil)
@ff = TkFrame.new
super(@ff, keys) {|l|
TkScrollbar.new(@ff, ‘command’=>proc{|*args| l.yview *args}) {|s|
pack(‘side’=>‘right’, ‘fill’=>‘y’)
l.yscrollcommand(proc{|first,last| s.set(first,last)})
}
pack(‘side’=>‘right’, ‘fill’=>‘both’, ‘expand’=>‘yes’)
}
@ff.pack
TkFont.families.each{|fname|
self.insert(‘end’, fname.chomp)
}
end
end

fb = FontBox.new.pack
Tk.mainloop


The following does show the scroll bar

class FontBox < TkListbox
def initialize(parent = nil, keys=nil)
@ff = TkFrame.new

the difference is here /

@lb = TkListbox.new(@ff, keys) {|l|
TkScrollbar.new(@ff, ‘command’=>proc{|*args| l.yview *args}) {|s|
pack(‘side’=>‘right’, ‘fill’=>‘y’)
l.yscrollcommand(proc{|first,last| s.set(first,last)})
}
pack(‘side’=>‘right’, ‘fill’=>‘both’, ‘expand’=>‘yes’)
}
@ff.pack
class FontBox < TkListbox
def initialize(parent = nil, keys=nil)
@ff = TkFrame.new
@lb = TkListbox.new(@ff, keys) {|l|
TkScrollbar.new(@ff, ‘command’=>proc{|*args| l.yview *args}) {|s|
pack(‘side’=>‘right’, ‘fill’=>‘y’)
l.yscrollcommand(proc{|first,last| s.set(first,last)})
}
pack(‘side’=>‘right’, ‘fill’=>‘both’, ‘expand’=>‘yes’)
}
@ff.pack
TkFont.families.each{|fname|
@lb.insert(‘end’, fname.chomp)
}
end
end

fb = FontBox.new

Tk.mainloop end
end

fb = FontBox.new
Tk.mainloop

Thanks,
Alan Walkington

That’s peculiar, and I don’t have an answer for you, just a couple of
tangential observations:

I notice that although the listbox is getting packed, the pack options
(‘expand’ and ‘fill’) are ignored in both versions of the code. I
can’t see why that would be. Maybe it’s got something to do with
what’s in and out of scope in nested blocks … that’s just a guess,
though–I still don’t understand blocks very well.

Also, did you know you can do this?

@lb = TkListbox.new(@ff, keys) {
yscrollbar(TkScrollbar.new(@ff) {
pack(‘side’=>‘right’, ‘fill’=>‘y’)
})
pack(‘side’=>‘right’, ‘fill’=>‘both’, ‘expand’=>‘yes’)
}

Making this change doesn’t seem to affect whether the scroll bar gets
packed or not; the simplification might make it a little easier to
isolate the problem. That yscrollbar method comes from the Scrollable
module.

···

On Thu, Oct 31, 2002 at 09:58:56AM +0900, Alan (Ursus Major) wrote:

The following doesn’t produce a visible scroll bar, but if I rewrite it
slighlty so that it calls TkListbox directly, it shows it. What am I doing
wrong here?


Matt Gushee When a nation follows the Way,
Englewood, Colorado, USA Horses bear manure through
mgushee@havenrock.com its fields;
http://www.havenrock.com/ When a nation ignores the Way,
Horses bear soldiers through
its streets.

                        --Lao Tzu (Peter Merel, trans.)

Hi,

···

From: “Alan (Ursus Major)” ursus@walkington.org
Subject: working with super?
Date: Thu, 31 Oct 2002 09:58:56 +0900
Message-ID: p7%v9.104765$tu.1081659@news.easynews.com

The following doesn’t produce a visible scroll bar, but if I rewrite it
slighlty so that it calls TkListbox directly, it shows it. What am I doing
wrong here?

The super(@ff, keys) calls TkListbox#initialize method.
It does NOT call TkListbox#new method.
TkListbox#initialize method does not use the given block.
So, the block isn’t evaluated.

There are many solutions for the problem.
One of them is

require ‘tk’
class FontBox < TkListbox
def initialize(parent = nil, keys=nil)
@ff = TkFrame.new
super(@ff, keys)
@lbox = self
TkScrollbar.new(@ff, ‘command’=>proc{|*args| lbox.yview *args}) {|s|
pack(‘side’=>‘right’, ‘fill’=>‘y’)
lbox.yscrollcommand(proc{|first,last| s.set(first,last)})
}
pack(‘side’=>‘right’, ‘fill’=>‘both’, ‘expand’=>‘yes’)
@ff.pack
TkFont.families.each{|fname|
self.insert(‘end’, fname.chomp)
}
end
end

fb = FontBox.new.pack
Tk.mainloop

But, I think that it is better to use TkComposite module.
tkscrollbox.rb is a sample to use the module,
and it already installed on your ruby’s library directory. :slight_smile:
The result of the following script is similar to your script.


require ‘tkscrollbox’
fb = TkScrollbox.new.pack
TkFont.families.each{|fname| fb.insert(‘end’, fname.chomp)}
Tk.mainloop


Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)

nagai@ai.kyutech.ac.jp mentored in message
news:20021031132836S.nagai@ai.kyutech.ac.jp…

Hi,

The super(@ff, keys) calls TkListbox#initialize method.
It does NOT call TkListbox#new method.
TkListbox#initialize method does not use the given block.
So, the block isn’t evaluated.

It took me a /long/ time to realize that the block in the ‘super’ call was
being ignored. I never /did/ figure out why. Domo arigato, tomidachi! I
ended up with this snippet:

···

def initialize(parent = nil, keys = nil)
super(parent, keys)

if ya wanna scroll, baby, ya need a scroll’em

@sb = TkScrollbar.new(@frame, ‘command’=>proc{|*args| self.yview *args}){
pack(‘side’=>‘right’, ‘fill’=>‘y’)
}
self.yscrollcommand(proc{|first,last| @sb.set(first,last)})

TkFont.families.each{|fname|
self.insert(‘end’, fname.chomp)
}
end

But, I think that it is better to use TkComposite module.
tkscrollbox.rb is a sample to use the module,

Ah yes. I’m glad I didn’t know about that. This was a learning exercise in
using inheritance in Ruby, so if I had know about that, I would certainly
have cheated!


require ‘tkscrollbox’
fb = TkScrollbox.new.pack
TkFont.families.each{|fname| fb.insert(‘end’, fname.chomp)}
Tk.mainloop


Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
Thank you again,
Alan Walkington