• How to pass an object from inside its own method to a helper function

    From Mark Summerfield@21:1/5 to All on Thu Jul 11 09:44:07 2024
    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)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Summerfield@21:1/5 to All on Thu Jul 11 10:03:27 2024
    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]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Schelte@21:1/5 to Mark Summerfield on Thu Jul 11 13:12:52 2024
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Summerfield@21:1/5 to Schelte on Thu Jul 11 11:42:36 2024
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Thu Jul 11 14:55:53 2024
    * Mark Summerfield <[email protected]>
    | 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'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)