While working on the end assignment of a tutorial I encountered a
problem that I have found multiple solutions to, but can not understand
why it will not work the way I initially tried to code it. The program
(3 instances of it, working method 1, working method 2, and non-working)
are attached.
this code had the same behavior in the following enviroments:
ruby 1.9.2p136 (2010-12-25 revision 30365) [i686-linux]
ruby 1.8.7 (2010-12-23 patchlevel 330) [i686-linux]
Tk::TK_PATCHLEVEL
=> “8.5.9”
snipits of code in question:
The non-working method with @image as an instance variable of the class
gave no error to traceback, but did not work.
Using a class variable of the class, method 2, worked, but seemed like a
poor coding practice to me. (I am trying to learn good ways not bad
ones)
assigning @image to the label after the Label.new method was complete
rather than during the execution of the .new method works as well. Again
this method seems to me to be a bad programing practice.
If anyone could explain to me how the scope for ruby::tk interface works
for this method, and why or how to fix this properly I would greatly
appreciate it.
A block given to “new” method of TkWindow class (and sub-class of
TkWindow) is evaluated by “instance_eval”. So, at internal of the
block, “self” denotes the created widget object.
Your “{image @image}” means “{self.image(@image)}” and the “self” is
the button widget (@button). @image is not a instance variable of the
button widget. It is the reason of why your script doesn’t work.
Your trouble depends on the scope of variables. So,
Ans 1: give a hash of widget options to “new” method. @button = Tk::Tile::Label.new($content, :image => @image,
…).grid(:column => @position, :row => 1, :sticky =>‘we’)
Ans 2: use local variables (not equal to names of wiget options)
img = @image @button = Tk::Tile::Label.new($content){image img; …}.grid(:column
=> @position, :row => 1, :sticky =>‘we’)
or “@button.image@image” or “@button.image = @image” or
“@button.configure(:image => @image, … )”.
Methods for widget options aren’t shown by Object#methods method.
“method_missing” method is used to implement those method.
If you want to get the list of supported widget options,
Please use “@button.current_configinfo.keys” or
“@button.configinfo.collect{|optinfo| optinfo[0]}”.
working method 2: @button = Tk::Tile::Label.new($content){image @@image}.grid(:column => @position, :row => 1, :sticky =>‘we’)
(snip)
Using a class variable of the class, method 2, worked, but seemed like a
poor coding practice to me. (I am trying to learn good ways not bad
ones)
In this case, you use a class variable as a global variable.
It is a wrong solution.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.