tcltklib and not init'ing tk

Discussion in 'Ruby' started by Aamer Akhter, Oct 1, 2003.

  1. Aamer Akhter

    Aamer Akhter Guest

    Hello,

    I'm using the tcltklib extension in ruby 1.8. It seems to be working
    well for my transition from tcl. There are a couple of stumbling
    blocks I'm running into:

    1) is there a way to _not_ start tk? When I create a new interpreter
    (let's say from a non X-fwded ssh session) it may cause a failure. I'm
    only interested in Tcl.

    2) Is there a japanese to english translation of
    ext/tcltklib/MANUAL.euc? Or can somebody point to a tool that I may
    use to do the translation? babelfish.altavista does not appear to
    work.

    3). Are there any examples of ruby methods being called from the tcl
    code running inside the interpreter?

    Thank-you,

    Aamer Akhter,
    cisco Systems
    Aamer Akhter, Oct 1, 2003
    #1
    1. Advertising

  2. On Oct 1, Aamer Akhter wrote:
    > Hello,
    >
    > I'm using the tcltklib extension in ruby 1.8. It seems to be working
    > well for my transition from tcl. There are a couple of stumbling
    > blocks I'm running into:
    >
    > 1) is there a way to _not_ start tk? When I create a new interpreter
    > (let's say from a non X-fwded ssh session) it may cause a failure. I'm
    > only interested in Tcl.


    This is a big pain for me as well. I would really like to have this fixed,
    as Ruby/Tcl interaction is important to me. But it hasn't been a big
    enough pain to try and hack around in the C code :) (yet)

    > 2) Is there a japanese to english translation of
    > ext/tcltklib/MANUAL.euc? Or can somebody point to a tool that I may
    > use to do the translation? babelfish.altavista does not appear to
    > work.


    I've done all of my work without any kind of documentation in English.
    There just doesn't seem to be that strong an interest in mixing Ruby and
    Tcl (we are some of the exceptions). The tcltklib extension was written
    for Ruby/Tk. Access to the Tcl interpreter through it is a side effect--a
    highly useful side effect for me and you, but nevertheless not really
    what was intended by the developers. So using the Tcl interpreter from
    Ruby, and vice versa, is probably not even well documented in Japanese
    (someone please correct me if I am wrong).

    > 3). Are there any examples of ruby methods being called from the tcl
    > code running inside the interpreter?


    This is how I do it:

    set somevar [ruby "some_method()"]

    You can put any ruby code as the argument to the 'ruby' proc. You _must_,
    however, make sure that the return value of the ruby code is a string, or
    things will crash.

    You likely will have to do some creative things to get the scope that you
    want--Tcl can only communicate directly with class or global variables.
    This means if you call out to Tcl from Ruby, you will not have access to
    instance or local variables. It makes perfect sense, but typically
    requires doing some non-rubyish things to get access to what you need in
    Tcl.

    --
    ---------------------------------------------- | --------------------------
    Brett Williams | (970) 288-0475
    Agilent Technologies |
    ---------------------------------------------- | --------------------------
    Brett H. Williams, Oct 1, 2003
    #2
    1. Advertising

  3. "Brett H. Williams" wrote:
    >
    > On Oct 1, Aamer Akhter wrote:

    [...]
    > > 2) Is there a japanese to english translation of
    > > ext/tcltklib/MANUAL.euc? Or can somebody point to a tool that I may
    > > use to do the translation? babelfish.altavista does not appear to
    > > work.


    I have some hungarian notes about its work... :)) Sorry. :-/

    > for Ruby/Tk. Access to the Tcl interpreter through it is a side effect--a
    > highly useful side effect for me and you, but nevertheless not really


    And me :)

    > > 3). Are there any examples of ruby methods being called from the tcl
    > > code running inside the interpreter?


    You can register ruby proc objects into tcl and use it. However, it is a
    bit though to understand.

    Actually, there is a ruby_fmt proc which is buggy, but it is extensively
    used by tcltklib. Here is a patch for 1.6.7, but I do not think that it
    has changed since then...

    --------------------------------------------------------------------
    --- tcltk.old.rb 2002-02-07 02:53:30.000000000 +0100
    +++ tcltk_jav.rb 2003-01-07 02:36:04.000000000 +0100
    @@ -93,9 +93,9 @@
    # ruby_fmt command format arguments by `format' and call `ruby'
    command
    # (notice ruby command receives only one argument)
    if $DEBUG
    - @ip._eval("proc ruby_fmt {fmt args} { puts \"ruby_fmt: $fmt
    $args\" ; ruby [format $fmt $args] }")
    + @ip._eval("proc ruby_fmt {fmt args} { puts \"ruby_fmt: $fmt
    $args\" ; set cmd [list ruby [format $fmt $args]] ; uplevel $cmd }")
    else
    - @ip._eval("proc ruby_fmt {fmt args} { ruby [format $fmt $args]
    }")
    + @ip._eval("proc ruby_fmt {fmt args} { set cmd [list ruby [format
    $fmt $args]] ; uplevel $cmd }")
    end

    # @ip._get_eval_string(*args): generate string to evaluate in tcl
    interpreter
    --------------------------------------------------------------------

    Here I post a testprog of mine, ask if you cannot figure out what is
    going on...

    --------------------------------------------------------------------
    require "tcltk"

    $DEBUG=1

    ip=TclTkInterpreter.new
    pr=proc { |*args|
    puts "args: #{args}"
    puts "valami"
    }
    # megoldás paraméterátadásra
    # cb.to_eval: {ruby_fmt {TclTk._callcallback("c_1", "%%s")} %s}
    cb=TclTkCallback.new(ip,pr,"%s")
    puts "cb to_eval: #{cb.to_eval}"

    # a [format] a %%s helyére %s-t, %s helyére pedig param1-et helyettesít,
    azaz:
    # ... -command {ruby_fmt {TclTk._callcallback("c_1", "%s")} param1}
    btn1=TclTkWidget.new(ip,".","button","-text valami","-command [format ",
    cb,"param1]")
    ip.pack(btn1)

    TclTk.mainloop
    --------------------------------------------------------------------
    Ferenc Engard, Oct 1, 2003
    #3
  4. On Oct 2, Aamer Akhter wrote:
    >
    > Nice to see a fellow industry member dealing with the same problem ;-)
    >
    > On 10/1/03 10:06 AM, in article
    > , "Brett H. Williams"
    > <> wrote:
    >
    > > On Oct 1, Aamer Akhter wrote:
    > >> Hello,
    > >>
    > >> I'm using the tcltklib extension in ruby 1.8. It seems to be working
    > >> well for my transition from tcl. There are a couple of stumbling
    > >> blocks I'm running into:
    > >>
    > >> 1) is there a way to _not_ start tk? When I create a new interpreter
    > >> (let's say from a non X-fwded ssh session) it may cause a failure. I'm
    > >> only interested in Tcl.

    > >
    > > This is a big pain for me as well. I would really like to have this fixed,
    > > as Ruby/Tcl interaction is important to me. But it hasn't been a big
    > > enough pain to try and hack around in the C code :) (yet)

    >
    > I'm more than willing to spend some time on this. But I'm new to ruby, and
    > to the tcl-C portions.
    >
    > It seems like the thing to do is be able to pass the desire for no tk in via
    > the new call:
    >
    > TclTkIp.new(notk => 1),
    >
    > It looks like tcltklib.c:ip_init() gets called. The current parameters wind
    > up being plugged into Tcl's argv0 and args. So, in keeping with the current
    > implementation perhaps something like:
    >
    > TclTkIp.new($argv0, $args, 1) would be "better"
    >
    > Where 1 represents the non-desire to load Tk.
    >
    > One would need to skip over when 1 is set.:
    >
    > /* from Tcl_AppInit() */
    > DUMP1("Tk_Init");
    > if (Tk_Init(ptr->ip) == TCL_ERROR) {
    > rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
    > }
    > DUMP1("Tcl_StaticPackage(\"Tk\")");
    > #if TCL_MAJOR_VERSION >= 8
    > Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init, Tk_SafeInit);
    > #else
    > Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init,
    > (Tcl_PackageInitProc *) NULL);
    > #endif


    This kind of approach has merit... however, in the current setup, simply
    doing:

    require 'tk'

    dies if the DISPLAY is not set. It seems a reorganization of how the
    tcltklib module is presented would be needed as well.

    Am I missing a better way to get access to the Tcl interpreter?

    > ;-) yeah. I already ran into that. I've been using the ruby_fmt proc that
    > tcltk creates on init. That's just a wrapper for calling the ruby tcl
    > command.


    I have not been using this, but perhaps I should. The way I've been doing
    it usually leads to naming differences and confusion, like:

    TclFuncs = <<-EOTCL
    proc foo {args} {
    ruby {bar('$args')}
    }
    EOTCL

    #TclFuncs is evaled into the tcl interpreter...

    def bar(args)
    ...
    end


    > > You likely will have to do some creative things to get the scope that you
    > > want--Tcl can only communicate directly with class or global variables.
    > > This means if you call out to Tcl from Ruby, you will not have access to
    > > instance or local variables. It makes perfect sense, but typically
    > > requires doing some non-rubyish things to get access to what you need in
    > > Tcl.

    >
    > I don't think the importance of the above has sunk in yet. Do you mean to
    > say that in a class, I won't be able to do something like:
    >
    > Ip._eval("puts #{var}")


    No, because #{var} will be interpolated before the call to Tcl's eval.

    What I mean is that the following will not work (note that TclUtils
    provides some wrapper functionality that ultimately results in a call to
    Tk.tk_call("eval", cmd)... I didn't know about _eval which is probably what
    I should be using):

    #tcl function defined as follows...
    proc some_proc {} {
    set somevar [ruby {do_something()}]
    }

    #and a ruby methods defined as...
    class SomeClass
    def do_something()
    ...
    return some_str
    end

    def some_instance_method()
    TclUtils.eval("some_proc")
    end
    end

    When you call some_instance_method(), and it runs the tcl proc 'some_proc',
    the Tcl interpreter is calling things at the basest level of Ruby scoping,
    so there will be no such method 'do_something' at that level.


    If this seemed obvious to you that such a thing wouldn't work, perhaps it
    is. But it is an ugliness you have to deal with when spanning the two
    worlds.

    I end up having a current_obj variable or something which can be gotten at
    with a class method at the Tcl level, i.e.:

    proc some_proc {} {
    set somevar [ruby {SomeClass.current_obj.do_something()}]
    }

    #and...
    class SomeClass
    def SomeClass.current_obj
    return @@current_obj
    end

    ...

    def some_instance_method()
    @@current_obj = self
    TclUtils.eval("some_proc")
    end
    end

    Ugly. Sinfully ugly. Luckily, I try to keep Ruby in control of most
    everything, and the Tcl is a configuration file, so I don't need to do this
    that often.

    --
    ---------------------------------------------- | --------------------------
    Brett Williams | (970) 288-0475
    Agilent Technologies |
    ---------------------------------------------- | --------------------------
    Brett H. Williams, Oct 1, 2003
    #4
  5. > I end up having a current_obj variable or something which can be gotten at
    > with a class method at the Tcl level, i.e.:
    >
    > proc some_proc {} {
    > set somevar [ruby {SomeClass.current_obj.do_something()}]
    > }
    >
    > #and...
    > class SomeClass
    > def SomeClass.current_obj
    > return @@current_obj
    > end
    >
    > ...
    >
    > def some_instance_method()
    > @@current_obj = self
    > TclUtils.eval("some_proc")
    > end
    > end
    >
    > Ugly. Sinfully ugly. Luckily, I try to keep Ruby in control of most
    > everything, and the Tcl is a configuration file, so I don't need to do this
    > that often.


    Or you can use the TclTkCallback class as I have shown in my previous
    post:

    class SomeClass
    ...
    def do_something
    ...
    return some_str
    end

    def some_instance_method()
    pr=proc {do_something}
    cb=TclTkCallback.new(ip,pr,"%s")
    $interpreter._eval(cb.to_eval) # or something to eval cb.eval in the
    tcl interpreter
    end
    end
    Ferenc Engard, Oct 2, 2003
    #5
  6. Hi,

    Maybe this reply mail is too late.
    # Sorry, but I was out on business trip.

    From: (Aamer Akhter)
    Subject: tcltklib and not init'ing tk
    Date: Wed, 1 Oct 2003 15:20:05 +0900
    Message-ID: <>
    > 1) is there a way to _not_ start tk? When I create a new interpreter
    > (let's say from a non X-fwded ssh session) it may cause a failure. I'm
    > only interested in Tcl.


    from ChangeLog of CVS Head,
    ----------------------------------------------
    Fri Aug 29 17:30:15 2003 Hidetoshi NAGAI <>
    (snip)
    * ext/tcltklib/tcltklib.c : can create a interpreter without Tk
    ----------------------------------------------
    Please create a Tcl interpreter by TclTkIp.new(ip_name, nil).
    'ip_name' is the name of the interpreter which is shown with
    'winfo interps' and so on.
    Usually, 2nd argument of TclTkIp.new method is given command
    line options of 'wish' (e.g. TclTkIp.new('FOO', '-geometry
    500x200 -use 0x2200009') ). But if given nil or false, the
    interpreter starts without Tk.

    Unfortunately, tk.rb doesn't work with the interpreter without
    initialized Tk library. Therefore you must call TclTkIp#invoke
    or TclTkIp#eval. If you want to wrap the control script using
    such methods by Ruby's classes or modules, please refer TkCore
    or TkComm moduless on tk.rb. They may help you.

    BTW, there is a known bug on tcltklib.c. It causes 'Segmentation
    Fault' when 'vwait' or 'tkwait' command is called on the other
    thread than 'mainloop' thread. Those commands call Tcl_DoOneEvent()
    function. And it conflicts with the eventloop control of tcltklib.c.
    I've been working on fixing the problem. I think I must implement
    the routines to replace 'vwait' and 'tkwait'.
    --
    Hidetoshi Nagai ()
    Hidetoshi NAGAI, Oct 4, 2003
    #6
  7. Aamer Akhter

    Aamer Akhter Guest

    Hidetoshi NAGAI <> wrote in message news:<>...
    > Hi,
    >
    > Maybe this reply mail is too late.
    > # Sorry, but I was out on business trip.


    Hidetoshi,

    Thank-you for responding. It seems like these changes were in r1.39 of
    tcltklib.c, while 1.38 was the version released with with 1.8.0. I
    should have checked the CVS.

    > > 1) is there a way to _not_ start tk? When I create a new interpreter
    > > (let's say from a non X-fwded ssh session) it may cause a failure. I'm
    > > only interested in Tcl.

    >
    > from ChangeLog of CVS Head,
    > ----------------------------------------------
    > Fri Aug 29 17:30:15 2003 Hidetoshi NAGAI <>
    > (snip)
    > * ext/tcltklib/tcltklib.c : can create a interpreter without Tk
    > ----------------------------------------------
    > Please create a Tcl interpreter by TclTkIp.new(ip_name, nil).
    > 'ip_name' is the name of the interpreter which is shown with
    > 'winfo interps' and so on.
    > Usually, 2nd argument of TclTkIp.new method is given command
    > line options of 'wish' (e.g. TclTkIp.new('FOO', '-geometry
    > 500x200 -use 0x2200009') ). But if given nil or false, the
    > interpreter starts without Tk.


    I would suggest not using the argv parameter space for indicating the
    non-desire for Tk. One might one to pass command line arguments to
    tclsh ( in the same way as to wish)

    >
    > Unfortunately, tk.rb doesn't work with the interpreter without
    > initialized Tk library. Therefore you must call TclTkIp#invoke
    > or TclTkIp#eval. If you want to wrap the control script using
    > such methods by Ruby's classes or modules, please refer TkCore
    > or TkComm moduless on tk.rb. They may help you.
    >
    > BTW, there is a known bug on tcltklib.c. It causes 'Segmentation
    > Fault' when 'vwait' or 'tkwait' command is called on the other
    > thread than 'mainloop' thread. Those commands call Tcl_DoOneEvent()
    > function. And it conflicts with the eventloop control of tcltklib.c.
    > I've been working on fixing the problem. I think I must implement
    > the routines to replace 'vwait' and 'tkwait'.


    While I'm not an active user of vwait, tkwait and espically not
    threads as they're not supported in tcl-expect, I think the TKinter
    python library has worked around these type of issues see:

    Modules/_tkinter.c in the regular python distribution


    I would like to work with yon on improving the transferability of
    lists and arrays between tcl and ruby, if you are interisted.
    Aamer Akhter, Oct 4, 2003
    #7
  8. Hi,

    # I resend the following message, because I had no delivery of it.
    # I'm sorry, if you saw it twice.

    From: (Aamer Akhter)
    Subject: Re: tcltklib and not init'ing tk
    Date: Sun, 5 Oct 2003 06:56:12 +0900
    Message-ID: <>
    > I would suggest not using the argv parameter space for indicating the
    > non-desire for Tk. One might one to pass command line arguments to
    > tclsh ( in the same way as to wish)


    Hmm... I don't think so. Because, command line options ( except
    display options for wish ) can be given by Ruby.
    For example, when want to evaluate the following script on Ruby/Tcl,
    ---<foo.tcl>----------------
    puts "argc = $argc"
    puts "argv = $argv"
    puts "argv0 = $argv0"
    ----------------------------
    the following can simulate 'tclsh foo.tcl 1 2 3'.
    ----------------------------
    require 'tcltklib'
    ip = TclTkIp.new('foo.tcl', nil)
    ip._eval('set argc 3')
    ip._eval('set argv {1 2 3}')
    ip._eval('source foo.tcl')
    ----------------------------

    > > BTW, there is a known bug on tcltklib.c. It causes 'Segmentation
    > > Fault' when 'vwait' or 'tkwait' command is called on the other
    > > thread than 'mainloop' thread. Those commands call Tcl_DoOneEvent()
    > > function. And it conflicts with the eventloop control of tcltklib.c.
    > > I've been working on fixing the problem. I think I must implement
    > > the routines to replace 'vwait' and 'tkwait'.

    > While I'm not an active user of vwait, tkwait and espically not
    > threads as they're not supported in tcl-expect, I think the TKinter
    > python library has worked around these type of issues see:
    > Modules/_tkinter.c in the regular python distribution


    If you don't use threads, there is no problem (probably).
    The trouble depends on "thread switching".

    To avoid confliction of Tk operations between threads, the invoked
    command on the other thread than eventloop thread are serialized
    by adding into the event queue. And then, the invoking thread sleeps
    and waits for evaluation of the command. The event queue handler,
    which called on Tcl_DoOneEvent(), evaluates the command, and wakes
    the sleeping thread.

    Tcl's eventloop is the repeat of calling Tcl_DoOneEvent().
    Current Ruby/Tk uses its own eventloop for smooth switching of
    threads. But, as I wrote on the last mail, 'vwait' and 'tkwait'
    call Tcl_DoOneEvent() repeatedly. It is equal to situation where
    two eventloops are running on each thread. Therefore, the call stack
    of Tcl is broken by thread switching.

    > I would like to work with yon on improving the transferability of
    > lists and arrays between tcl and ruby, if you are interisted.


    Thank you for your proposal. Please tell me what is not enough on
    tk.rb (tcltk.rb is not maintained).
    --
    Hidetoshi NAGAI ()
    Hidetoshi NAGAI, Oct 8, 2003
    #8
  9. vwait and tkwait on Ruby/Tk (Re: tcltklib and not init'ing tk)

    Hi,

    From: Hidetoshi NAGAI <>
    Subject: Re: tcltklib and not init'ing tk
    Date: Sun, 5 Oct 2003 01:55:50 +0900
    Message-ID: <>
    > BTW, there is a known bug on tcltklib.c. It causes 'Segmentation
    > Fault' when 'vwait' or 'tkwait' command is called on the other
    > thread than 'mainloop' thread. Those commands call Tcl_DoOneEvent()
    > function. And it conflicts with the eventloop control of tcltklib.c.
    > I've been working on fixing the problem. I think I must implement
    > the routines to replace 'vwait' and 'tkwait'.


    I implemented them on the CVS. If you are interested in them,
    please try them.
    -----<ChangeLog>----------------------------
    Wed Oct 15 00:20:15 2003 Hidetoshi NAGAI <>

    * ext/tcltklib/tcltklib.c: replace Tcl/Tk's vwait and tkwait to
    switch on threads smoothly and avoid seg-fault.

    * ext/tcltklib/tcltklib.c: add TclTkIp._thread_vwait and
    _thread_tkwait for waiting on a thread. (Because Tcl/Tk's vwait
    and tkwait command wait on an eventloop.)

    * ext/tk/lib/multi-tk.rb: support TclTkIp._thread_vwait and
    _thread_tkwait.

    * ext/tk/lib/tk.rb: now, TkVariable#wait has 2 arguments.
    If 1st argument is true, waits on a thread. If false, waits on
    an eventloop. If 2nd argument is true, checks existence of
    rootwidgets. If false, doesn't. Default is wait(true, false).

    * ext/tk/lib/tk.rb: add TkVariable#tkwait(arg) which is equal to
    TkVariable#wait(arg, true). wait_visibility and wait_destroy
    have an argument for waiting on a thread or an eventloop.

    * ext/tk/lib/tk.rb: improve of accessing Tcl/Tk's special variables.

    * ext/tk/lib/tkafter.rb: support 'wait on a thread' and 'wait on
    an eventloop'.
    -------------------------------------------
    --
    Hidetoshi NAGAI ()
    Hidetoshi NAGAI, Oct 16, 2003
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tony Cheng
    Replies:
    1
    Views:
    8,205
    Juan T. Llibre
    Feb 24, 2006
  2. James D Carroll

    Init'ing fields

    James D Carroll, Jan 4, 2005, in forum: Java
    Replies:
    10
    Views:
    613
    Tom Dyess
    Jan 4, 2005
  3. Replies:
    1
    Views:
    656
    Jules
    Aug 18, 2005
  4. Jess
    Replies:
    4
    Views:
    438
  5. news.aon.at
    Replies:
    11
    Views:
    640
    Ian Collins
    Jan 29, 2011
Loading...

Share This Page