# Ruby/Tk: How to access surrounding class from Tk Callback?

**URL:** <https://www.ruby-forum.com/t/ruby-tk-how-to-access-surrounding-class-from-tk-callback/74132>\
**Category:** Ruby\
**Created:** [February 27, 2006, 1:19pm UTC](https://www.ruby-forum.com/t/ruby-tk-how-to-access-surrounding-class-from-tk-callback/74132 "2006-02-27T13:19:17Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 27, 2006, 1:19pm UTC](https://www.ruby-forum.com/t/ruby-tk-how-to-access-surrounding-class-from-tk-callback/74132/1 "2006-02-27T13:19:17Z")

</div>

Assume that I’m modelling a visible form, consisting of entry fields,  
buttons etc., as a class:

require ‘tk’  
class Form  
def initialize(…)  
@foo=1234  
…  
@root=TkRoot.new() { title “My Form” }  
action\_button=TkButton.new(@root) {  
text “Action!”  
command {  
# Do something with @root and @foo  
puts @root.foo # DOES NOT WORK  
}  
}  
action\_button.pack(“side” =\> “right”);  
end  
end

The problem is with the command routine inside the action\_button:  
Both @root and @foo are undefined here. Obviously, the class context  
is not present anymore inside this callback function.

How would one model this situation in Ruby? In C++ terms: How do  
I pass the ‘this’ pointer of my class into the command callback  
of the button?

In my case, I happen to have only one instance of the Form, so  
I could use a global variable, $form, to hold a reference to my  
Form object and access it via this global, but of course this  
solution would be ugly beyond imagination…

Kind regards,

Ronald

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 27, 2006, 4:16pm UTC](https://www.ruby-forum.com/t/ruby-tk-how-to-access-surrounding-class-from-tk-callback/74132/2 "2006-02-27T16:16:28Z")

</div>

From: removed\_email\_address@domain.invalid (Ronald F.)  
Subject: Ruby/Tk: How to access surrounding class from Tk Callback?  
Date: Mon, 27 Feb 2006 21:18:35 +0900  
Message-ID: [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> ```
> @root=TkRoot.new() { title "My Form" }
> action_button=TkButton.new(@root) { 
> text "Action!" 
> command {
> # Do something with @root and @foo
> puts @root.foo # DOES NOT WORK
> }
> }
> 
> ```

## It may be a FAQ. A block given to .new method is evaluated by .instance\_eval(). That is, in the block, ‘self’ is the widget object. So, @root in your button’s command is an instance variable of the button widget. To avoid it, you have to give attention to scope of variables. For example, ------\< example 1 \>------------------------------------------ def initialize(…) foo = @foo=1234 … root = @root = TkRoot.new() { title “My Form” } action\_button=TkButton.new(@root) { text “Action!” command { # use local variables puts foo # same as @foo puts root # same as @root } } action\_button.pack(“side” =\> “right”); end

## ------\< example 2 \>------------------------------------------ def initialize(…) @foo=1234 … @root = TkRoot.new() { title “My Form” } action\_button=TkButton.new(@root, :text=\>“Action!”, :command=\>proc{ puts @foo puts @root }) action\_button.pack(“side” =\> “right”); end

------\< example 3 \>------------------------------------------  
def initialize(…)  
@foo=1234  
…  
@root = TkRoot.new() { title “My Form” }  
cmd = proc{  
puts @foo  
puts @root  
}  
action\_button=TkButton.new(@root) {  
text “Action!”  
command cmd  
}  
action\_button.pack(“side” =\> “right”);  
end

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 1, 2006, 9:48am UTC](https://www.ruby-forum.com/t/ruby-tk-how-to-access-surrounding-class-from-tk-callback/74132/3 "2006-03-01T09:48:56Z")

</div>

Hidetoshi NAGAI wrote:

> It may be a FAQ.  
> Arigatou gozaimasu! But where can I find the FAQ? I was able to  
> locate one only in Japanese, and my Japanese is barely sufficient  
> to order some Yakitori, let alone reading such a FAQ… ☹

Aside from a FAQ, a Ruby/Tk reference manual might be handy. Right  
now I am “learning” Ruby/Tk by looking at examples I find on the  
net, and _guessing_ how they could work - not a very satisfying  
means to grasp a new language.

> A block given to .new method is  
> evaluated by .instance\_eval().  
> That is, in the block, ‘self’ is the widget object.  
> So, @root in your button’s command is an instance variable  
> of the button widget.

I understand.

> ```
> # use local variables
> puts foo # same as @foo
> puts root # same as @root
> }
> }
> action_button.pack("side" => "right");
> 
> ```
> 
> end

I amazed that this works, but I don’t know how. foo is a local  
variable inside initialize, isn’t it? So it should go out of scope  
as soon as initialize ends. How then can I refer to it from inside  
my action command?

> ```
> })
> action_button.pack("side" => "right");
> 
> ```
> 
> end

Here I have two questions: What is the meaning of the  
colon in front of “command”, and why can I access @root  
now from inside command, but not in my original code?

> ```
> text "Action!" 
> command cmd
> }
> action_button.pack("side" => "right");
> 
> ```
> 
> end

This looks clever too. From a design point of view, I like solution 2  
best, because it avoids the need for additional variables. Still would  
like to understand, _why_ it works.

Ronald

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 1, 2006, 10:38am UTC](https://www.ruby-forum.com/t/ruby-tk-how-to-access-surrounding-class-from-tk-callback/74132/4 "2006-03-01T10:38:53Z")

</div>

> > ```
> > })
> > action_button.pack("side" => "right");
> > 
> > ```
> > 
> > end
> 
> Here I have two questions: What is the meaning of the  
> colon in front of “command”, and why can I access @root  
> now from inside command, but not in my original code?

I think, I figured this out by myself: Instead of setting  
text and command in an initialization procedure for the button,  
you supply them as parameter (:command denotes the named parameter  
“command” - I had used only positional parameters before, so I  
was not aware of this possibility). Since the command procedure  
is defined inside the list of actual parameters to the TkButton  
constructor, they can access any variable within the scope of  
the initialize function body; in particular, they can access  
the member variables of the surrounding class.

Ronald

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 8, 2006, 3:39pm UTC](https://www.ruby-forum.com/t/ruby-tk-how-to-access-surrounding-class-from-tk-callback/74132/5 "2006-03-08T15:39:55Z")

</div>

From: removed\_email\_address@domain.invalid (Ronald F.)  
Subject: Re: Ruby/Tk: How to access surrounding class from Tk Callback?  
Date: Wed, 1 Mar 2006 17:48:37 +0900  
Message-ID: [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> Arigatou gozaimasu! But where can I find the FAQ?

If I am right, I’d wrote a same answer on this ML. 😉

> Aside from a FAQ, a Ruby/Tk reference manual might be handy. Right  
> now I am “learning” Ruby/Tk by looking at examples I find on the  
> net, and _guessing_ how they could work - not a very satisfying  
> means to grasp a new language.

I want to compose Ruby/Tk manuals/documents.  
But I don’t have enough time and collaborators to do that.  
And it is so hard for me to translate them to English,  
because I’m poor at English.

> > ------\< example 1 \>------------------------------------------  
> > (snip)  
> > I amazed that this works, but I don’t know how. foo is a local  
> > variable inside initialize, isn’t it? So it should go out of scope  
> > as soon as initialize ends. How then can I refer to it from inside  
> > my action command?

A Proc object keeps its binding.

> > ------\< example 2 \>------------------------------------------  
> > (snip)  
> > Here I have two questions: What is the meaning of the  
> > colon in front of “command”,

“:command” is a symbol.  
Current Ruby/Tk can accept a string or a symbol as a key of an option.

## FYI, a has of options is a little faster than method calls. For example,

## action\_button=TkButton.new(@root, :text=\>“Action!”,:command=\>cmd)

## this calls the Tk interpreter only once. But,

## action\_button=TkButton.new(@root) { # \<= 1 text “Action!” # \<= 2 command cmd # \<= 3 })

this calls Tk interpreter three times.

> ```
> and why can I access @root
> 
> ```
> 
> now from inside command, but not in my original code?

It depends on the difference of scope.  
In the block given to TkButton.new, ‘self’ is the button object.  
But the proc object is defined in the scope of ‘initialize’.

> > ------\< example 3 \>------------------------------------------  
> > (snip)  
> > This looks clever too. From a design point of view, I like solution 2  
> > best, because it avoids the need for additional variables. Still would  
> > like to understand, _why_ it works.

The answer is same as the one for \< example 1 \>.
