Thread from comp.lang.tcl (4 replies)

How to pass an object from inside its own method to a helper function
Posted by Mark Summerfield <mark@qtrac.eu> 2 months 3 weeks ago

I want to pass an object from inside its own method to a helper function. 
(I'd also like to know how to pass a bound method.)

In the example below I have tried using [self] and [self object] and [self 
namespace] but none of them works.

#!/usr/bin/env wish9
tk appname "Test App"
proc make_file_menu {app} {
    .menu.file add command -command {$app on_quit} -label Quit \
            -underline 0 -accelerator Ctrl+Q
}
oo::class create App {
    constructor {} {
        wm withdraw .
        wm title . [tk appname]
        grid [ttk::button .quitButton -text Quit -underline 0 \
              -command [callback on_quit]]
        bind . <Escape> [callback on_quit]
        bind . <Alt-q> [callback on_quit]
        menu .menu
        menu .menu.file
        .menu add cascade -menu .menu.file -label File -underline 0
        make_file_menu [self] ;# BUG what do I pass here as "this"
        . configure -menu .menu
    }
    method on_quit {} {destroy .}
    method show {} {
        wm deiconify .
        raise .
    }
}
set application [App new]
$application show

The error I get is:

can't read "app": no such variable
    while executing
"$app on_quit"
    invoked from within
".#menu.#menu#file invoke active"
    ("uplevel" body line 1)
    invoked from within
"uplevel #0 [list $w invoke active]"
    (procedure "tk::MenuInvoke" line 49)
    invoked from within
"tk::MenuInvoke .#menu.#menu#file 1"
    (command bound to event)

Click on article to view all threads in comp.lang.tcl
Re: How to pass an object from inside its own method to a helper function
Posted by Mark Summerfield <mark@qtrac.eu> 2 months 3 weeks ago

I worked out how to do it:

proc make_file_menu {app} {
    .menu.file add command -command [list ${app}::my on_quit] \
       -label Quit -underline 0 -accelerator Ctrl+Q
}

For the caller I used:

make_file_menu [self]

Click on article to view all threads in comp.lang.tcl
Re: How to pass an object from inside its own method to a helper function
Posted by Schelte <nospam@wanadoo.nl> 2 months 3 weeks ago

On 11/07/2024 12:03, Mark Summerfield wrote:
> I worked out how to do it:
> 
> proc make_file_menu {app} {
>      .menu.file add command -command [list ${app}::my on_quit] \
>         -label Quit -underline 0 -accelerator Ctrl+Q
> }
> 
Or less hacky:

proc make_file_menu {app} {
     .menu.file add command -command [list $app on_quit] \
        -label Quit -underline 0 -accelerator Ctrl+Q
}

Originally you had $app inside curly braces, which prevented it from 
being substituted at definition time. At execution time, the app 
variable was out of scope.


Schelte.

Click on article to view all threads in comp.lang.tcl
Re: How to pass an object from inside its own method to a helper function
Posted by Mark Summerfield <mark@qtrac.eu> 2 months 3 weeks ago

On Thu, 11 Jul 2024 13:12:52 +0200, Schelte wrote:

[snip]
> Or less hacky:
> 
> proc make_file_menu {app} {
>      .menu.file add command -command [list $app on_quit] \
>         -label Quit -underline 0 -accelerator Ctrl+Q
> }
> 
> Originally you had $app inside curly braces, which prevented it from
> being substituted at definition time. At execution time, the app
> variable was out of scope.

Thank you, that works great.

Click on article to view all threads in comp.lang.tcl
Re: How to pass an object from inside its own method to a helper function
Posted by Ralf Fassel <ralfixx@gmx.de> 2 months 3 weeks ago

* Mark Summerfield <mark@qtrac.eu>
| On Thu, 11 Jul 2024 13:12:52 +0200, Schelte wrote:
| > proc make_file_menu {app} {
| >      .menu.file add command -command [list $app on_quit] \
| >         -label Quit -underline 0 -accelerator Ctrl+Q
| > }
| > 
| > Originally you had $app inside curly braces, which prevented it from
| > being substituted at definition time. At execution time, the app
| > variable was out of scope.
>
| Thank you, that works great.

To save you trouble on your TCL-road ahead, make sure you understand the
difference between

  -command {$app on_quit}

which you had originally in your code and

  -command [list $app on_quit]

which is the correct way of doing things and

  -command "$app on_quit"

which also most probably would "work" right now,
until some day it won't :-)... 

HTH
R'

Click on article to view all threads in comp.lang.tcl