[#38782] [Bug:trunk] Re: [ruby-cvs:31281] Ruby:r24063 (trunk): * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

15 messages 2009/07/14
[#38784] Re: [Bug:trunk] Re: [ruby-cvs:31281] Ruby:r24063 (trunk): * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. — Hidetoshi NAGAI <nagai@...> 2009/07/14

永井@知能.九工大です.

[#38790] Re: [Bug:trunk] Re: [ruby-cvs:31281] Ruby:r24063 (trunk): * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. — "U.Nakamura" <usa@...> 2009/07/15

こんにちは、なかむら(う)です。

[#38791] Re: [Bug:trunk] Re: [ruby-cvs:31281] Ruby:r24063 (trunk): * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. — Hidetoshi NAGAI <nagai@...> 2009/07/15

永井@知能.九工大です.

[#38792] Re: [Bug:trunk] Re: [ruby-cvs:31281] Ruby:r24063 (trunk): * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. — "U.Nakamura" <usa@...> 2009/07/15

こんにちは、なかむら(う)です。

[#38793] Re: [Bug:trunk] Re: [ruby-cvs:31281] Ruby:r24063 (trunk): * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. — Hidetoshi NAGAI <nagai@...> 2009/07/15

永井@知能.九工大です.

[#38794] Re: [Bug:trunk] Re: [ruby-cvs:31281] Ruby:r24063 (trunk): * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. — "U.Nakamura" <usa@...> 2009/07/15

こんにちは、なかむら(う)です。

[#38843] 複素数リテラルについて — Yukihiro Matsumoto <matz@...>

まつもと ゆきひろです

32 messages 2009/07/21
[#38855] Re: 複素数リテラルについて — Yusuke ENDOH <mame@...> 2009/07/22

遠藤です。

[#38857] Re: 複素数リテラルについて — Tadayoshi Funaba <tadf@...> 2009/07/22

> は十分検討されたのでしょうか。積極的に反対なわけではないですが、

[#38912] String#valid_encoding?にオプションが欲しい — Fujioka <fuj@...>

xibbarこと藤岡です。(なぜか届かないので再送します)

19 messages 2009/07/27
[#38918] Re: String#valid_encoding?にオプションが欲しい — "NARUSE, Yui" <naruse@...> 2009/07/27

成瀬です。

[#38925] Re: String#valid_encoding?にオプションが欲しい — Fujioka <fuj@...> 2009/07/27

xibbarです。

[#38927] Re: String#valid_encoding?にオプションが欲しい — Fujioka <fuj@...> 2009/07/28

xibbarです。

[#38914] [Bug #1819] Ruby-1.9.1を使用しDB(MySQL)接続時にエラー — Ryouhei Saita 斉田 <redmine@...>

Bug #1819: Ruby-1.9.1を使用しDB(MySQL)接続時にエラー

11 messages 2009/07/27

[#38932] Enumerator#peek — Tanaka Akira <akr@...>

Enumerator#peek を新設するのはどうでしょうか。

16 messages 2009/07/28

[ruby-dev:38752] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合

From: Hidetoshi NAGAI <nagai@...>
Date: 2009-07-08 13:57:04 UTC
List: ruby-dev #38752
永井@知能.九工大です.

From: oshida@bb-next.net
Subject: [ruby-dev:38750] Re: [1.8.7][1.9.1][tk] 自前実装の拡張 widget を使いたい場合
Date: Wed, 8 Jul 2009 19:57:43 +0900
Message-ID: <1247050663.4a547ba7531f6@u1.div.rasch.jp>
> 押田です。

お世話になっております.

> さて本題です。
> Cygwin での結果です。
> 
> 1.8 は期待通りです。
> 
> 1.9 は残念ながら期待通りではありません。
> sample/tkcombobox.rb でも同様の挙動であったため、
> そちらの結果をお伝えします。
> 
> 1.9 では、ノッペラな窓が出るのみで固まってしまいます。
> タイトルバーの [X] ボタンでも終了しません。
> C-c すると下記が出てきます。
> 
> $ ruby ext/tk/sample/tkcombobox.rb
> /usr/local/lib/ruby/1.9.1/tk.rb:1363:in `_invoke': Interrupt
>         from /usr/local/lib/ruby/1.9.1/tk.rb:1363:in `<module:TkCore>'
>         from /usr/local/lib/ruby/1.9.1/tk.rb:1110:in `<top (required)>'
>         from ext/tk/sample/tkcombobox.rb:6:in `require'
>         from ext/tk/sample/tkcombobox.rb:6:in `<main>'

ぁぅ...
Ruby 1.9 で必要になる Tcl インタープリタ専用スレッドが
落ちちゃっているんでしょうね.
以下ではいかがでしょうか?

--- ext/tk/lib/tk.rb	(revision 23988)
+++ ext/tk/lib/tk.rb	(working copy)
@@ -15,7 +15,9 @@
 class TclTkIp
   # backup original (without encoding) _eval and _invoke
   alias _eval_without_enc _eval
+  alias __eval__ _eval
   alias _invoke_without_enc _invoke
+  alias __invoke__ _invoke
 
   def _ip_id_
     # for RemoteTkIp
@@ -113,17 +115,24 @@
       gen_class_name = ruby_class_name
       classname_def = ''
     else # ruby_class == nil
-      mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)}
-      mods.each{|mod|
-        begin
-          mod.const_get(tk_class)  # auto_load
-          break if (ruby_class = WidgetClassNames[tk_class])
-        rescue LoadError
-          # ignore load error
-        end
-      }
+      if Tk.const_defined?(tk_class)
+        mod.const_get(tk_class)  # auto_load
+        ruby_class = WidgetClassNames[tk_class]
+      end
 
       unless ruby_class
+        mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)}
+        mods.each{|mod|
+          begin
+            mod.const_get(tk_class)  # auto_load
+            break if (ruby_class = WidgetClassNames[tk_class])
+          rescue LoadError
+            # ignore load error
+          end
+        }
+      end
+
+      unless ruby_class
         std_class = 'Tk' << tk_class
         if Object.const_defined?(std_class)
           Object.const_get(std_class)  # auto_load
@@ -131,6 +140,14 @@
         end
       end
 
+      unless ruby_class
+        if Tk.const_defined?('TOPLEVEL_ALIASES') &&
+            Tk::TOPLEVEL_ALIASES.const_defined?(std_class)
+          Tk::TOPLEVEL_ALIASES.const_get(std_class)  # auto_load
+          ruby_class = WidgetClassNames[tk_class]
+        end
+      end
+
       if ruby_class
         # found
         ruby_class_name = ruby_class.name
@@ -613,11 +630,35 @@
       val
     end
   end
-  private :bool, :number, :string, :num_or_str
-  private :list, :simplelist, :window, :procedure
-  module_function :bool, :number, :num_or_str, :string
+  private :bool, :number, :num_or_str, :num_or_nil, :string
+  private :list, :simplelist, :window, :image_obj, :procedure
+  module_function :bool, :number, :num_or_str, :num_or_nil, :string
   module_function :list, :simplelist, :window, :image_obj, :procedure
 
+  if (RUBY_VERSION.split('.').map{|n| n.to_i} <=> [1,8,7]) < 0
+    def slice_ary(ary, size)
+      sliced = []
+      wk_ary = ary.dup
+      until wk_ary.size.zero?
+        sub_ary = []
+        size.times{ sub_ary << wk_ary.shift }
+        yield(sub_ary) if block_given?
+        sliced << sub_ary
+      end
+      (block_given?)? ary: sliced
+    end
+  else
+    def slice_ary(ary, size, &b)
+      if b
+        ary.each_slice(size, &b)
+      else
+        ary.each_slice(size).to_a
+      end
+    end
+  end
+  private :slice_ary
+  module_function :slice_ary
+
   def subst(str, *opts)
     # opts := :nobackslashes | :nocommands | novariables
     tk_call('subst',
@@ -1130,30 +1171,42 @@
       opts = ''
     end
 
-    if WITH_RUBY_VM ### check Ruby 1.9 !!!!!!!
-      # *** NEED TO FIX ***
-      ip = TclTkIp.new(name, opts)
-      if ip._invoke_without_enc('tk', 'windowingsystem') == 'aqua' &&
-          (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
-        # *** KNOWN BUG ***
-        #   Main event loop thread of TkAqua (> Tk8.4.9) must be the main
-        #   application thread. So, ruby1.9 users must call Tk.mainloop on
-        #   the main application thread.
-        RUN_EVENTLOOP_ON_MAIN_THREAD = true
-        INTERP = ip
-      else
-        unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
-          RUN_EVENTLOOP_ON_MAIN_THREAD = false
-        end
-        if RUN_EVENTLOOP_ON_MAIN_THREAD
+    unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
+      if WITH_RUBY_VM ### check Ruby 1.9 !!!!!!!
+        # *** NEED TO FIX ***
+        ip = TclTkIp.new(name, opts)
+        if ip._invoke_without_enc('tk', 'windowingsystem') == 'aqua' &&
+            (TclTkLib.get_version<=>[8,4,TclTkLib::RELEASE_TYPE::FINAL,6]) > 0
+          # *** KNOWN BUG ***
+          #   Main event loop thread of TkAqua (> Tk8.4.9) must be the main
+          #   application thread. So, ruby1.9 users must call Tk.mainloop on
+          #   the main application thread.
+          #
+          # *** ADD (2009/05/10) ***
+          #   In some cases (I don't know the description of conditions), 
+          #   TkAqua 8.4.7 has a same kind of hang-up trouble. 
+          #   So, if 8.4.7 or later, set RUN_EVENTLOOP_ON_MAIN_THREAD to true. 
+          #   When you want to control this mode, please call the following 
+          #   (set true/false as you want) before "require 'tk'".
+          #   ----------------------------------------------------------
+          #   module TkCore; RUN_EVENTLOOP_ON_MAIN_THREAD = true; end
+          #   ----------------------------------------------------------
+          #
+          RUN_EVENTLOOP_ON_MAIN_THREAD = true
           INTERP = ip
         else
-          ip.delete
+          unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
+            RUN_EVENTLOOP_ON_MAIN_THREAD = false
+          end
+          if RUN_EVENTLOOP_ON_MAIN_THREAD
+            INTERP = ip
+          else
+            ip.delete
+          end
         end
-      end
-      ip = nil
-    else
-      unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
+        ip = nil
+
+      else # Ruby 1.8.x
         RUN_EVENTLOOP_ON_MAIN_THREAD = false
       end
     end
@@ -1183,13 +1236,29 @@
         #sleep
 
         begin
-          Thread.current[:status].value = TclTkLib.mainloop(true)
-        rescue Exception=>e
-          Thread.current[:status].value = e
+          begin
+            #TclTkLib.mainloop_abort_on_exception = false
+            #Thread.current[:status].value = TclTkLib.mainloop(true)
+            interp.mainloop_abort_on_exception = true
+            Thread.current[:status].value = interp.mainloop(true)
+          rescue SystemExit=>e
+            Thread.current[:status].value = e
+          rescue Exception=>e
+            Thread.current[:status].value = e
+            retry if interp.has_mainwindow?
+          ensure
+            INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }
+          end
+
+          #Thread.current[:status].value = TclTkLib.mainloop(false)
+          Thread.current[:status].value = interp.mainloop(false)
+
         ensure
-          INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }
+          # interp must be deleted before the thread for interp is dead.
+          # If not, raise Tcl_Panic on Tcl_AsyncDelete because async handler 
+          # deleted by the wrong thread.
+          interp.delete
         end
-        Thread.current[:status].value = TclTkLib.mainloop(false)
       }
 
       until INTERP_THREAD[:interp]
@@ -1321,7 +1390,8 @@
         @add_tk_procs.delete_if{|elem|
           elem.kind_of?(Array) && elem[0].to_s == name
         }
-        self._invoke('rename', name, '')
+        #self._invoke('rename', name, '')
+        self.__invoke__('rename', name, '')
       }
     end
     def INTERP.init_ip_internal
@@ -1704,11 +1774,14 @@
 
     elsif TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD
       # if TclTkLib::WINDOWING_SYSTEM == 'aqua' &&
-      if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='aqua' &&
-          Thread.current != Thread.main &&
-          (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
-        raise RuntimeError,
-              "eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only"
+      #if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='aqua' &&
+      #    Thread.current != Thread.main &&
+      #    (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
+      #  raise RuntimeError,
+      #       "eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only"
+      #end
+      if Thread.current != Thread.main
+        raise RuntimeError, "Tk.mainloop is allowed on the main thread only"
       end
       TclTkLib.mainloop(check_root)
 
@@ -3028,7 +3101,7 @@
 
 =begin
     if ext_enc_obj == Tk::Encoding::UNKNOWN
-      if defind? DEFAULT_TK_ENCODING
+      if defined? DEFAULT_TK_ENCODING
         if DEFAULT_TK_ENCODING.kind_of?(::Encoding)
           tk_enc_name    = DEFAULT_TK_ENCODING.name
           tksys_enc_name = DEFAULT_TK_ENCODING.name
@@ -3126,7 +3199,7 @@
           #if ext_enc_name && ext_enc_name != tksys_enc_name
           int_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(int_enc_obj)
           if int_enc_name
-            # use default_external
+            # use default_internal
             enc_name = int_enc_name
           else
             # use Tk.encoding_system
@@ -3279,10 +3352,10 @@
         TkFont.init_widget_font(pathname, *__confinfo_cmd)
     else
       fonts = {}
-      optkeys.each{|key|
-        key = key.to_s
-        pathname = [win, tag, key].join(';')
-        fonts[key] =
+      optkeys.each{|k|
+        k = k.to_s
+        pathname = [win, tag, k].join(';')
+        fonts[k] =
           TkFont.used_on(pathname) ||
           TkFont.init_widget_font(pathname, *__confinfo_cmd)
       }
@@ -3407,7 +3480,7 @@
       if fobj.kind_of?(TkFont)
         if ltn.kind_of?(TkFont)
           conf = {}
-          ltn.latin_configinfo.each{|key,val| conf[key] = val}
+          ltn.latin_configinfo.each{|k,val| conf[k] = val}
           if keys
             fobj.latin_configure(conf.update(keys))
           else
@@ -3467,7 +3540,7 @@
       if fobj.kind_of?(TkFont)
         if knj.kind_of?(TkFont)
           conf = {}
-          knj.kanji_configinfo.each{|key,val| conf[key] = val}
+          knj.kanji_configinfo.each{|k,val| conf[k] = val}
           if keys
             fobj.kanji_configure(conf.update(keys))
           else
@@ -3701,11 +3774,17 @@
     val
   end
 
+  def cget_tkstring(option)
+    opt = option.to_s
+    fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.length == 0
+    tk_call_without_enc(*(__cget_cmd << "-#{opt}"))
+  end
+
   def __cget_core(slot)
     orig_slot = slot
     slot = slot.to_s
 
-   if slot.length == 0
+    if slot.length == 0
       fail ArgumentError, "Invalid option `#{orig_slot.inspect}'"
     end
 
@@ -4106,7 +4185,8 @@
 
           else
             # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
-            conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true)
+            # conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true)
+            conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 1, false, true)
           end
           conf[__configinfo_struct[:key]] =
             conf[__configinfo_struct[:key]][1..-1]
@@ -4296,8 +4376,8 @@
             end
           }
 
-          __methodcall_optkeys.each{|optkey, method|
-            ret << [optkey.to_s, '', '', '', self.__send__(method)]
+          __methodcall_optkeys.each{|optkey, m|
+            ret << [optkey.to_s, '', '', '', self.__send__(m)]
           }
 
           ret
@@ -4335,7 +4415,7 @@
         if slot
           slot = slot.to_s
 
-          alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}
+          alias_name, real_name = __optkey_aliases.find{|k,var| k.to_s == slot}
           if real_name
             slot = real_name.to_s
           end
@@ -4682,8 +4762,8 @@
             end
           }
 
-          __methodcall_optkeys.each{|optkey, method|
-            ret[optkey.to_s] = ['', '', '', self.__send__(method)]
+          __methodcall_optkeys.each{|optkey, m|
+            ret[optkey.to_s] = ['', '', '', self.__send__(m)]
           }
 
           ret
@@ -4721,18 +4801,18 @@
           "there is a configure alias loop about '#{org_slot}'"
       else
         ret = {}
-        configinfo().each{|conf|
+        configinfo().each{|cnf|
           if ( ! __configinfo_struct[:alias] \
-              || conf.size > __configinfo_struct[:alias] + 1 )
-            ret[conf[0]] = conf[-1]
+              || cnf.size > __configinfo_struct[:alias] + 1 )
+            ret[cnf[0]] = cnf[-1]
           end
         }
         ret
       end
     else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
       ret = {}
-      configinfo(slot).each{|key, conf|
-        ret[key] = conf[-1] if conf.kind_of?(Array)
+      configinfo(slot).each{|key, cnf|
+        ret[key] = cnf[-1] if cnf.kind_of?(Array)
       }
       ret
     end
@@ -4864,6 +4944,7 @@
   include TkWinfo
   extend TkBindCore
   include Tk::Wm_for_General
+  include Tk::Busy
 
   @@WIDGET_INSPECT_FULL = false
   def TkWindow._widget_inspect_full_?
@@ -5551,7 +5632,7 @@
 #Tk.freeze
 
 module Tk
-  RELEASE_DATE = '2009-01-13'.freeze
+  RELEASE_DATE = '2009-07-08'.freeze
 
   autoload :AUTO_PATH,        'tk/variable'
   autoload :TCL_PACKAGE_PATH, 'tk/variable'

-- 
永井 秀利  (nagai@ai.kyutech.ac.jp)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門

In This Thread