From: "akr (Akira Tanaka)" Date: 2013-11-04T18:38:11+09:00 Subject: [ruby-dev:47791] [ruby-trunk - Bug #9072] test_weakref.rb failure Issue #9072 has been updated by akr (Akira Tanaka). ちょっと追いかけたところ、ObjectSpace::WeakMap が、 入れた覚えのないオブジェクトを返すことがあるようです。 % ./ruby -ve ' wmap = ObjectSpace::WeakMap.new keys = (1..10000).map {|i| i.to_s } keys.each {|k| wmap[k] = "value" } GC.start keys.each {|k| p wmap[k] } '|head -30 ruby 2.1.0dev (2013-11-04 trunk 43525) [x86_64-linux] nil [0, #] [0, #] nil [0, #] [0, #] nil [0, #] [0, #] nil [0, #] [0, #] nil [0, #] [0, #] nil [0, #] [0, #] nil [0, #] [0, #] nil nil nil [0, #] nil nil nil nil -e:6:in `p': Broken pipe (Errno::EPIPE) from -e:6:in `block in
' from -e:6:in `each' from -e:6:in `
' ---------------------------------------- Bug #9072: test_weakref.rb failure https://bugs.ruby-lang.org/issues/9072#change-42739 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/