开发者

Embedding tcl in ruby

Is there any way to do this? It seems the only possible way to do this is by using ruby/tk and creating a tcl interpreter through that api. However, I'd like to use this on 开发者_开发知识库a system with no GUI (x windows). Am I out of options?

Thanks


If you can invoke arbitrary simple functions in Tcl's C API, the key ones are:

  • Tcl_FindExecutable – Call this first to initialize the library
  • Tcl_CreateInterp – This returns a handle for a new execution context
  • Tcl_Eval – This evaluates a script; returns constants TCL_OK (0) or TCL_ERROR (1) (or a few others which are rare in general code)
  • Tcl_GetResult – This returns the result value (or error message)
  • Tcl_ResetResult – This clears the result value
  • Tcl_DeleteInterp – Maybe you can guess what this does…

You can also access "global" variables in the context with Tcl_GetVar and Tcl_SetVar; this is a very convenient way to pass in values that might not be valid scripts.


if you are on the command line you can shell out to tclsh. tcl also has a C api so you should be able to use this to embed tcl in ruby if there is no preexisting way?


Q. Embedding tcl in ruby[.] Is there any way to do this?

I came across this post by Matz himself in 2005, from a thread called, "Run TCL in ruby".

His example program (from the post) evaluates strings of Tcl code from Ruby without shelling out:

require 'tcltklib'

def test
  ip1 = TclTkIp.new

  puts ip1._eval('button .lab -text exit -command "destroy ."').inspect
  puts ip1._eval('pack .lab').inspect

  puts ip1._eval(%q+puts [ruby {print "print by ruby\n"; 'puts by tcl/tk'}]+).inspect

  TclTkLib.mainloop
end

test

Its console output is:

".lab"
""
print by ruby
puts by tcl/tk
""

Quoting from his post:

The tcltklib extension, which comes with the standard distribution, invokes Tcl interpreter directly without any inter-process communication.

To make it work, I needed to duplicate the following directories:

  1. /c/Ruby/lib/tcltk/tcl8.5 as /c/Ruby/lib/tcl8.5
  2. /c/Ruby/lib/tcltk/tk8.5 as /c/Ruby/lib/tk8.5

(Possibly, your Ruby is installed somewhere else.)

Q. I'd like to use this on a system with no GUI (x windows).

In a reply post immediately below Matz's, Hidetoshi Nagai says:

If no need for Tk, an IP without Tk can be created. To do that, please call TclTkIp.new(nil, false).

So here is Matz's program, altered to run without a Tk graphics window:

require 'tcltklib'

def test
# nil, false means without Tk:
  ip1 = TclTkIp.new nil, false

  puts ip1._eval('list { aa bb cc }').inspect

  puts ip1._eval('set list { aa bb cc }; join $list ""').inspect

  TclTkLib.mainloop
end

test

Its console output is:

"{ aa bb cc }"
"aabbcc"

These two programs worked for me, using Ruby 2.2.5 (with Tk 8.5.12) on Windows 7.

For what it's worth, here is the manual for tcltklib.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜