From: "akr (Akira Tanaka)" Date: 2013-11-05T19:48:16+09:00 Subject: [ruby-dev:47792] [ruby-trunk - Bug #9072] test_weakref.rb failure Issue #9072 has been updated by akr (Akira Tanaka). もうちょっと調べて、いくらか少ない繰り返しで症状を発生させてみました。 % ./ruby -ve ' wmap = ObjectSpace::WeakMap.new keys = [] 1.upto(10) {|i| GC.start k = i.to_s v = i.to_s keys << k wmap[k] = v keys.each {|kk| vv = wmap[kk] next if vv == nil || vv == kk p [kk, vv] } } ' ruby 2.1.0dev (2013-11-05 trunk 43538) [x86_64-linux] ["1", [69905805532920]] ["1", [69905805532700]] ["2", "8"] ["5", "\"1\""] ["1", [69905805532620]] ["2", "8"] ["3", "9"] ["5", "9"] ["6", "[\"3\", \"9\"]"] ["1", [69905805532560]] ["2", "8"] ["3", "9"] ["4", "10"] ["5", "9"] ["6", "10"] ["7", "[\"5\", \"9\"]"] キーと同じ値を入れたはずが、違うものが返ってくるのが観察できます。 finalizer が、想定されているほど早くには動かない、のかなぁ。 ---------------------------------------- Bug #9072: test_weakref.rb failure https://bugs.ruby-lang.org/issues/9072#change-42757 Author: akr (Akira Tanaka) Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: ruby 2.1.0dev (2013-11-01 trunk 43510) [i686-linux] Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN test_weakref.rb を単独で動かすと、以下のように失敗します。 boron% ./ruby -v -e 'load("test/test_weakref.rb")' ruby 2.1.0dev (2013-11-01 trunk 43510) [i686-linux] test/test_weakref.rb:19: warning: assigned but unused variable - str Run options: # Running tests: [2/4] TestWeakRef#test_recycled = 0.01 s 1) Failure: TestWeakRef#test_recycled [test/test_weakref.rb:25]: Expected "." to not be weakref_alive?. Finished tests in 0.140466s, 28.4766 tests/s, 64.0724 assertions/s. 4 tests, 9 assertions, 1 failures, 0 errors, 0 skips ruby -v: ruby 2.1.0dev (2013-11-01 trunk 43510) [i686-linux] いろいろと疑問はあるのですが、 とりあえず weakref_alive? の結果を確認して見ようと思って test/test_weakref.rb に以下のように p を入れてみました。 def test_recycled weak, str = make_weakref assert_nothing_raised(WeakRef::RefError) {weak.to_s} assert_predicate(weak, :weakref_alive?) ObjectSpace.garbage_collect ObjectSpace.garbage_collect assert_raise(WeakRef::RefError) {weak.to_s} p weak.weakref_alive? assert_not_predicate(weak, :weakref_alive?) end そうすると、以下のようになりました。 boron% ./ruby -v -e 'load("test/test_weakref.rb")' ruby 2.1.0dev (2013-11-01 trunk 43510) [i686-linux] test/test_weakref.rb:19: warning: assigned but unused variable - str Run options: # Running tests: [2/4] TestWeakRef#test_recyclednil = 0.01 s 1) Failure: TestWeakRef#test_recycled [test/test_weakref.rb:26]: Expected [] to not be weakref_alive?. Finished tests in 0.164603s, 24.3009 tests/s, 54.6770 assertions/s. 4 tests, 9 assertions, 1 failures, 0 errors, 0 skips ruby -v: ruby 2.1.0dev (2013-11-01 trunk 43510) [i686-linux] weakref_alive? は nil を返しているようですがそれはともかく、 ここで奇妙なのは、Expected の次に出てくるのが "." から [] に変わっていることです。 さらにもうひとつ p を入れてみました。 def test_recycled weak, str = make_weakref assert_nothing_raised(WeakRef::RefError) {weak.to_s} assert_predicate(weak, :weakref_alive?) ObjectSpace.garbage_collect ObjectSpace.garbage_collect assert_raise(WeakRef::RefError) {weak.to_s} p weak.weakref_alive? p weak.weakref_alive? assert_not_predicate(weak, :weakref_alive?) end そうすると以下のようになりました。 boron% ./ruby -v -e 'load("test/test_weakref.rb")' ruby 2.1.0dev (2013-11-01 trunk 43510) [i686-linux] test/test_weakref.rb:19: warning: assigned but unused variable - str Run options: # Running tests: [2/4] TestWeakRef#test_recyclednil nil = 0.01 s 1) Failure: TestWeakRef#test_recycled [test/test_weakref.rb:27]: Expected {Object=>:never} to not be weakref_alive?. Finished tests in 0.140746s, 28.4200 tests/s, 63.9450 assertions/s. 4 tests, 9 assertions, 1 failures, 0 errors, 0 skips ruby -v: ruby 2.1.0dev (2013-11-01 trunk 43510) [i686-linux] Expected の次に出てくるのは今度は {Object=>:never} になっています。 思うのですが、Expected の次に出てくるのがこのように変わるのはあまりに奇妙ではないでしょうか。 -- http://bugs.ruby-lang.org/