From 7814a68ac62ebfbbe2e025a473ff64ec9a5641b5 Mon Sep 17 00:00:00 2001 From: nagai Date: Mon, 31 Jan 2005 04:34:35 +0000 Subject: * ext/tcltklib/tcltklib.c: add invalid namespace check * ext/tk/lib/multi-tk.rb: add invalid_namespace? method * ext/tk/lib/remote-tk.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@7853 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/tcltklib/sample/sample2.rb | 12 +-- ext/tcltklib/tcltklib.c | 171 ++++++++++++++++++++++++++--------------- ext/tk/README.1st | 31 ++++---- ext/tk/lib/multi-tk.rb | 8 +- ext/tk/lib/remote-tk.rb | 2 +- ext/tk/lib/tk.rb | 2 +- 6 files changed, 136 insertions(+), 90 deletions(-) (limited to 'ext') diff --git a/ext/tcltklib/sample/sample2.rb b/ext/tcltklib/sample/sample2.rb index 5d43470de3..444bb1eef7 100644 --- a/ext/tcltklib/sample/sample2.rb +++ b/ext/tcltklib/sample/sample2.rb @@ -19,7 +19,7 @@ require "tcltk" $ip = TclTkInterpreter.new() $root = $ip.rootwidget() $button, $canvas, $checkbutton, $frame, $label, $pack, $update, $wm = - $ip.commands().indexes( + $ip.commands().values_at( "button", "canvas", "checkbutton", "frame", "label", "pack", "update", "wm") class Othello @@ -196,10 +196,12 @@ class Othello def initialize(view, row, col) @view = view - @id = @view.e("create rectangle", *view.tk_rect(view.left + col, - view.top + row, - view.left + col + 1, - view.top + row + 1)) + @id = @view.e("create rectangle", + *(view.tk_rect(view.left + col, + view.top + row, + view.left + col + 1, + view.top + row + 1) \ + << "-fill #{BACK_GROUND_COLOR}") ) @row = row @col = col @view.e("itemconfigure", @id, diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c index c9a72ed4bd..fae8e3da3e 100644 --- a/ext/tcltklib/tcltklib.c +++ b/ext/tcltklib/tcltklib.c @@ -4,7 +4,7 @@ * Oct. 24, 1997 Y. Matsumoto */ -#define TCLTKLIB_RELEASE_DATE "2005-01-25" +#define TCLTKLIB_RELEASE_DATE "2005-01-28" #include "ruby.h" #include "rubysig.h" @@ -204,17 +204,35 @@ static int ip_ruby_eval _((ClientData, Tcl_Interp *, int, char **)); static int ip_ruby_cmd _((ClientData, Tcl_Interp *, int, char **)); #endif -static int ip_null_namespace _((Tcl_Interp *)); -#if TCL_MAJOR_VERSION >= 8 -#ifndef Tcl_GetCurrentNamespace +#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 5 +/* Tcl7.x doesn't have namespace support. */ +/* Tcl8.5+ has definition of Tcl_GetCurrentNamespace() in tclDecls.h */ +# ifndef Tcl_GetCurrentNamespace EXTERN Tcl_Namespace * Tcl_GetCurrentNamespace _((Tcl_Interp *)); -#endif +# endif +# if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) +# ifndef Tcl_GetCurrentNamespace +# ifndef FunctionNum_of_GetCurrentNamespace +# define FunctionNum_of_GetCurrentNamespace 124 +# endif +struct DummyTclIntStubs { + int magic; + struct TclIntStubHooks *hooks; + void (*func[FunctionNum_of_GetCurrentNamespace])(); + Tcl_Namespace * (*tcl_GetCurrentNamespace) _((Tcl_Interp *)); +}; +EXTERN struct TclIntStubs *tclIntStubsPtr; +#define Tcl_GetCurrentNamespace \ + (((struct DummyTclIntStubs *)tclIntStubsPtr)->tcl_GetCurrentNamespace) +# endif +# endif #endif /*---- class TclTkIp ----*/ struct tcltkip { Tcl_Interp *ip; /* the interpreter */ + Tcl_Namespace *default_ns; /* default namespace */ int has_orig_exit; /* has original 'exit' command ? */ Tcl_CmdInfo orig_exit_info; /* command info of original 'exit' command */ int ref_count; /* reference count of rbtk_preserve_ip call */ @@ -235,6 +253,25 @@ get_ip(self) return ptr; } + +/* namespace check */ +/* ip_null_namespace(Tcl_Interp *interp) */ +#if TCL_MAJOR_VERSION < 8 +#define ip_null_namespace(interp) (0) +#else /* support namespace */ +#define ip_null_namespace(interp) \ + (Tcl_GetCurrentNamespace(interp) == (Tcl_Namespace *)NULL) +#endif + +/* rbtk_invalid_namespace(tcltkip *ptr) */ +#if TCL_MAJOR_VERSION < 8 +#define rbtk_invalid_namespace(ptr) (0) +#else /* support namespace */ +#define rbtk_invalid_namespace(ptr) \ + ((ptr)->default_ns == (Tcl_Namespace*)NULL || Tcl_GetCurrentNamespace((ptr)->ip) != (ptr)->default_ns) +#endif + + /* increment/decrement reference count of tcltkip */ static int rbtk_preserve_ip(ptr) @@ -3333,18 +3370,19 @@ delete_slaves(ip) Tcl_Preserve(slave); - if (!Tcl_InterpDeleted(slave) && !ip_null_namespace(slave)) { - if (Tcl_Eval(slave, DEF_CANCEL_AFTER_SCRIPTS_PROC) == TCL_OK) { - if (Tcl_GetCommandInfo(slave, CANCEL_AFTER_SCRIPTS, &info)) { - DUMP2("call cancel after scripts proc '%s'", - CANCEL_AFTER_SCRIPTS); - Tcl_Eval(slave, CANCEL_AFTER_SCRIPTS); - } - } + if (!Tcl_InterpDeleted(slave) && !ip_null_namespace(slave) && + Tcl_GetCommandInfo(slave, finalize_hook_name, &info)) { + DUMP2("call finalize hook proc '%s'", finalize_hook_name); + Tcl_Eval(slave, finalize_hook_name); + } - if (Tcl_GetCommandInfo(slave, finalize_hook_name, &info)) { - DUMP2("call finalize hook proc '%s'", finalize_hook_name); - Tcl_Eval(slave, finalize_hook_name); + if (!Tcl_InterpDeleted(slave) && + Tcl_Eval(slave, DEF_CANCEL_AFTER_SCRIPTS_PROC) == TCL_OK) { + if (!Tcl_InterpDeleted(slave) && !ip_null_namespace(slave) && + Tcl_GetCommandInfo(slave, CANCEL_AFTER_SCRIPTS, &info)) { + DUMP2("call cancel after scripts proc '%s'", + CANCEL_AFTER_SCRIPTS); + Tcl_Eval(slave, CANCEL_AFTER_SCRIPTS); } } @@ -3355,7 +3393,7 @@ delete_slaves(ip) del_root(slave); /* while(!rbtk_InterpDeleted(slave)) { */ if (!Tcl_InterpDeleted(slave)) { - DUMP1("wait ip is deleted"); + DUMP2("delete slave ip(%lx)", slave); Tcl_DeleteInterp(slave); } @@ -3376,6 +3414,7 @@ ip_free(ptr) { Tcl_CmdInfo info; int thr_crit_bup; + char* argv[2]; DUMP2("free Tcl Interp %lx", ptr->ip); if (ptr) { @@ -3384,7 +3423,7 @@ ip_free(ptr) DUMP2("IP ref_count = %d", ptr->ref_count); - if (!Tcl_InterpDeleted(ptr->ip) && !ip_null_namespace(ptr->ip)) { + if (!Tcl_InterpDeleted(ptr->ip) && !rbtk_invalid_namespace(ptr)) { DUMP2("IP(%lx) is not deleted", ptr->ip); /* Tcl_Preserve(ptr->ip); */ rbtk_preserve_ip(ptr); @@ -3393,25 +3432,28 @@ ip_free(ptr) Tcl_ResetResult(ptr->ip); - if (Tcl_Eval(ptr->ip, DEF_CANCEL_AFTER_SCRIPTS_PROC) == TCL_OK) { - if (Tcl_GetCommandInfo(ptr->ip, CANCEL_AFTER_SCRIPTS, &info)) { + if (!Tcl_InterpDeleted(ptr->ip) && !rbtk_invalid_namespace(ptr) + && Tcl_GetCommandInfo(ptr->ip, finalize_hook_name, &info)) { + DUMP2("call finalize hook proc '%s'", finalize_hook_name); + Tcl_Eval(ptr->ip, finalize_hook_name); + } + + if (!Tcl_InterpDeleted(ptr->ip) && !rbtk_invalid_namespace(ptr) + && Tcl_Eval(ptr->ip, DEF_CANCEL_AFTER_SCRIPTS_PROC) == TCL_OK) { + if (!Tcl_InterpDeleted(ptr->ip) && !rbtk_invalid_namespace(ptr) + && Tcl_GetCommandInfo(ptr->ip, CANCEL_AFTER_SCRIPTS, &info)) { DUMP2("call cancel after scripts proc '%s'", CANCEL_AFTER_SCRIPTS); Tcl_Eval(ptr->ip, CANCEL_AFTER_SCRIPTS); } } - if (Tcl_GetCommandInfo(ptr->ip, finalize_hook_name, &info)) { - DUMP2("call finalize hook proc '%s'", finalize_hook_name); - Tcl_Eval(ptr->ip, finalize_hook_name); - } - /* del_root(ptr->ip); */ DUMP1("delete interp"); /* while(!rbtk_InterpDeleted(ptr->ip)) { */ if (!Tcl_InterpDeleted(ptr->ip)) { - DUMP1("wait ip is deleted"); + DUMP2("delete ip(%lx)", ptr->ip); Tcl_DeleteInterp(ptr->ip); } @@ -3470,6 +3512,14 @@ ip_init(argc, argv, self) rb_raise(rb_eRuntimeError, "fail to create a new Tk interpreter"); } +#if TCL_MAJOR_VERSION >= 8 + DUMP1("get current namespace"); + if ((ptr->default_ns = Tcl_GetCurrentNamespace(ptr->ip)) + == (Tcl_Namespace*)NULL) { + rb_raise(rb_eRuntimeError, "a new Tk interpreter has a NULL namespace"); + } +#endif + rbtk_preserve_ip(ptr); DUMP2("IP ref_count = %d", ptr->ref_count); current_interp = ptr->ip; @@ -3711,6 +3761,9 @@ ip_create_slave(argc, argv, self) rb_thread_critical = thr_crit_bup; rb_raise(rb_eRuntimeError, "fail to create the new slave interpreter"); } +#if TCL_MAJOR_VERSION >= 8 + slave->default_ns = Tcl_GetCurrentNamespace(slave->ip); +#endif rbtk_preserve_ip(slave); slave->has_orig_exit @@ -3878,25 +3931,28 @@ ip_delete(self) delete_slaves(ptr->ip); DUMP1("finalize operation"); - if (Tcl_Eval(ptr->ip, DEF_CANCEL_AFTER_SCRIPTS_PROC) == TCL_OK) { - if (Tcl_GetCommandInfo(ptr->ip, CANCEL_AFTER_SCRIPTS, &info)) { + if (!Tcl_InterpDeleted(ptr->ip) && !rbtk_invalid_namespace(ptr) + && Tcl_GetCommandInfo(ptr->ip, finalize_hook_name, &info)) { + DUMP2("call finalize hook proc '%s'", finalize_hook_name); + Tcl_Eval(ptr->ip, finalize_hook_name); + } + + if (!Tcl_InterpDeleted(ptr->ip) && !rbtk_invalid_namespace(ptr) + && Tcl_Eval(ptr->ip, DEF_CANCEL_AFTER_SCRIPTS_PROC) == TCL_OK) { + if (!Tcl_InterpDeleted(ptr->ip) && !rbtk_invalid_namespace(ptr) + && Tcl_GetCommandInfo(ptr->ip, CANCEL_AFTER_SCRIPTS, &info)) { DUMP2("call cancel after scripts proc '%s'", CANCEL_AFTER_SCRIPTS); Tcl_Eval(ptr->ip, CANCEL_AFTER_SCRIPTS); } } - if (Tcl_GetCommandInfo(ptr->ip, finalize_hook_name, &info)) { - DUMP2("call finalize hook proc '%s'", finalize_hook_name); - Tcl_Eval(ptr->ip, finalize_hook_name); - } - del_root(ptr->ip); DUMP1("delete interp"); /* while(!rbtk_InterpDeleted(ptr->ip)) { */ if (!Tcl_InterpDeleted(ptr->ip)) { - DUMP1("wait ip is deleted"); + DUMP2("delete ip(%lx)", ptr->ip); Tcl_DeleteInterp(ptr->ip); } @@ -3907,24 +3963,13 @@ ip_delete(self) } /* is deleted? */ -static int -ip_null_namespace(interp) - Tcl_Interp *interp; -{ -#if TCL_MAJOR_VERSION < 8 - return 0; -#else /* support Namespace */ - return ( Tcl_GetCurrentNamespace(interp) == (Tcl_Namespace *)NULL ); -#endif -} - static VALUE -ip_has_null_namespace_p(self) +ip_has_invalid_namespace_p(self) VALUE self; { struct tcltkip *ptr = get_ip(self); - if (ip_null_namespace(ptr->ip)) { + if (rbtk_invalid_namespace(ptr)) { return Qtrue; } else { return Qfalse; @@ -3937,7 +3982,7 @@ ip_is_deleted_p(self) { struct tcltkip *ptr = get_ip(self); - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { return Qtrue; } else { return Qfalse; @@ -4053,7 +4098,7 @@ ip_eval_real(self, cmd_str, cmd_len) Tcl_IncrRefCount(cmd); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(cmd); rb_thread_critical = thr_crit_bup; @@ -4094,7 +4139,7 @@ ip_eval_real(self, cmd_str, cmd_len) DUMP2("Tcl_Eval(%s)", cmd_str); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); ptr->return_value = TCL_OK; return rb_tainted_str_new2(""); @@ -4299,7 +4344,7 @@ lib_restart(self) rb_secure(4); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); rb_raise(rb_eRuntimeError, "interpreter is deleted"); } @@ -4788,7 +4833,7 @@ ip_invoke_core(interp, argc, argv) ptr = get_ip(interp); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } @@ -5270,7 +5315,7 @@ ip_get_variable(self, varname_arg, flag_arg) Tcl_IncrRefCount(nameobj); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(nameobj); rb_thread_critical = thr_crit_bup; @@ -5334,7 +5379,7 @@ ip_get_variable(self, varname_arg, flag_arg) char *ret; /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } else { @@ -5406,7 +5451,7 @@ ip_get_variable2(self, varname_arg, index_arg, flag_arg) Tcl_IncrRefCount(idxobj); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(nameobj); Tcl_DecrRefCount(idxobj); @@ -5471,7 +5516,7 @@ ip_get_variable2(self, varname_arg, index_arg, flag_arg) char *ret; /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } else { @@ -5568,7 +5613,7 @@ ip_set_variable(self, varname_arg, value_arg, flag_arg) # endif /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(nameobj); Tcl_DecrRefCount(valobj); @@ -5635,7 +5680,7 @@ ip_set_variable(self, varname_arg, value_arg, flag_arg) CONST char *ret; /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } else { @@ -5732,7 +5777,7 @@ ip_set_variable2(self, varname_arg, index_arg, value_arg, flag_arg) Tcl_IncrRefCount(valobj); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(nameobj); Tcl_DecrRefCount(idxobj); @@ -5793,7 +5838,7 @@ ip_set_variable2(self, varname_arg, index_arg, value_arg, flag_arg) CONST char *ret; /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } else { @@ -5837,7 +5882,7 @@ ip_unset_variable(self, varname_arg, flag_arg) StringValue(varname); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); return Qtrue; } @@ -5879,7 +5924,7 @@ ip_unset_variable2(self, varname_arg, index_arg, flag_arg) StringValue(index); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || rbtk_invalid_namespace(ptr)) { DUMP1("ip is deleted"); return Qtrue; } @@ -6472,7 +6517,7 @@ Init_tcltklib() rb_define_method(ip, "allow_ruby_exit=", ip_allow_ruby_exit_set, 1); rb_define_method(ip, "delete", ip_delete, 0); rb_define_method(ip, "deleted?", ip_is_deleted_p, 0); - rb_define_method(ip, "null_namespace?", ip_has_null_namespace_p, 0); + rb_define_method(ip, "invalid_namespace?", ip_has_invalid_namespace_p, 0); rb_define_method(ip, "_eval", ip_eval, 1); rb_define_method(ip, "_toUTF8", ip_toUTF8, -1); rb_define_method(ip, "_fromUTF8", ip_fromUTF8, -1); diff --git a/ext/tk/README.1st b/ext/tk/README.1st index 038528e553..df6c819d26 100644 --- a/ext/tk/README.1st +++ b/ext/tk/README.1st @@ -1,23 +1,22 @@ -If you want to use Ruby/Tk (tk.rb and so on), you must have -tcltklib.so which is working collectry. If you fail to call -'require "tcltklib"', you may not have tcltklib.so. -( see also README files of tcltklib ) -Even if there is a tcltklib.so on your Ruby library directry, -it will not work without Tcl/Tk libraries (e.g. libtcl8.4.so) -on your environment. You must also check that your Tcl/Tk is -installed properly. +If you want to use Ruby/Tk (tk.rb and so on), you must have tcltklib.so +which is working correctly. If you fail to call 'require "tcltklib"', +you may not have tcltklib.so. When you have some troubles on compiling +tcltklib, please read README files on tcltklib. +Even if there is a tcltklib.so on your Ruby library directry, it will not +work without Tcl/Tk libraries (e.g. libtcl8.4.so) on your environment. +You must also check that your Tcl/Tk is installed properly. -------------------------------------------- ( the following is written in EUC-JP ) -Ruby/Tk (tk.rb など) を使いたい場合には,tcltklib.so が正しく -動いていなければなりません.もし require "tcltklib" に失敗する -ようなら,tcltklib.so が存在していないのかもしれません. -( tcltklib の README ファイルも見てください ) -たとえ Ruby のライブラリディレクトリに tcltklib.so が存在して -いたとしても,実行環境に Tcl/Tk ライブラリ (libtcl8.4.so など) -がなければ機能しません.Tcl/Tk が正しくインストールされているか -どうかもチェックしてください. +Ruby/Tk (tk.rb など) を使いたい場合には,tcltklib.so が正しく動いて +いなければなりません.もし 'require "tcltklib"' に失敗するようなら, +tcltklib.so がインストールされていないのかもしれません.tcltklib の +コンパイル時に何か問題が生じている場合は,tcltklib の README ファイル +を見てください. +たとえ Ruby のライブラリディレクトリに tcltklib.so が存在していたとして +も,実行環境に Tcl/Tk ライブラリ (libtcl8.4.so など) がなければ機能しま +せん.Tcl/Tk が正しくインストールされているかもチェックしてください. ========================================================== Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb index ef4868fdef..cfe4887c4e 100644 --- a/ext/tk/lib/multi-tk.rb +++ b/ext/tk/lib/multi-tk.rb @@ -1568,8 +1568,8 @@ class << MultiTkIp __getip.deleted? end - def null_namespace? - __getip.null_namespace? + def invalid_namespace? + __getip.invalid_namespace? end def abort(msg = nil) @@ -1894,8 +1894,8 @@ class MultiTkIp @interp.deleted? end - def null_namespace? - @interp.null_namespace? + def invalid_namespace? + @interp.invalid_namespace? end def abort(msg = nil) diff --git a/ext/tk/lib/remote-tk.rb b/ext/tk/lib/remote-tk.rb index a2f8a46d4e..04d86d4cdb 100644 --- a/ext/tk/lib/remote-tk.rb +++ b/ext/tk/lib/remote-tk.rb @@ -282,7 +282,7 @@ class RemoteTkIp end end - def null_namespace? + def invalid_namespace? false end diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index 7f734a0820..e7217ff975 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -3940,7 +3940,7 @@ end #Tk.freeze module Tk - RELEASE_DATE = '2005-01-25'.freeze + RELEASE_DATE = '2005-01-28'.freeze autoload :AUTO_PATH, 'tk/variable' autoload :TCL_PACKAGE_PATH, 'tk/variable' -- cgit v1.2.3