ref-1.0.2/0000755000175000017500000000000012063250627011647 5ustar boutilboutilref-1.0.2/MIT_LICENSE0000644000175000017500000000204012063250626013360 0ustar boutilboutilCopyright (c) 2011 Brian Durand Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ref-1.0.2/README.rdoc0000644000175000017500000000575312063250626013466 0ustar boutilboutilThis library provides object references for Ruby as well as some common utilities for working with references. Object references are used to point to other objects and come in three distinct flavors that interact differently with the garbage collector. * Ref::StrongReference - This is a plain old pointer to another object. * Ref::WeakReference - This is a pointer to another object, but it is not seen by the garbage collector and the memory used by the object can be reclaimed at any time. * Ref::SoftReference - This is similar to a weak reference, but the garbage collector is not as eager to reclaim the referenced object. All of these classes extend from a common Ref::Reference class and have a common interface. Weak and soft references are useful when you have instantiated objects that you may want to use again but can recreate if necessary. Since the garbage collector determines when to reclaim the memory used by the objects, you don't need to worry about bloating the Ruby heap. = Example Usage ref = Ref::WeakReference.new("hello") ref.object # should be "hello" ObjectSpace.garbage_collect ref.object # should be nil (assuming the garbage collector reclaimed the reference) = Goodies This library also includes tools for some common uses of weak and soft references. * Ref::WeakKeyMap - A map of keys to values where the keys are weak references * Ref::WeakValueMap - A map of keys to values where the values are weak references * Ref::SoftKeyMap - A map of keys to values where the keys are soft references * Ref::SoftValueMap - A map of keys to values where the values are soft references * Ref::ReferenceQueue - A thread safe implementation of a queue that will add references to itself as their objects are garbage collected. = Problems with WeakRef Ruby does come with the WeakRef class in the standard library. However, there are issues with this class across several different Ruby runtimes. This gem provides a common interface to weak references that works across MRI, Ruby Enterprise Edition, YARV, Jruby, Rubinius, and IronRuby. 1. MRI and REE 1.8 - WeakRef extends from Delegator which is a very heavy weight class under Ruby 1.8. Creating a WeakRef object will allocate thousands of other objects and use up hundreds of kilobytes of memory. This makes WeakRef all but unusable even if you only need several hundred of them. 2. YARV 1.9 - WeakRef is unsafe to use because the garbage collector can run in a different system thread than a thread allocating memory. This exposes a bug where a WeakRef may end up pointing to a completely different object than it originally referenced. 3. Jruby and IronRuby - Jruby and IronRuby using the Ruby 1.8 libraries suffers from the same performance issue with the Delegator class. Furthermore, these VM's don't implement the method used to load an object from the heap using an object id and so cannot use a pure Ruby method to implement weak references. 4. Rubinius - Rubinius implements WeakRef with a lighter weight version of delegation and works very well. ref-1.0.2/ext/0000755000175000017500000000000012063250626012446 5ustar boutilboutilref-1.0.2/ext/java/0000755000175000017500000000000012063250626013367 5ustar boutilboutilref-1.0.2/ext/java/org/0000755000175000017500000000000012063250626014156 5ustar boutilboutilref-1.0.2/ext/java/org/jruby/0000755000175000017500000000000012063250626015311 5ustar boutilboutilref-1.0.2/ext/java/org/jruby/ext/0000755000175000017500000000000012063250626016111 5ustar boutilboutilref-1.0.2/ext/java/org/jruby/ext/ref/0000755000175000017500000000000012063250626016665 5ustar boutilboutilref-1.0.2/ext/java/org/jruby/ext/ref/RubyWeakReference.java0000644000175000017500000000251612063250626023104 0ustar boutilboutilpackage org.jruby.ext.ref; import java.lang.ref.WeakReference; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyObject; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; public class RubyWeakReference extends RubyObject { private WeakReference _ref; private static final String REFERENCED_OBJECT_ID_VARIABLE = "@referenced_object_id".intern(); public RubyWeakReference(Ruby runtime, RubyClass klass) { super(runtime, klass); } public static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new RubyWeakReference(runtime, klass); } }; @JRubyMethod(name = "initialize", frame = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(ThreadContext context, IRubyObject obj) { _ref = new WeakReference(obj); fastSetInstanceVariable(REFERENCED_OBJECT_ID_VARIABLE, obj.id()); return context.getRuntime().getNil(); } @JRubyMethod(name = "object") public IRubyObject object() { IRubyObject obj = (IRubyObject)_ref.get(); if (obj != null) { return obj; } else { return getRuntime().getNil(); } } } ref-1.0.2/ext/java/org/jruby/ext/ref/RubySoftReference.java0000644000175000017500000000251612063250626023130 0ustar boutilboutilpackage org.jruby.ext.ref; import java.lang.ref.SoftReference; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyObject; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; public class RubySoftReference extends RubyObject { private SoftReference _ref; private static final String REFERENCED_OBJECT_ID_VARIABLE = "@referenced_object_id".intern(); public RubySoftReference(Ruby runtime, RubyClass klass) { super(runtime, klass); } public static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new RubySoftReference(runtime, klass); } }; @JRubyMethod(name = "initialize", frame = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(ThreadContext context, IRubyObject obj) { _ref = new SoftReference(obj); fastSetInstanceVariable(REFERENCED_OBJECT_ID_VARIABLE, obj.id()); return context.getRuntime().getNil(); } @JRubyMethod(name = "object") public IRubyObject object() { IRubyObject obj = (IRubyObject)_ref.get(); if (obj != null) { return obj; } else { return getRuntime().getNil(); } } } ref-1.0.2/ext/java/org/jruby/ext/ref/ReferencesService.java0000644000175000017500000000203212063250626023127 0ustar boutilboutilpackage org.jruby.ext.ref; import java.io.IOException; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.load.BasicLibraryService; /** * This library adds native Java support for weak and soft references. * * @author Brian Durand */ public class ReferencesService implements BasicLibraryService { public boolean basicLoad(Ruby runtime) throws IOException { RubyModule refModule = runtime.getModule("Ref"); RubyClass referenceClass = refModule.getClass("Reference"); RubyClass rubyWeakReferenceClass = runtime.defineClassUnder("WeakReference", referenceClass, RubyWeakReference.ALLOCATOR, refModule); rubyWeakReferenceClass.defineAnnotatedMethods(RubyWeakReference.class); RubyClass rubySoftReferenceClass = runtime.defineClassUnder("SoftReference", referenceClass, RubySoftReference.ALLOCATOR, refModule); rubySoftReferenceClass.defineAnnotatedMethods(RubySoftReference.class); return true; } } ref-1.0.2/VERSION0000644000175000017500000000000512063250626012711 0ustar boutilboutil1.0.2ref-1.0.2/test/0000755000175000017500000000000012063250626012625 5ustar boutilboutilref-1.0.2/test/soft_key_map_test.rbc0000644000175000017500000000252312063250626017036 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 82 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 5 45 2 7 7 8 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 9 45 10 11 43 12 43 13 65 49 14 3 13 99 12 7 15 12 7 16 12 65 12 49 17 4 15 49 15 0 15 2 11 I 6 I 0 I 0 I 0 n p 18 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path n s 29 ../reference_key_map_behavior x 14 TestSoftKeyMap x 4 Test n x 4 Unit x 8 TestCase x 10 open_class x 14 __class_init__ M 1 n n x 14 TestSoftKeyMap i 39 5 66 5 45 0 1 47 49 2 1 15 99 7 3 7 4 65 67 49 5 0 49 6 4 15 99 7 7 7 8 65 67 49 5 0 49 6 4 11 I 5 I 0 I 0 I 0 n p 9 x 23 ReferenceKeyMapBehavior n x 7 include x 9 map_class M 1 n n x 9 map_class i 6 45 0 1 43 2 11 I 1 I 0 I 0 I 0 n p 3 x 3 Ref n x 10 SoftKeyMap p 5 I -1 I 8 I 0 I 9 I 6 x 57 /Users/bdurand/dev/projects/ref/test/soft_key_map_test.rb p 0 x 17 method_visibility x 15 add_defn_method x 15 reference_class M 1 n n x 15 reference_class i 6 45 0 1 43 2 11 I 1 I 0 I 0 I 0 n p 3 x 3 Ref n x 13 SoftReference p 5 I -1 I c I 0 I d I 6 x 57 /Users/bdurand/dev/projects/ref/test/soft_key_map_test.rb p 0 p 7 I 2 I 6 I b I 8 I 19 I c I 27 x 57 /Users/bdurand/dev/projects/ref/test/soft_key_map_test.rb p 0 x 13 attach_method p 9 I 0 I 1 I 9 I 2 I 1c I 3 I 2f I 5 I 52 x 57 /Users/bdurand/dev/projects/ref/test/soft_key_map_test.rb p 0 ref-1.0.2/test/weak_value_map_test.rbc0000644000175000017500000000254512063250626017342 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 82 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 5 45 2 7 7 8 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 9 45 10 11 43 12 43 13 65 49 14 3 13 99 12 7 15 12 7 16 12 65 12 49 17 4 15 49 15 0 15 2 11 I 6 I 0 I 0 I 0 n p 18 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path n s 31 ../reference_value_map_behavior x 16 TestWeakValueMap x 4 Test n x 4 Unit x 8 TestCase x 10 open_class x 14 __class_init__ M 1 n n x 16 TestWeakValueMap i 39 5 66 5 45 0 1 47 49 2 1 15 99 7 3 7 4 65 67 49 5 0 49 6 4 15 99 7 7 7 8 65 67 49 5 0 49 6 4 11 I 5 I 0 I 0 I 0 n p 9 x 25 ReferenceValueMapBehavior n x 7 include x 9 map_class M 1 n n x 9 map_class i 6 45 0 1 43 2 11 I 1 I 0 I 0 I 0 n p 3 x 3 Ref n x 12 WeakValueMap p 5 I -1 I 8 I 0 I 9 I 6 x 59 /Users/bdurand/dev/projects/ref/test/weak_value_map_test.rb p 0 x 17 method_visibility x 15 add_defn_method x 15 reference_class M 1 n n x 15 reference_class i 6 45 0 1 43 2 11 I 1 I 0 I 0 I 0 n p 3 x 3 Ref n x 13 WeakReference p 5 I -1 I c I 0 I d I 6 x 59 /Users/bdurand/dev/projects/ref/test/weak_value_map_test.rb p 0 p 7 I 2 I 6 I b I 8 I 19 I c I 27 x 59 /Users/bdurand/dev/projects/ref/test/weak_value_map_test.rb p 0 x 13 attach_method p 9 I 0 I 1 I 9 I 2 I 1c I 3 I 2f I 5 I 52 x 59 /Users/bdurand/dev/projects/ref/test/weak_value_map_test.rb p 0 ref-1.0.2/test/soft_reference_test.rbc0000644000175000017500000001164012063250626017347 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 63 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 7 45 8 9 43 10 43 11 65 49 12 3 13 99 12 7 13 12 7 14 12 65 12 49 15 4 15 49 13 0 15 2 11 I 6 I 0 I 0 I 0 n p 16 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path x 17 TestSoftReference x 4 Test n x 4 Unit x 8 TestCase x 10 open_class x 14 __class_init__ M 1 n n x 17 TestSoftReference i 58 5 66 99 7 0 7 1 65 67 49 2 0 49 3 4 15 99 7 4 7 5 65 67 49 2 0 49 3 4 15 99 7 6 7 7 65 67 49 2 0 49 3 4 15 99 7 8 7 9 65 67 49 2 0 49 3 4 11 I 5 I 0 I 0 I 0 n p 10 x 42 test_can_get_non_garbage_collected_objects M 1 n n x 42 test_can_get_non_garbage_collected_objects i 89 45 0 1 13 71 2 47 9 21 47 49 3 0 13 47 49 4 0 15 8 24 49 2 0 19 0 15 45 5 6 43 7 13 71 2 47 9 52 47 49 3 0 13 20 0 47 49 4 1 15 8 57 20 0 49 2 1 19 1 15 5 20 0 20 1 49 8 0 47 49 9 2 15 5 20 0 49 10 0 20 1 49 11 0 47 49 9 2 11 I 5 I 2 I 0 I 0 n p 12 x 6 Object n x 3 new x 8 allocate x 10 initialize x 3 Ref n x 13 SoftReference x 6 object x 12 assert_equal x 9 object_id x 20 referenced_object_id p 11 I -1 I 5 I 0 I 6 I 1b I 7 I 3c I 8 I 49 I 9 I 59 x 59 /Users/bdurand/dev/projects/ref/test/soft_reference_test.rb p 2 x 3 obj x 3 ref x 17 method_visibility x 15 add_defn_method x 27 test_get_the_correct_object M 1 n n x 27 test_get_the_correct_object i 38 44 43 0 78 49 1 1 19 0 15 45 2 3 7 4 64 49 5 1 7 6 64 83 7 9 30 7 8 8 32 7 9 56 10 50 11 0 11 I 3 I 1 I 0 I 0 n p 12 x 4 Hash x 16 new_from_literal x 3 ENV n s 10 QUICK_TEST x 2 [] s 4 true x 2 == I 3e8 I 186a0 M 1 p 2 x 9 for_block t n x 27 test_get_the_correct_object i 219 57 19 0 15 45 0 1 13 71 2 47 9 25 47 49 3 0 13 47 49 4 0 15 8 28 49 2 0 19 1 15 21 1 0 20 1 49 5 0 49 6 1 9 81 21 1 0 20 1 49 5 0 49 7 1 19 2 15 20 2 49 8 0 9 78 5 7 9 64 47 49 10 1 15 1 33 8 79 1 8 82 1 15 7 11 64 7 12 64 7 13 64 7 14 64 7 15 64 7 16 64 7 17 64 7 12 64 7 18 64 7 19 64 7 20 64 7 21 64 7 22 64 7 23 64 7 24 64 7 25 64 7 26 64 7 27 64 7 28 64 35 19 15 21 1 0 20 1 49 5 0 45 29 30 43 31 13 71 2 47 9 176 47 49 3 0 13 20 1 47 49 4 1 15 8 181 20 1 49 2 1 13 18 3 49 32 2 15 15 20 0 7 33 49 34 1 78 83 35 9 217 45 36 37 49 38 0 15 5 7 39 47 49 40 1 8 218 1 11 I 17 I 3 I 1 I 1 n p 41 x 6 Object n x 3 new x 8 allocate x 10 initialize x 9 object_id x 4 key? x 2 [] x 6 object s 96 soft reference found with a live reference to an object that was not the one it was created with x 5 flunk s 4 Here s 3 are s 1 a s 5 bunch s 2 of s 7 objects s 4 that s 9 allocated s 3 and s 3 can s 4 then s 2 be s 7 cleaned s 2 up s 2 by s 3 the s 7 garbage s 9 collector x 3 Ref n x 13 SoftReference x 3 []= I 3e8 x 1 % x 2 == x 2 GC n x 5 start d +0.640000000000000013322676295501878485083580017089843750 -6 x 5 sleep p 31 I 0 I 13 I 4 I 14 I 1f I 15 I 2c I 16 I 3a I 17 I 41 I 18 I 4a I 19 I 4e I 17 I 51 I 15 I 53 I 1c I 8f I 1d I bd I 1e I c9 I 1f I d0 I 20 I d9 I 1e I db x 59 /Users/bdurand/dev/projects/ref/test/soft_reference_test.rb p 3 x 1 i x 3 obj x 3 ref x 5 times p 7 I -1 I c I 0 I 12 I a I 13 I 26 x 59 /Users/bdurand/dev/projects/ref/test/soft_reference_test.rb p 1 x 9 id_to_ref x 45 test_references_are_not_collected_immediately M 1 n n x 45 test_references_are_not_collected_immediately i 96 45 0 1 43 2 13 71 3 47 9 47 47 49 4 0 13 45 5 6 13 71 3 47 9 37 47 49 4 0 13 47 49 7 0 15 8 40 49 3 0 47 49 7 1 15 8 74 45 5 8 13 71 3 47 9 68 47 49 4 0 13 47 49 7 0 15 8 71 49 3 0 49 3 1 19 0 15 4 9 56 9 50 10 0 15 5 20 0 49 11 0 47 49 12 1 11 I 5 I 1 I 0 I 0 n p 13 x 3 Ref n x 13 SoftReference x 3 new x 8 allocate x 6 Object n x 10 initialize n M 1 p 2 x 9 for_block t n x 45 test_references_are_not_collected_immediately i 40 7 0 64 7 1 64 7 2 64 7 3 64 7 4 64 7 5 64 35 6 19 0 15 20 0 4 100 49 6 1 19 0 15 45 7 8 49 9 0 11 I 8 I 1 I 0 I 0 I -2 p 10 s 8 allocate s 4 some s 6 memory s 2 on s 3 the s 4 heap x 1 * x 2 GC n x 5 start p 3 I 0 I 27 I 28 x 59 /Users/bdurand/dev/projects/ref/test/soft_reference_test.rb p 1 x 3 arr x 5 times x 6 object x 6 assert p 9 I -1 I 25 I 0 I 26 I 4d I 27 I 55 I 28 I 60 x 59 /Users/bdurand/dev/projects/ref/test/soft_reference_test.rb p 1 x 3 ref x 12 test_inspect M 1 n n x 12 test_inspect i 113 45 0 1 43 2 13 71 3 47 9 47 47 49 4 0 13 45 5 6 13 71 3 47 9 37 47 49 4 0 13 47 49 7 0 15 8 40 49 3 0 47 49 7 1 15 8 74 45 5 8 13 71 3 47 9 68 47 49 4 0 13 47 49 7 0 15 8 71 49 3 0 49 3 1 19 0 15 5 20 0 49 9 0 47 49 10 1 15 45 11 12 49 13 0 15 45 11 14 49 13 0 15 5 20 0 49 9 0 47 49 10 1 11 I 5 I 1 I 0 I 0 n p 15 x 3 Ref n x 13 SoftReference x 3 new x 8 allocate x 6 Object n x 10 initialize n x 7 inspect x 6 assert x 2 GC n x 5 start n p 13 I -1 I 2b I 0 I 2c I 4d I 2d I 58 I 2e I 5f I 2f I 66 I 30 I 71 x 59 /Users/bdurand/dev/projects/ref/test/soft_reference_test.rb p 1 x 3 ref p 9 I 2 I 5 I 10 I c I 1e I 25 I 2c I 2b I 3a x 59 /Users/bdurand/dev/projects/ref/test/soft_reference_test.rb p 0 x 13 attach_method p 7 I 0 I 1 I 9 I 2 I 1c I 4 I 3f x 59 /Users/bdurand/dev/projects/ref/test/soft_reference_test.rb p 0 ref-1.0.2/test/mock_test.rb0000644000175000017500000000125212063250626015142 0ustar boutilboutilrequire File.expand_path("../test_helper", __FILE__) class TestMock < Test::Unit::TestCase def test_gc_with_argument Ref::Mock.use do obj_1 = Object.new obj_2 = Object.new ref_1 = Ref::WeakReference.new(obj_1) ref_2 = Ref::WeakReference.new(obj_2) Ref::Mock.gc(obj_1) assert_nil ref_1.object assert_equal ref_2.object, obj_2 end end def test_gc_with_no_argument Ref::Mock.use do obj_1 = Object.new obj_2 = Object.new ref_1 = Ref::WeakReference.new(obj_1) ref_2 = Ref::WeakReference.new(obj_2) Ref::Mock.gc assert_nil ref_1.object assert_nil ref_2.object end end end ref-1.0.2/test/reference_key_map_behavior.rbc0000644000175000017500000003326512063250626020650 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 56 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 7 65 49 8 2 13 99 12 7 9 12 7 10 12 65 12 49 11 4 15 49 9 0 15 2 11 I 6 I 0 I 0 I 0 n p 12 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path x 23 ReferenceKeyMapBehavior x 11 open_module x 15 __module_init__ M 1 n n x 23 ReferenceKeyMapBehavior i 142 5 66 99 7 0 7 1 65 67 49 2 0 49 3 4 15 99 7 4 7 5 65 67 49 2 0 49 3 4 15 99 7 6 7 7 65 67 49 2 0 49 3 4 15 99 7 8 7 9 65 67 49 2 0 49 3 4 15 99 7 10 7 11 65 67 49 2 0 49 3 4 15 99 7 12 7 13 65 67 49 2 0 49 3 4 15 99 7 14 7 15 65 67 49 2 0 49 3 4 15 99 7 16 7 17 65 67 49 2 0 49 3 4 15 99 7 18 7 19 65 67 49 2 0 49 3 4 15 99 7 20 7 21 65 67 49 2 0 49 3 4 11 I 5 I 0 I 0 I 0 n p 22 x 31 test_uses_the_proper_references M 1 n n x 31 test_uses_the_proper_references i 15 5 5 48 0 5 48 1 49 0 0 47 49 2 2 11 I 3 I 0 I 0 I 0 n p 3 x 15 reference_class x 9 map_class x 12 assert_equal p 5 I -1 I 5 I 0 I 6 I f x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 17 method_visibility x 15 add_defn_method x 41 test_keeps_entries_with_strong_references M 1 n n x 41 test_keeps_entries_with_strong_references i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 41 test_keeps_entries_with_strong_references i 143 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 45 4 5 13 71 1 47 9 48 47 49 2 0 13 47 49 3 0 15 8 51 49 1 0 19 1 15 45 4 6 13 71 1 47 9 75 47 49 2 0 13 47 49 3 0 15 8 78 49 1 0 19 2 15 20 0 20 1 7 7 64 13 18 3 49 8 2 15 15 20 0 20 2 7 9 64 13 18 3 49 8 2 15 15 5 7 7 64 20 0 20 1 49 10 1 47 49 11 2 15 5 7 9 64 20 0 20 2 49 10 1 47 49 11 2 11 I 8 I 3 I 0 I 0 I -2 p 12 x 9 map_class x 3 new x 8 allocate x 10 initialize x 6 Object n n s 7 value 1 x 3 []= s 7 value 2 x 2 [] x 12 assert_equal p 15 I 0 I b I 1b I c I 36 I d I 51 I e I 60 I f I 6f I 10 I 7f I 11 I 8f x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 3 x 4 hash x 5 key_1 x 5 key_2 x 3 use p 5 I -1 I 9 I 0 I a I b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 53 test_removes_entries_that_have_been_garbage_collected M 1 n n x 53 test_removes_entries_that_have_been_garbage_collected i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 53 test_removes_entries_that_have_been_garbage_collected i 183 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 45 4 5 13 71 1 47 9 48 47 49 2 0 13 47 49 3 0 15 8 51 49 1 0 19 1 15 45 4 6 13 71 1 47 9 75 47 49 2 0 13 47 49 3 0 15 8 78 49 1 0 19 2 15 20 0 20 1 7 7 64 13 18 3 49 8 2 15 15 20 0 20 2 7 9 64 13 18 3 49 8 2 15 15 5 7 7 64 20 0 20 1 49 10 1 47 49 11 2 15 5 7 9 64 20 0 20 2 49 10 1 47 49 11 2 15 45 12 13 43 14 20 2 49 15 1 15 5 7 7 64 20 0 20 1 49 10 1 47 49 11 2 15 5 20 0 20 2 49 10 1 47 49 16 1 11 I 8 I 3 I 0 I 0 I -2 p 17 x 9 map_class x 3 new x 8 allocate x 10 initialize x 6 Object n n s 7 value 1 x 3 []= s 7 value 2 x 2 [] x 12 assert_equal x 3 Ref n x 4 Mock x 2 gc x 10 assert_nil p 21 I 0 I 17 I 1b I 18 I 36 I 19 I 51 I 1a I 60 I 1b I 6f I 1c I 7f I 1d I 8f I 1e I 9a I 1f I aa I 20 I b7 x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 3 x 4 hash x 5 key_1 x 5 key_2 x 3 use p 5 I -1 I 15 I 0 I 16 I b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 22 test_can_clear_the_map M 1 n n x 22 test_can_clear_the_map i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 22 test_can_clear_the_map i 153 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 45 6 7 13 71 1 47 9 60 47 49 2 0 13 47 49 3 0 15 8 63 49 1 0 19 3 15 45 6 8 13 71 1 47 9 87 47 49 2 0 13 47 49 3 0 15 8 90 49 1 0 19 4 15 20 0 20 3 20 1 13 18 3 49 9 2 15 15 20 0 20 4 20 2 13 18 3 49 9 2 15 15 20 0 49 10 0 15 5 20 0 20 3 49 11 1 47 49 12 1 15 5 20 0 20 4 49 11 1 47 49 12 1 11 I a I 5 I 0 I 0 I -2 p 13 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 x 6 Object n n x 3 []= x 5 clear x 2 [] x 10 assert_nil p 21 I 0 I 26 I 1b I 27 I 21 I 28 I 27 I 29 I 42 I 2a I 5d I 2b I 6b I 2c I 79 I 2d I 7f I 2e I 8c I 2f I 99 x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 5 x 4 hash x 7 value_1 x 7 value_2 x 5 key_1 x 5 key_2 x 3 use p 5 I -1 I 24 I 0 I 25 I b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 23 test_can_delete_entries M 1 n n x 23 test_can_delete_entries i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 23 test_can_delete_entries i 173 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 45 6 7 13 71 1 47 9 60 47 49 2 0 13 47 49 3 0 15 8 63 49 1 0 19 3 15 45 6 8 13 71 1 47 9 87 47 49 2 0 13 47 49 3 0 15 8 90 49 1 0 19 4 15 20 0 20 3 20 1 13 18 3 49 9 2 15 15 20 0 20 4 20 2 13 18 3 49 9 2 15 15 45 10 11 43 12 20 4 49 13 1 15 5 20 0 20 4 49 14 1 47 49 15 1 15 5 20 1 20 0 20 3 49 14 1 47 49 16 2 15 5 20 0 20 3 49 17 1 47 49 15 1 11 I a I 5 I 0 I 0 I -2 p 18 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 x 6 Object n n x 3 []= x 3 Ref n x 4 Mock x 2 gc x 6 delete x 10 assert_nil x 12 assert_equal x 2 [] p 23 I 0 I 35 I 1b I 36 I 21 I 37 I 27 I 38 I 42 I 39 I 5d I 3a I 6b I 3b I 79 I 3c I 84 I 3d I 91 I 3e I a0 I 3f I ad x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 5 x 4 hash x 7 value_1 x 7 value_2 x 5 key_1 x 5 key_2 x 3 use p 5 I -1 I 33 I 0 I 34 I b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 30 test_can_merge_in_another_hash M 1 n n x 30 test_can_merge_in_another_hash i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 30 test_can_merge_in_another_hash i 261 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 7 6 64 19 3 15 45 7 8 13 71 1 47 9 66 47 49 2 0 13 47 49 3 0 15 8 69 49 1 0 19 4 15 45 7 9 13 71 1 47 9 93 47 49 2 0 13 47 49 3 0 15 8 96 49 1 0 19 5 15 45 7 10 13 71 1 47 9 120 47 49 2 0 13 47 49 3 0 15 8 123 49 1 0 19 6 15 20 0 20 4 20 1 13 18 3 49 11 2 15 15 20 0 20 5 20 2 13 18 3 49 11 2 15 15 20 0 44 43 12 79 49 13 1 13 20 6 20 3 49 11 2 15 49 14 1 15 5 7 5 64 20 0 20 5 49 15 1 47 49 16 2 15 5 20 1 20 0 20 4 49 15 1 47 49 16 2 15 45 17 18 43 19 20 5 49 20 1 15 5 20 0 20 5 49 15 1 47 49 21 1 15 5 20 1 20 0 20 4 49 15 1 47 49 16 2 15 5 20 3 20 0 20 6 49 15 1 47 49 16 2 11 I d I 7 I 0 I 0 I -2 p 22 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 7 value 3 x 6 Object n n n x 3 []= x 4 Hash x 16 new_from_literal x 6 merge! x 2 [] x 12 assert_equal x 3 Ref n x 4 Mock x 2 gc x 10 assert_nil p 33 I 0 I 45 I 1b I 46 I 21 I 47 I 27 I 48 I 2d I 49 I 48 I 4a I 63 I 4b I 7e I 4c I 8c I 4d I 9a I 4e I b0 I 4f I c0 I 50 I cf I 51 I da I 52 I e7 I 53 I f6 I 54 I 105 x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 7 x 4 hash x 7 value_1 x 7 value_2 x 7 value_3 x 5 key_1 x 5 key_2 x 5 key_3 x 3 use p 5 I -1 I 43 I 0 I 44 I b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 21 test_can_get_all_keys M 1 n n x 21 test_can_get_all_keys i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 21 test_can_get_all_keys i 227 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 7 6 64 19 3 15 45 7 8 13 71 1 47 9 66 47 49 2 0 13 47 49 3 0 15 8 69 49 1 0 19 4 15 45 7 9 13 71 1 47 9 93 47 49 2 0 13 47 49 3 0 15 8 96 49 1 0 19 5 15 45 7 10 13 71 1 47 9 120 47 49 2 0 13 47 49 3 0 15 8 123 49 1 0 19 6 15 20 0 20 4 20 1 13 18 3 49 11 2 15 15 20 0 20 5 20 2 13 18 3 49 11 2 15 15 20 0 20 6 20 3 13 18 3 49 11 2 15 15 5 35 0 20 4 20 5 20 6 35 3 20 0 49 12 0 82 13 47 49 14 2 15 45 15 16 43 17 20 5 49 18 1 15 5 20 5 35 1 20 4 20 5 20 6 35 3 20 0 49 12 0 82 13 47 49 14 2 11 I d I 7 I 0 I 0 I -2 p 19 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 7 value 3 x 6 Object n n n x 3 []= x 4 keys x 1 - x 12 assert_equal x 3 Ref n x 4 Mock x 2 gc p 27 I 0 I 5a I 1b I 5b I 21 I 5c I 27 I 5d I 2d I 5e I 48 I 5f I 63 I 60 I 7e I 61 I 8c I 62 I 9a I 63 I a8 I 64 I bf I 65 I ca I 66 I e3 x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 7 x 4 hash x 7 value_1 x 7 value_2 x 7 value_3 x 5 key_1 x 5 key_2 x 5 key_3 x 3 use p 5 I -1 I 58 I 0 I 59 I b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 27 test_can_turn_into_an_array M 1 n n x 27 test_can_turn_into_an_array i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 27 test_can_turn_into_an_array i 314 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 7 6 64 19 3 15 45 7 8 13 71 1 47 9 66 47 49 2 0 13 47 49 3 0 15 8 69 49 1 0 19 4 15 45 7 9 13 71 1 47 9 93 47 49 2 0 13 47 49 3 0 15 8 96 49 1 0 19 5 15 45 7 10 13 71 1 47 9 120 47 49 2 0 13 47 49 3 0 15 8 123 49 1 0 19 6 15 20 0 20 4 20 1 13 18 3 49 11 2 15 15 20 0 20 5 20 2 13 18 3 49 11 2 15 15 20 0 20 6 20 3 13 18 3 49 11 2 15 15 5 56 12 47 50 13 0 19 7 15 5 20 4 7 4 64 35 2 20 5 7 5 64 35 2 20 6 7 6 64 35 2 35 3 20 7 13 70 10 215 44 43 14 12 49 15 1 50 16 0 20 0 49 17 0 20 7 13 70 10 236 44 43 14 12 49 15 1 50 16 0 47 49 18 2 15 45 19 20 43 21 20 5 49 22 1 15 5 20 4 7 4 64 35 2 20 6 7 6 64 35 2 35 2 20 7 13 70 10 285 44 43 14 12 49 15 1 50 16 0 20 0 49 17 0 20 7 13 70 10 306 44 43 14 12 49 15 1 50 16 0 47 49 18 2 11 I e I 8 I 0 I 0 I -2 p 23 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 7 value 3 x 6 Object n n n x 3 []= M 1 p 2 x 9 for_block t n x 27 test_can_turn_into_an_array i 24 58 37 19 0 15 37 19 1 15 15 20 0 49 0 0 20 1 49 0 0 49 1 1 11 I 5 I 2 I 2 I 2 n p 2 x 4 last x 3 <=> p 3 I 0 I 76 I 18 x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 2 x 1 a x 1 b x 6 lambda x 4 Proc x 14 __from_block__ x 4 sort x 4 to_a x 12 assert_equal x 3 Ref n x 4 Mock x 2 gc p 29 I 0 I 6c I 1b I 6d I 21 I 6e I 27 I 6f I 2d I 70 I 48 I 71 I 63 I 72 I 7e I 73 I 8c I 74 I 9a I 75 I a8 I 76 I b2 I 77 I f4 I 78 I ff I 79 I 13a x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 8 x 4 hash x 7 value_1 x 7 value_2 x 7 value_3 x 5 key_1 x 5 key_2 x 5 key_3 x 5 order x 3 use p 5 I -1 I 6a I 0 I 6b I b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 33 test_can_iterate_over_all_entries M 1 n n x 33 test_can_iterate_over_all_entries i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 33 test_can_iterate_over_all_entries i 298 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 7 6 64 19 3 15 45 7 8 13 71 1 47 9 66 47 49 2 0 13 47 49 3 0 15 8 69 49 1 0 19 4 15 45 7 9 13 71 1 47 9 93 47 49 2 0 13 47 49 3 0 15 8 96 49 1 0 19 5 15 45 7 10 13 71 1 47 9 120 47 49 2 0 13 47 49 3 0 15 8 123 49 1 0 19 6 15 20 0 20 4 20 1 13 18 3 49 11 2 15 15 20 0 20 5 20 2 13 18 3 49 11 2 15 15 20 0 20 6 20 3 13 18 3 49 11 2 15 15 35 0 19 7 15 35 0 19 8 15 20 0 56 12 50 13 0 15 5 35 0 20 4 20 5 20 6 35 3 20 7 82 14 47 49 15 2 15 5 7 4 64 7 5 64 7 6 64 35 3 20 8 49 16 0 47 49 15 2 15 45 17 18 43 19 20 5 49 20 1 15 35 0 19 7 15 35 0 19 8 15 20 0 56 21 50 13 0 15 5 20 5 35 1 20 4 20 5 20 6 35 3 20 7 82 14 47 49 15 2 15 5 7 4 64 7 6 64 35 2 20 8 49 16 0 47 49 15 2 11 I f I 9 I 0 I 0 I -2 p 22 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 7 value 3 x 6 Object n n n x 3 []= M 1 p 2 x 9 for_block t n x 33 test_can_iterate_over_all_entries i 28 58 37 19 0 15 37 19 1 15 15 21 1 7 20 0 49 0 1 15 21 1 8 20 1 49 0 1 11 I 5 I 2 I 2 I 2 n p 1 x 2 << p 3 I 0 I 8b I 1c x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 2 x 1 k x 1 v x 4 each x 1 - x 12 assert_equal x 4 sort x 3 Ref n x 4 Mock x 2 gc M 1 p 2 x 9 for_block t n x 33 test_can_iterate_over_all_entries i 28 58 37 19 0 15 37 19 1 15 15 21 1 7 20 0 49 0 1 15 21 1 8 20 1 49 0 1 11 I 5 I 2 I 2 I 2 n p 1 x 2 << p 3 I 0 I 91 I 1c x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 2 x 1 k x 1 v p 43 I 0 I 7f I 1b I 80 I 21 I 81 I 27 I 82 I 2d I 83 I 48 I 84 I 63 I 85 I 7e I 86 I 8c I 87 I 9a I 88 I a8 I 89 I ad I 8a I b2 I 8b I ba I 8c I ce I 8d I e4 I 8e I ef I 8f I f4 I 90 I f9 I 91 I 101 I 92 I 117 I 93 I 12a x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 9 x 4 hash x 7 value_1 x 7 value_2 x 7 value_3 x 5 key_1 x 5 key_2 x 5 key_3 x 4 keys x 6 values x 3 use p 5 I -1 I 7d I 0 I 7e I b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 12 test_inspect M 1 n n x 12 test_inspect i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 12 test_inspect i 75 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 20 0 45 4 5 13 71 1 47 9 50 47 49 2 0 13 47 49 3 0 15 8 53 49 1 0 7 6 64 13 18 3 49 7 2 15 15 5 20 0 49 8 0 47 49 9 1 11 I 6 I 1 I 0 I 0 I -2 p 10 x 9 map_class x 3 new x 8 allocate x 10 initialize x 6 Object n s 7 value 1 x 3 []= x 7 inspect x 6 assert p 7 I 0 I 99 I 1b I 9a I 40 I 9b I 4b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 1 x 4 hash x 3 use p 5 I -1 I 97 I 0 I 98 I b x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 p 21 I 2 I 5 I 10 I 9 I 1e I 15 I 2c I 24 I 3a I 33 I 48 I 43 I 56 I 58 I 64 I 6a I 72 I 7d I 80 I 97 I 8e x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 x 13 attach_method p 7 I 0 I 1 I 9 I 2 I 1c I 4 I 38 x 66 /Users/bdurand/dev/projects/ref/test/reference_key_map_behavior.rb p 0 ref-1.0.2/test/weak_key_map_test.rbc0000644000175000017500000000252312063250626017012 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 82 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 5 45 2 7 7 8 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 9 45 10 11 43 12 43 13 65 49 14 3 13 99 12 7 15 12 7 16 12 65 12 49 17 4 15 49 15 0 15 2 11 I 6 I 0 I 0 I 0 n p 18 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path n s 29 ../reference_key_map_behavior x 14 TestWeakKeyMap x 4 Test n x 4 Unit x 8 TestCase x 10 open_class x 14 __class_init__ M 1 n n x 14 TestWeakKeyMap i 39 5 66 5 45 0 1 47 49 2 1 15 99 7 3 7 4 65 67 49 5 0 49 6 4 15 99 7 7 7 8 65 67 49 5 0 49 6 4 11 I 5 I 0 I 0 I 0 n p 9 x 23 ReferenceKeyMapBehavior n x 7 include x 9 map_class M 1 n n x 9 map_class i 6 45 0 1 43 2 11 I 1 I 0 I 0 I 0 n p 3 x 3 Ref n x 10 WeakKeyMap p 5 I -1 I 8 I 0 I 9 I 6 x 57 /Users/bdurand/dev/projects/ref/test/weak_key_map_test.rb p 0 x 17 method_visibility x 15 add_defn_method x 15 reference_class M 1 n n x 15 reference_class i 6 45 0 1 43 2 11 I 1 I 0 I 0 I 0 n p 3 x 3 Ref n x 13 WeakReference p 5 I -1 I c I 0 I d I 6 x 57 /Users/bdurand/dev/projects/ref/test/weak_key_map_test.rb p 0 p 7 I 2 I 6 I b I 8 I 19 I c I 27 x 57 /Users/bdurand/dev/projects/ref/test/weak_key_map_test.rb p 0 x 13 attach_method p 9 I 0 I 1 I 9 I 2 I 1c I 3 I 2f I 5 I 52 x 57 /Users/bdurand/dev/projects/ref/test/weak_key_map_test.rb p 0 ref-1.0.2/test/soft_value_map_test.rbc0000644000175000017500000000254512063250626017366 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 82 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 5 45 2 7 7 8 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 9 45 10 11 43 12 43 13 65 49 14 3 13 99 12 7 15 12 7 16 12 65 12 49 17 4 15 49 15 0 15 2 11 I 6 I 0 I 0 I 0 n p 18 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path n s 31 ../reference_value_map_behavior x 16 TestSoftValueMap x 4 Test n x 4 Unit x 8 TestCase x 10 open_class x 14 __class_init__ M 1 n n x 16 TestSoftValueMap i 39 5 66 5 45 0 1 47 49 2 1 15 99 7 3 7 4 65 67 49 5 0 49 6 4 15 99 7 7 7 8 65 67 49 5 0 49 6 4 11 I 5 I 0 I 0 I 0 n p 9 x 25 ReferenceValueMapBehavior n x 7 include x 9 map_class M 1 n n x 9 map_class i 6 45 0 1 43 2 11 I 1 I 0 I 0 I 0 n p 3 x 3 Ref n x 12 SoftValueMap p 5 I -1 I 8 I 0 I 9 I 6 x 59 /Users/bdurand/dev/projects/ref/test/soft_value_map_test.rb p 0 x 17 method_visibility x 15 add_defn_method x 15 reference_class M 1 n n x 15 reference_class i 6 45 0 1 43 2 11 I 1 I 0 I 0 I 0 n p 3 x 3 Ref n x 13 SoftReference p 5 I -1 I c I 0 I d I 6 x 59 /Users/bdurand/dev/projects/ref/test/soft_value_map_test.rb p 0 p 7 I 2 I 6 I b I 8 I 19 I c I 27 x 59 /Users/bdurand/dev/projects/ref/test/soft_value_map_test.rb p 0 x 13 attach_method p 9 I 0 I 1 I 9 I 2 I 1c I 3 I 2f I 5 I 52 x 59 /Users/bdurand/dev/projects/ref/test/soft_value_map_test.rb p 0 ref-1.0.2/test/weak_reference_test.rb0000644000175000017500000000311712063250626017160 0ustar boutilboutilrequire File.expand_path("../test_helper", __FILE__) class TestWeakReference < Test::Unit::TestCase def test_can_get_non_garbage_collected_objects obj = Object.new ref_1 = Ref::WeakReference.new(obj) ref_2 = Ref::WeakReference.new(obj) assert_equal obj, ref_1.object assert_equal obj.object_id, ref_1.referenced_object_id assert_equal obj, ref_2.object assert_equal obj.object_id, ref_2.referenced_object_id end def test_get_the_correct_object # Since we can't reliably control the garbage collector, this is a brute force test. # It might not always fail if the garbage collector and memory allocator don't # cooperate, but it should fail often enough on continuous integration to # hilite any problems. Set the environment variable QUICK_TEST to "true" if you # want to make the tests run quickly. id_to_ref = {} (ENV["QUICK_TEST"] == "true" ? 1000 : 100000).times do |i| obj = Object.new if id_to_ref.key?(obj.object_id) ref = id_to_ref[obj.object_id] if ref.object flunk "weak reference found with a live reference to an object that was not the one it was created with" break end end %w(Here are a bunch of objects that are allocated and can then be cleaned up by the garbage collector) id_to_ref[obj.object_id] = Ref::WeakReference.new(obj) if i % 1000 == 0 GC.start sleep(0.01) end end end def test_inspect ref = Ref::WeakReference.new(Object.new) assert ref.inspect GC.start GC.start assert ref.inspect end end ref-1.0.2/test/reference_queue_test.rb0000644000175000017500000000323612063250626017357 0ustar boutilboutilrequire File.expand_path("../test_helper", __FILE__) class TestReferenceQueue < Test::Unit::TestCase def test_can_add_references queue = Ref::ReferenceQueue.new ref_1 = Ref::WeakReference.new(Object.new) ref_2 = Ref::WeakReference.new(Object.new) assert queue.empty? assert_equal 0, queue.size queue.push(ref_1) queue.push(ref_2) assert !queue.empty? assert_equal 2, queue.size end def test_can_remove_references_as_a_queue queue = Ref::ReferenceQueue.new ref_1 = Ref::WeakReference.new(Object.new) ref_2 = Ref::WeakReference.new(Object.new) queue.push(ref_1) queue.push(ref_2) assert_equal ref_1, queue.shift assert_equal ref_2, queue.shift assert_nil queue.shift end def test_can_remove_references_as_a_stack queue = Ref::ReferenceQueue.new ref_1 = Ref::WeakReference.new(Object.new) ref_2 = Ref::WeakReference.new(Object.new) queue.push(ref_1) queue.push(ref_2) assert_equal ref_2, queue.pop assert_equal ref_1, queue.pop assert_nil queue.pop end def test_references_are_added_when_the_object_has_been_collected Ref::Mock.use do obj = Object.new ref = Ref::WeakReference.new(obj) queue = Ref::ReferenceQueue.new queue.monitor(ref) assert_nil queue.shift Ref::Mock.gc(obj) assert_equal ref, queue.shift end end def test_references_are_added_immediately_if_the_object_has_been_collected Ref::Mock.use do obj = Object.new ref = Ref::WeakReference.new(obj) Ref::Mock.gc(obj) queue = Ref::ReferenceQueue.new queue.monitor(ref) assert_equal ref, queue.shift end end end ref-1.0.2/test/test_helper.rb0000644000175000017500000000032212063250626015465 0ustar boutilboutilrequire 'test/unit' require File.expand_path("../../lib/ref", __FILE__) require File.expand_path("../reference_key_map_behavior", __FILE__) require File.expand_path("../reference_value_map_behavior", __FILE__) ref-1.0.2/test/soft_reference_test.rb0000644000175000017500000000322312063250626017202 0ustar boutilboutilrequire File.expand_path("../test_helper", __FILE__) class TestSoftReference < Test::Unit::TestCase def test_can_get_non_garbage_collected_objects obj = Object.new ref = Ref::SoftReference.new(obj) assert_equal obj, ref.object assert_equal obj.object_id, ref.referenced_object_id end def test_get_the_correct_object # Since we can't reliably control the garbage collector, this is a brute force test. # It might not always fail if the garbage collector and memory allocator don't # cooperate, but it should fail often enough on continuous integration to # hilite any problems. Set the environment variable QUICK_TEST to "true" if you # want to make the tests run quickly. id_to_ref = {} (ENV["QUICK_TEST"] == "true" ? 1000 : 100000).times do |i| obj = Object.new if id_to_ref.key?(obj.object_id) ref = id_to_ref[obj.object_id] if ref.object flunk "soft reference found with a live reference to an object that was not the one it was created with" break end end %w(Here are a bunch of objects that are allocated and can then be cleaned up by the garbage collector) id_to_ref[obj.object_id] = Ref::SoftReference.new(obj) if i % 1000 == 0 GC.start sleep(0.01) end end end def test_references_are_not_collected_immediately ref = Ref::SoftReference.new(Object.new) 9.times{arr = %w(allocate some memory on the heap); arr *= 100; GC.start} assert ref.object end def test_inspect ref = Ref::SoftReference.new(Object.new) assert ref.inspect GC.start GC.start assert ref.inspect end end ref-1.0.2/test/reference_value_map_behavior.rb0000644000175000017500000000722012063250626021021 0ustar boutilboutilmodule ReferenceValueMapBehavior def test_keeps_entries_with_strong_references Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" hash["key 1"] = value_1 hash["key 2"] = value_2 assert_equal value_1, hash["key 1"] assert_equal value_2, hash["key 2"] end end def test_removes_entries_that_have_been_garbage_collected Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" hash["key 1"] = value_1 hash["key 2"] = value_2 assert_equal "value 2", hash["key 2"] assert_equal "value 1", hash["key 1"] Ref::Mock.gc(value_2) assert_nil hash["key 2"] assert_equal value_1, hash["key 1"] end end def test_can_clear_the_map Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" hash["key 1"] = value_1 hash["key 2"] = value_2 hash.clear assert_nil hash["key 1"] assert_nil hash["key 2"] end end def test_can_delete_entries Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" hash["key 1"] = value_1 hash["key 2"] = value_2 Ref::Mock.gc(value_2) assert_nil hash.delete("key 2") assert_equal value_1, hash.delete("key 1") assert_nil hash["key 1"] end end def test_can_merge_in_another_hash Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" value_3 = "value 3" hash["key 1"] = value_1 hash["key 2"] = value_2 hash.merge!("key 3" => value_3) assert_equal "value 2", hash["key 2"] assert_equal value_1, hash["key 1"] Ref::Mock.gc(value_2) assert_nil hash["key 2"] assert_equal value_1, hash["key 1"] assert_equal value_3, hash["key 3"] end end def test_can_get_all_values Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" value_3 = "value 3" hash["key 1"] = value_1 hash["key 2"] = value_2 hash["key 3"] = value_3 assert_equal ["value 1", "value 2", "value 3"].sort, hash.values.sort Ref::Mock.gc(value_2) assert_equal ["value 1", "value 3"].sort, hash.values.sort end end def test_can_turn_into_an_array Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" value_3 = "value 3" hash["key 1"] = value_1 hash["key 2"] = value_2 hash["key 3"] = value_3 order = lambda{|a,b| a.first <=> b.first} assert_equal [["key 1", "value 1"], ["key 2", "value 2"], ["key 3", "value 3"]].sort(&order), hash.to_a.sort(&order) Ref::Mock.gc(value_2) assert_equal [["key 1", "value 1"], ["key 3", "value 3"]].sort(&order), hash.to_a.sort(&order) end end def test_can_iterate_over_all_entries Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" value_3 = "value 3" hash["key 1"] = value_1 hash["key 2"] = value_2 hash["key 3"] = value_3 keys = [] values = [] hash.each{|k,v| keys << k; values << v} assert_equal ["key 1", "key 2", "key 3"], keys.sort assert_equal ["value 1", "value 2", "value 3"], values.sort Ref::Mock.gc(value_2) keys = [] values = [] hash.each{|k,v| keys << k; values << v} assert_equal ["key 1", "key 3"], keys.sort assert_equal ["value 1", "value 3"], values.sort end end def test_inspect Ref::Mock.use do hash = map_class.new hash["key 1"] = "value 1" assert hash.inspect end end end ref-1.0.2/test/weak_value_map_test.rb0000644000175000017500000000036112063250626017171 0ustar boutilboutilrequire File.expand_path("../test_helper", __FILE__) class TestWeakValueMap < Test::Unit::TestCase include ReferenceValueMapBehavior def map_class Ref::WeakValueMap end def reference_class Ref::WeakReference end end ref-1.0.2/test/soft_value_map_test.rb0000644000175000017500000000036112063250626017215 0ustar boutilboutilrequire File.expand_path("../test_helper", __FILE__) class TestSoftValueMap < Test::Unit::TestCase include ReferenceValueMapBehavior def map_class Ref::SoftValueMap end def reference_class Ref::SoftReference end end ref-1.0.2/test/weak_reference_test.rbc0000644000175000017500000001012212063250626017315 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 63 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 7 45 8 9 43 10 43 11 65 49 12 3 13 99 12 7 13 12 7 14 12 65 12 49 15 4 15 49 13 0 15 2 11 I 6 I 0 I 0 I 0 n p 16 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path x 17 TestWeakReference x 4 Test n x 4 Unit x 8 TestCase x 10 open_class x 14 __class_init__ M 1 n n x 17 TestWeakReference i 44 5 66 99 7 0 7 1 65 67 49 2 0 49 3 4 15 99 7 4 7 5 65 67 49 2 0 49 3 4 15 99 7 6 7 7 65 67 49 2 0 49 3 4 11 I 5 I 0 I 0 I 0 n p 8 x 42 test_can_get_non_garbage_collected_objects M 1 n n x 42 test_can_get_non_garbage_collected_objects i 151 45 0 1 13 71 2 47 9 21 47 49 3 0 13 47 49 4 0 15 8 24 49 2 0 19 0 15 45 5 6 43 7 13 71 2 47 9 52 47 49 3 0 13 20 0 47 49 4 1 15 8 57 20 0 49 2 1 19 1 15 45 5 8 43 7 13 71 2 47 9 85 47 49 3 0 13 20 0 47 49 4 1 15 8 90 20 0 49 2 1 19 2 15 5 20 0 20 1 49 9 0 47 49 10 2 15 5 20 0 49 11 0 20 1 49 12 0 47 49 10 2 15 5 20 0 20 2 49 9 0 47 49 10 2 15 5 20 0 49 11 0 20 2 49 12 0 47 49 10 2 11 I 6 I 3 I 0 I 0 n p 13 x 6 Object n x 3 new x 8 allocate x 10 initialize x 3 Ref n x 13 WeakReference n x 6 object x 12 assert_equal x 9 object_id x 20 referenced_object_id p 17 I -1 I 5 I 0 I 6 I 1b I 7 I 3c I 8 I 5d I 9 I 6a I a I 7a I b I 87 I c I 97 x 59 /Users/bdurand/dev/projects/ref/test/weak_reference_test.rb p 3 x 3 obj x 5 ref_1 x 5 ref_2 x 17 method_visibility x 15 add_defn_method x 27 test_get_the_correct_object M 1 n n x 27 test_get_the_correct_object i 38 44 43 0 78 49 1 1 19 0 15 45 2 3 7 4 64 49 5 1 7 6 64 83 7 9 30 7 8 8 32 7 9 56 10 50 11 0 11 I 3 I 1 I 0 I 0 n p 12 x 4 Hash x 16 new_from_literal x 3 ENV n s 10 QUICK_TEST x 2 [] s 4 true x 2 == I 3e8 I 186a0 M 1 p 2 x 9 for_block t n x 27 test_get_the_correct_object i 219 57 19 0 15 45 0 1 13 71 2 47 9 25 47 49 3 0 13 47 49 4 0 15 8 28 49 2 0 19 1 15 21 1 0 20 1 49 5 0 49 6 1 9 81 21 1 0 20 1 49 5 0 49 7 1 19 2 15 20 2 49 8 0 9 78 5 7 9 64 47 49 10 1 15 1 33 8 79 1 8 82 1 15 7 11 64 7 12 64 7 13 64 7 14 64 7 15 64 7 16 64 7 17 64 7 12 64 7 18 64 7 19 64 7 20 64 7 21 64 7 22 64 7 23 64 7 24 64 7 25 64 7 26 64 7 27 64 7 28 64 35 19 15 21 1 0 20 1 49 5 0 45 29 30 43 31 13 71 2 47 9 176 47 49 3 0 13 20 1 47 49 4 1 15 8 181 20 1 49 2 1 13 18 3 49 32 2 15 15 20 0 7 33 49 34 1 78 83 35 9 217 45 36 37 49 38 0 15 5 7 39 47 49 40 1 8 218 1 11 I 17 I 3 I 1 I 1 n p 41 x 6 Object n x 3 new x 8 allocate x 10 initialize x 9 object_id x 4 key? x 2 [] x 6 object s 96 weak reference found with a live reference to an object that was not the one it was created with x 5 flunk s 4 Here s 3 are s 1 a s 5 bunch s 2 of s 7 objects s 4 that s 9 allocated s 3 and s 3 can s 4 then s 2 be s 7 cleaned s 2 up s 2 by s 3 the s 7 garbage s 9 collector x 3 Ref n x 13 WeakReference x 3 []= I 3e8 x 1 % x 2 == x 2 GC n x 5 start d +0.640000000000000013322676295501878485083580017089843750 -6 x 5 sleep p 31 I 0 I 16 I 4 I 17 I 1f I 18 I 2c I 19 I 3a I 1a I 41 I 1b I 4a I 1c I 4e I 1a I 51 I 18 I 53 I 1f I 8f I 20 I bd I 21 I c9 I 22 I d0 I 23 I d9 I 21 I db x 59 /Users/bdurand/dev/projects/ref/test/weak_reference_test.rb p 3 x 1 i x 3 obj x 3 ref x 5 times p 7 I -1 I f I 0 I 15 I a I 16 I 26 x 59 /Users/bdurand/dev/projects/ref/test/weak_reference_test.rb p 1 x 9 id_to_ref x 12 test_inspect M 1 n n x 12 test_inspect i 113 45 0 1 43 2 13 71 3 47 9 47 47 49 4 0 13 45 5 6 13 71 3 47 9 37 47 49 4 0 13 47 49 7 0 15 8 40 49 3 0 47 49 7 1 15 8 74 45 5 8 13 71 3 47 9 68 47 49 4 0 13 47 49 7 0 15 8 71 49 3 0 49 3 1 19 0 15 5 20 0 49 9 0 47 49 10 1 15 45 11 12 49 13 0 15 45 11 14 49 13 0 15 5 20 0 49 9 0 47 49 10 1 11 I 5 I 1 I 0 I 0 n p 15 x 3 Ref n x 13 WeakReference x 3 new x 8 allocate x 6 Object n x 10 initialize n x 7 inspect x 6 assert x 2 GC n x 5 start n p 13 I -1 I 28 I 0 I 29 I 4d I 2a I 58 I 2b I 5f I 2c I 66 I 2d I 71 x 59 /Users/bdurand/dev/projects/ref/test/weak_reference_test.rb p 1 x 3 ref p 7 I 2 I 5 I 10 I f I 1e I 28 I 2c x 59 /Users/bdurand/dev/projects/ref/test/weak_reference_test.rb p 0 x 13 attach_method p 7 I 0 I 1 I 9 I 2 I 1c I 4 I 3f x 59 /Users/bdurand/dev/projects/ref/test/weak_reference_test.rb p 0 ref-1.0.2/test/soft_key_map_test.rb0000644000175000017500000000035312063250626016672 0ustar boutilboutilrequire File.expand_path("../test_helper", __FILE__) class TestSoftKeyMap < Test::Unit::TestCase include ReferenceKeyMapBehavior def map_class Ref::SoftKeyMap end def reference_class Ref::SoftReference end end ref-1.0.2/test/weak_key_map_test.rb0000644000175000017500000000035312063250626016646 0ustar boutilboutilrequire File.expand_path("../test_helper", __FILE__) class TestWeakKeyMap < Test::Unit::TestCase include ReferenceKeyMapBehavior def map_class Ref::WeakKeyMap end def reference_class Ref::WeakReference end end ref-1.0.2/test/strong_reference_test.rbc0000644000175000017500000000360612063250626017713 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 63 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 7 45 8 9 43 10 43 11 65 49 12 3 13 99 12 7 13 12 7 14 12 65 12 49 15 4 15 49 13 0 15 2 11 I 6 I 0 I 0 I 0 n p 16 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path x 19 TestStrongReference x 4 Test n x 4 Unit x 8 TestCase x 10 open_class x 14 __class_init__ M 1 n n x 19 TestStrongReference i 30 5 66 99 7 0 7 1 65 67 49 2 0 49 3 4 15 99 7 4 7 5 65 67 49 2 0 49 3 4 11 I 5 I 0 I 0 I 0 n p 6 x 20 test_can_get_objects M 1 n n x 20 test_can_get_objects i 89 45 0 1 13 71 2 47 9 21 47 49 3 0 13 47 49 4 0 15 8 24 49 2 0 19 0 15 45 5 6 43 7 13 71 2 47 9 52 47 49 3 0 13 20 0 47 49 4 1 15 8 57 20 0 49 2 1 19 1 15 5 20 0 20 1 49 8 0 47 49 9 2 15 5 20 0 49 10 0 20 1 49 11 0 47 49 9 2 11 I 5 I 2 I 0 I 0 n p 12 x 6 Object n x 3 new x 8 allocate x 10 initialize x 3 Ref n x 15 StrongReference x 6 object x 12 assert_equal x 9 object_id x 20 referenced_object_id p 11 I -1 I 5 I 0 I 6 I 1b I 7 I 3c I 8 I 49 I 9 I 59 x 61 /Users/bdurand/dev/projects/ref/test/strong_reference_test.rb p 2 x 3 obj x 3 ref x 17 method_visibility x 15 add_defn_method x 12 test_inspect M 1 n n x 12 test_inspect i 88 45 0 1 43 2 13 71 3 47 9 47 47 49 4 0 13 45 5 6 13 71 3 47 9 37 47 49 4 0 13 47 49 7 0 15 8 40 49 3 0 47 49 7 1 15 8 74 45 5 8 13 71 3 47 9 68 47 49 4 0 13 47 49 7 0 15 8 71 49 3 0 49 3 1 19 0 15 5 20 0 49 9 0 47 49 10 1 11 I 5 I 1 I 0 I 0 n p 11 x 3 Ref n x 13 WeakReference x 3 new x 8 allocate x 6 Object n x 10 initialize n x 7 inspect x 6 assert p 7 I -1 I c I 0 I d I 4d I e I 58 x 61 /Users/bdurand/dev/projects/ref/test/strong_reference_test.rb p 1 x 3 ref p 5 I 2 I 5 I 10 I c I 1e x 61 /Users/bdurand/dev/projects/ref/test/strong_reference_test.rb p 0 x 13 attach_method p 7 I 0 I 1 I 9 I 2 I 1c I 4 I 3f x 61 /Users/bdurand/dev/projects/ref/test/strong_reference_test.rb p 0 ref-1.0.2/test/strong_reference_test.rb0000644000175000017500000000060112063250626017540 0ustar boutilboutilrequire File.expand_path("../test_helper", __FILE__) class TestStrongReference < Test::Unit::TestCase def test_can_get_objects obj = Object.new ref = Ref::StrongReference.new(obj) assert_equal obj, ref.object assert_equal obj.object_id, ref.referenced_object_id end def test_inspect ref = Ref::WeakReference.new(Object.new) assert ref.inspect end end ref-1.0.2/test/reference_value_map_behavior.rbc0000644000175000017500000002755512063250626021201 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 56 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 7 65 49 8 2 13 99 12 7 9 12 7 10 12 65 12 49 11 4 15 49 9 0 15 2 11 I 6 I 0 I 0 I 0 n p 12 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path x 25 ReferenceValueMapBehavior x 11 open_module x 15 __module_init__ M 1 n n x 25 ReferenceValueMapBehavior i 128 5 66 99 7 0 7 1 65 67 49 2 0 49 3 4 15 99 7 4 7 5 65 67 49 2 0 49 3 4 15 99 7 6 7 7 65 67 49 2 0 49 3 4 15 99 7 8 7 9 65 67 49 2 0 49 3 4 15 99 7 10 7 11 65 67 49 2 0 49 3 4 15 99 7 12 7 13 65 67 49 2 0 49 3 4 15 99 7 14 7 15 65 67 49 2 0 49 3 4 15 99 7 16 7 17 65 67 49 2 0 49 3 4 15 99 7 18 7 19 65 67 49 2 0 49 3 4 11 I 5 I 0 I 0 I 0 n p 20 x 41 test_keeps_entries_with_strong_references M 1 n n x 41 test_keeps_entries_with_strong_references i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 41 test_keeps_entries_with_strong_references i 101 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 20 0 7 6 64 20 1 13 18 3 49 7 2 15 15 20 0 7 8 64 20 2 13 18 3 49 7 2 15 15 5 20 1 20 0 7 6 64 49 9 1 47 49 10 2 15 5 20 2 20 0 7 8 64 49 9 1 47 49 10 2 11 I 8 I 3 I 0 I 0 I -2 p 11 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 5 key 1 x 3 []= s 5 key 2 x 2 [] x 12 assert_equal p 15 I 0 I 7 I 1b I 8 I 21 I 9 I 27 I a I 36 I b I 45 I c I 55 I d I 65 x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 3 x 4 hash x 7 value_1 x 7 value_2 x 3 use p 5 I -1 I 5 I 0 I 6 I b x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 x 17 method_visibility x 15 add_defn_method x 53 test_removes_entries_that_have_been_garbage_collected M 1 n n x 53 test_removes_entries_that_have_been_garbage_collected i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 53 test_removes_entries_that_have_been_garbage_collected i 144 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 20 0 7 6 64 20 1 13 18 3 49 7 2 15 15 20 0 7 8 64 20 2 13 18 3 49 7 2 15 15 5 7 5 64 20 0 7 8 64 49 9 1 47 49 10 2 15 5 7 4 64 20 0 7 6 64 49 9 1 47 49 10 2 15 45 11 12 43 13 20 2 49 14 1 15 5 20 0 7 8 64 49 9 1 47 49 15 1 15 5 20 1 20 0 7 6 64 49 9 1 47 49 10 2 11 I 8 I 3 I 0 I 0 I -2 p 16 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 5 key 1 x 3 []= s 5 key 2 x 2 [] x 12 assert_equal x 3 Ref n x 4 Mock x 2 gc x 10 assert_nil p 21 I 0 I 13 I 1b I 14 I 21 I 15 I 27 I 16 I 36 I 17 I 45 I 18 I 56 I 19 I 67 I 1a I 72 I 1b I 80 I 1c I 90 x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 3 x 4 hash x 7 value_1 x 7 value_2 x 3 use p 5 I -1 I 11 I 0 I 12 I b x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 x 22 test_can_clear_the_map M 1 n n x 22 test_can_clear_the_map i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 22 test_can_clear_the_map i 103 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 20 0 7 6 64 20 1 13 18 3 49 7 2 15 15 20 0 7 8 64 20 2 13 18 3 49 7 2 15 15 20 0 49 9 0 15 5 20 0 7 6 64 49 10 1 47 49 11 1 15 5 20 0 7 8 64 49 10 1 47 49 11 1 11 I 8 I 3 I 0 I 0 I -2 p 12 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 5 key 1 x 3 []= s 5 key 2 x 5 clear x 2 [] x 10 assert_nil p 17 I 0 I 22 I 1b I 23 I 21 I 24 I 27 I 25 I 36 I 26 I 45 I 27 I 4b I 28 I 59 I 29 I 67 x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 3 x 4 hash x 7 value_1 x 7 value_2 x 3 use p 5 I -1 I 20 I 0 I 21 I b x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 x 23 test_can_delete_entries M 1 n n x 23 test_can_delete_entries i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 23 test_can_delete_entries i 124 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 20 0 7 6 64 20 1 13 18 3 49 7 2 15 15 20 0 7 8 64 20 2 13 18 3 49 7 2 15 15 45 9 10 43 11 20 2 49 12 1 15 5 20 0 7 8 64 49 13 1 47 49 14 1 15 5 20 1 20 0 7 6 64 49 13 1 47 49 15 2 15 5 20 0 7 6 64 49 16 1 47 49 14 1 11 I 8 I 3 I 0 I 0 I -2 p 17 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 5 key 1 x 3 []= s 5 key 2 x 3 Ref n x 4 Mock x 2 gc x 6 delete x 10 assert_nil x 12 assert_equal x 2 [] p 19 I 0 I 2f I 1b I 30 I 21 I 31 I 27 I 32 I 36 I 33 I 45 I 34 I 50 I 35 I 5e I 36 I 6e I 37 I 7c x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 3 x 4 hash x 7 value_1 x 7 value_2 x 3 use p 5 I -1 I 2d I 0 I 2e I b x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 x 30 test_can_merge_in_another_hash M 1 n n x 30 test_can_merge_in_another_hash i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 30 test_can_merge_in_another_hash i 188 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 7 6 64 19 3 15 20 0 7 7 64 20 1 13 18 3 49 8 2 15 15 20 0 7 9 64 20 2 13 18 3 49 8 2 15 15 20 0 44 43 10 79 49 11 1 13 7 12 64 20 3 49 8 2 15 49 13 1 15 5 7 5 64 20 0 7 9 64 49 14 1 47 49 15 2 15 5 20 1 20 0 7 7 64 49 14 1 47 49 15 2 15 45 16 17 43 18 20 2 49 19 1 15 5 20 0 7 9 64 49 14 1 47 49 20 1 15 5 20 1 20 0 7 7 64 49 14 1 47 49 15 2 15 5 20 3 20 0 7 12 64 49 14 1 47 49 15 2 11 I a I 4 I 0 I 0 I -2 p 21 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 7 value 3 s 5 key 1 x 3 []= s 5 key 2 x 4 Hash x 16 new_from_literal s 5 key 3 x 6 merge! x 2 [] x 12 assert_equal x 3 Ref n x 4 Mock x 2 gc x 10 assert_nil p 27 I 0 I 3d I 1b I 3e I 21 I 3f I 27 I 40 I 2d I 41 I 3c I 42 I 4b I 43 I 62 I 44 I 73 I 45 I 83 I 46 I 8e I 47 I 9c I 48 I ac I 49 I bc x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 4 x 4 hash x 7 value_1 x 7 value_2 x 7 value_3 x 3 use p 5 I -1 I 3b I 0 I 3c I b x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 x 23 test_can_get_all_values M 1 n n x 23 test_can_get_all_values i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 23 test_can_get_all_values i 154 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 7 6 64 19 3 15 20 0 7 7 64 20 1 13 18 3 49 8 2 15 15 20 0 7 9 64 20 2 13 18 3 49 8 2 15 15 20 0 7 10 64 20 3 13 18 3 49 8 2 15 15 5 7 4 64 7 5 64 7 6 64 35 3 49 11 0 20 0 49 12 0 49 11 0 47 49 13 2 15 45 14 15 43 16 20 2 49 17 1 15 5 7 4 64 7 6 64 35 2 49 11 0 20 0 49 12 0 49 11 0 47 49 13 2 11 I 9 I 4 I 0 I 0 I -2 p 18 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 7 value 3 s 5 key 1 x 3 []= s 5 key 2 s 5 key 3 x 4 sort x 6 values x 12 assert_equal x 3 Ref n x 4 Mock x 2 gc p 21 I 0 I 4f I 1b I 50 I 21 I 51 I 27 I 52 I 2d I 53 I 3c I 54 I 4b I 55 I 5a I 56 I 76 I 57 I 81 I 58 I 9a x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 4 x 4 hash x 7 value_1 x 7 value_2 x 7 value_3 x 3 use p 5 I -1 I 4d I 0 I 4e I b x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 x 27 test_can_turn_into_an_array M 1 n n x 27 test_can_turn_into_an_array i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 27 test_can_turn_into_an_array i 241 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 7 6 64 19 3 15 20 0 7 7 64 20 1 13 18 3 49 8 2 15 15 20 0 7 9 64 20 2 13 18 3 49 8 2 15 15 20 0 7 10 64 20 3 13 18 3 49 8 2 15 15 5 56 11 47 50 12 0 19 4 15 5 7 7 64 7 4 64 35 2 7 9 64 7 5 64 35 2 7 10 64 7 6 64 35 2 35 3 20 4 13 70 10 140 44 43 13 12 49 14 1 50 15 0 20 0 49 16 0 20 4 13 70 10 161 44 43 13 12 49 14 1 50 15 0 47 49 17 2 15 45 18 19 43 20 20 2 49 21 1 15 5 7 7 64 7 4 64 35 2 7 10 64 7 6 64 35 2 35 2 20 4 13 70 10 212 44 43 13 12 49 14 1 50 15 0 20 0 49 16 0 20 4 13 70 10 233 44 43 13 12 49 14 1 50 15 0 47 49 17 2 11 I b I 5 I 0 I 0 I -2 p 22 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 7 value 3 s 5 key 1 x 3 []= s 5 key 2 s 5 key 3 M 1 p 2 x 9 for_block t n x 27 test_can_turn_into_an_array i 24 58 37 19 0 15 37 19 1 15 15 20 0 49 0 0 20 1 49 0 0 49 1 1 11 I 5 I 2 I 2 I 2 n p 2 x 5 first x 3 <=> p 3 I 0 I 65 I 18 x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 2 x 1 a x 1 b x 6 lambda x 4 Proc x 14 __from_block__ x 4 sort x 4 to_a x 12 assert_equal x 3 Ref n x 4 Mock x 2 gc p 23 I 0 I 5e I 1b I 5f I 21 I 60 I 27 I 61 I 2d I 62 I 3c I 63 I 4b I 64 I 5a I 65 I 64 I 66 I a9 I 67 I b4 I 68 I f1 x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 5 x 4 hash x 7 value_1 x 7 value_2 x 7 value_3 x 5 order x 3 use p 5 I -1 I 5c I 0 I 5d I b x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 x 33 test_can_iterate_over_all_entries M 1 n n x 33 test_can_iterate_over_all_entries i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 33 test_can_iterate_over_all_entries i 219 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 7 4 64 19 1 15 7 5 64 19 2 15 7 6 64 19 3 15 20 0 7 7 64 20 1 13 18 3 49 8 2 15 15 20 0 7 9 64 20 2 13 18 3 49 8 2 15 15 20 0 7 10 64 20 3 13 18 3 49 8 2 15 15 35 0 19 4 15 35 0 19 5 15 20 0 56 11 50 12 0 15 5 7 7 64 7 9 64 7 10 64 35 3 20 4 49 13 0 47 49 14 2 15 5 7 4 64 7 5 64 7 6 64 35 3 20 5 49 13 0 47 49 14 2 15 45 15 16 43 17 20 2 49 18 1 15 35 0 19 4 15 35 0 19 5 15 20 0 56 19 50 12 0 15 5 7 7 64 7 10 64 35 2 20 4 49 13 0 47 49 14 2 15 5 7 4 64 7 6 64 35 2 20 5 49 13 0 47 49 14 2 11 I b I 6 I 0 I 0 I -2 p 20 x 9 map_class x 3 new x 8 allocate x 10 initialize s 7 value 1 s 7 value 2 s 7 value 3 s 5 key 1 x 3 []= s 5 key 2 s 5 key 3 M 1 p 2 x 9 for_block t n x 33 test_can_iterate_over_all_entries i 28 58 37 19 0 15 37 19 1 15 15 21 1 4 20 0 49 0 1 15 21 1 5 20 1 49 0 1 11 I 5 I 2 I 2 I 2 n p 1 x 2 << p 3 I 0 I 77 I 1c x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 2 x 1 k x 1 v x 4 each x 4 sort x 12 assert_equal x 3 Ref n x 4 Mock x 2 gc M 1 p 2 x 9 for_block t n x 33 test_can_iterate_over_all_entries i 28 58 37 19 0 15 37 19 1 15 15 21 1 4 20 0 49 0 1 15 21 1 5 20 1 49 0 1 11 I 5 I 2 I 2 I 2 n p 1 x 2 << p 3 I 0 I 7d I 1c x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 2 x 1 k x 1 v p 37 I 0 I 6e I 1b I 6f I 21 I 70 I 27 I 71 I 2d I 72 I 3c I 73 I 4b I 74 I 5a I 75 I 5f I 76 I 64 I 77 I 6c I 78 I 82 I 79 I 98 I 7a I a3 I 7b I a8 I 7c I ad I 7d I b5 I 7e I c8 I 7f I db x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 6 x 4 hash x 7 value_1 x 7 value_2 x 7 value_3 x 4 keys x 6 values x 3 use p 5 I -1 I 6c I 0 I 6d I b x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 x 12 test_inspect M 1 n n x 12 test_inspect i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 12 test_inspect i 54 5 48 0 13 71 1 47 9 21 47 49 2 0 13 47 49 3 0 15 8 24 49 1 0 19 0 15 20 0 7 4 64 7 5 64 13 18 3 49 6 2 15 15 5 20 0 49 7 0 47 49 8 1 11 I 6 I 1 I 0 I 0 I -2 p 9 x 9 map_class x 3 new x 8 allocate x 10 initialize s 5 key 1 s 7 value 1 x 3 []= x 7 inspect x 6 assert p 7 I 0 I 85 I 1b I 86 I 2b I 87 I 36 x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 1 x 4 hash x 3 use p 5 I -1 I 83 I 0 I 84 I b x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 p 19 I 2 I 5 I 10 I 11 I 1e I 20 I 2c I 2d I 3a I 3b I 48 I 4d I 56 I 5c I 64 I 6c I 72 I 83 I 80 x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 x 13 attach_method p 7 I 0 I 1 I 9 I 2 I 1c I 4 I 38 x 68 /Users/bdurand/dev/projects/ref/test/reference_value_map_behavior.rb p 0 ref-1.0.2/test/reference_queue_test.rbc0000644000175000017500000001454512063250626017527 0ustar boutilboutil!RBIX 0 x M 1 n n x 10 __script__ i 63 5 7 0 64 47 49 1 1 15 5 45 2 3 7 4 64 65 49 5 0 49 6 2 47 49 1 1 15 99 7 7 45 8 9 43 10 43 11 65 49 12 3 13 99 12 7 13 12 7 14 12 65 12 49 15 4 15 49 13 0 15 2 11 I 6 I 0 I 0 I 0 n p 16 s 9 test/unit x 7 require x 4 File n s 13 ../../lib/ref x 11 active_path x 11 expand_path x 18 TestReferenceQueue x 4 Test n x 4 Unit x 8 TestCase x 10 open_class x 14 __class_init__ M 1 n n x 18 TestReferenceQueue i 72 5 66 99 7 0 7 1 65 67 49 2 0 49 3 4 15 99 7 4 7 5 65 67 49 2 0 49 3 4 15 99 7 6 7 7 65 67 49 2 0 49 3 4 15 99 7 8 7 9 65 67 49 2 0 49 3 4 15 99 7 10 7 11 65 67 49 2 0 49 3 4 11 I 5 I 0 I 0 I 0 n p 12 x 23 test_can_add_references M 1 n n x 23 test_can_add_references i 251 45 0 1 43 2 13 71 3 47 9 23 47 49 4 0 13 47 49 5 0 15 8 26 49 3 0 19 0 15 45 0 6 43 7 13 71 3 47 9 76 47 49 4 0 13 45 8 9 13 71 3 47 9 66 47 49 4 0 13 47 49 5 0 15 8 69 49 3 0 47 49 5 1 15 8 103 45 8 10 13 71 3 47 9 97 47 49 4 0 13 47 49 5 0 15 8 100 49 3 0 49 3 1 19 1 15 45 0 11 43 7 13 71 3 47 9 153 47 49 4 0 13 45 8 12 13 71 3 47 9 143 47 49 4 0 13 47 49 5 0 15 8 146 49 3 0 47 49 5 1 15 8 180 45 8 13 13 71 3 47 9 174 47 49 4 0 13 47 49 5 0 15 8 177 49 3 0 49 3 1 19 2 15 5 20 0 49 14 0 47 49 15 1 15 5 78 20 0 49 16 0 47 49 17 2 15 20 0 20 1 49 18 1 15 20 0 20 2 49 18 1 15 5 20 0 49 14 0 10 233 2 8 234 3 47 49 15 1 15 5 80 20 0 49 16 0 47 49 17 2 11 I 7 I 3 I 0 I 0 n p 19 x 3 Ref n x 14 ReferenceQueue x 3 new x 8 allocate x 10 initialize n x 13 WeakReference x 6 Object n n n n n x 6 empty? x 6 assert x 4 size x 12 assert_equal x 4 push p 21 I -1 I 5 I 0 I 6 I 1d I 7 I 6a I 8 I b7 I 9 I c2 I a I ce I b I d6 I c I de I d I ef I e I fb x 60 /Users/bdurand/dev/projects/ref/test/reference_queue_test.rb p 3 x 5 queue x 5 ref_1 x 5 ref_2 x 17 method_visibility x 15 add_defn_method x 37 test_can_remove_references_as_a_queue M 1 n n x 37 test_can_remove_references_as_a_queue i 236 45 0 1 43 2 13 71 3 47 9 23 47 49 4 0 13 47 49 5 0 15 8 26 49 3 0 19 0 15 45 0 6 43 7 13 71 3 47 9 76 47 49 4 0 13 45 8 9 13 71 3 47 9 66 47 49 4 0 13 47 49 5 0 15 8 69 49 3 0 47 49 5 1 15 8 103 45 8 10 13 71 3 47 9 97 47 49 4 0 13 47 49 5 0 15 8 100 49 3 0 49 3 1 19 1 15 45 0 11 43 7 13 71 3 47 9 153 47 49 4 0 13 45 8 12 13 71 3 47 9 143 47 49 4 0 13 47 49 5 0 15 8 146 49 3 0 47 49 5 1 15 8 180 45 8 13 13 71 3 47 9 174 47 49 4 0 13 47 49 5 0 15 8 177 49 3 0 49 3 1 19 2 15 20 0 20 1 49 14 1 15 20 0 20 2 49 14 1 15 5 20 1 20 0 49 15 0 47 49 16 2 15 5 20 2 20 0 49 15 0 47 49 16 2 15 5 20 0 49 15 0 47 49 17 1 11 I 7 I 3 I 0 I 0 n p 18 x 3 Ref n x 14 ReferenceQueue x 3 new x 8 allocate x 10 initialize n x 13 WeakReference x 6 Object n n n n n x 4 push x 5 shift x 12 assert_equal x 10 assert_nil p 19 I -1 I 11 I 0 I 12 I 1d I 13 I 6a I 14 I b7 I 15 I bf I 16 I c7 I 17 I d4 I 18 I e1 I 19 I ec x 60 /Users/bdurand/dev/projects/ref/test/reference_queue_test.rb p 3 x 5 queue x 5 ref_1 x 5 ref_2 x 37 test_can_remove_references_as_a_stack M 1 n n x 37 test_can_remove_references_as_a_stack i 236 45 0 1 43 2 13 71 3 47 9 23 47 49 4 0 13 47 49 5 0 15 8 26 49 3 0 19 0 15 45 0 6 43 7 13 71 3 47 9 76 47 49 4 0 13 45 8 9 13 71 3 47 9 66 47 49 4 0 13 47 49 5 0 15 8 69 49 3 0 47 49 5 1 15 8 103 45 8 10 13 71 3 47 9 97 47 49 4 0 13 47 49 5 0 15 8 100 49 3 0 49 3 1 19 1 15 45 0 11 43 7 13 71 3 47 9 153 47 49 4 0 13 45 8 12 13 71 3 47 9 143 47 49 4 0 13 47 49 5 0 15 8 146 49 3 0 47 49 5 1 15 8 180 45 8 13 13 71 3 47 9 174 47 49 4 0 13 47 49 5 0 15 8 177 49 3 0 49 3 1 19 2 15 20 0 20 1 49 14 1 15 20 0 20 2 49 14 1 15 5 20 2 20 0 49 15 0 47 49 16 2 15 5 20 1 20 0 49 15 0 47 49 16 2 15 5 20 0 49 15 0 47 49 17 1 11 I 7 I 3 I 0 I 0 n p 18 x 3 Ref n x 14 ReferenceQueue x 3 new x 8 allocate x 10 initialize n x 13 WeakReference x 6 Object n n n n n x 4 push x 3 pop x 12 assert_equal x 10 assert_nil p 19 I -1 I 1c I 0 I 1d I 1d I 1e I 6a I 1f I b7 I 20 I bf I 21 I c7 I 22 I d4 I 23 I e1 I 24 I ec x 60 /Users/bdurand/dev/projects/ref/test/reference_queue_test.rb p 3 x 5 queue x 5 ref_1 x 5 ref_2 x 60 test_references_are_added_when_the_object_has_been_collected M 1 n n x 60 test_references_are_added_when_the_object_has_been_collected i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 60 test_references_are_added_when_the_object_has_been_collected i 132 45 0 1 13 71 2 47 9 21 47 49 3 0 13 47 49 4 0 15 8 24 49 2 0 19 0 15 45 5 6 43 7 13 71 2 47 9 52 47 49 3 0 13 20 0 47 49 4 1 15 8 57 20 0 49 2 1 19 1 15 45 5 8 43 9 13 71 2 47 9 83 47 49 3 0 13 47 49 4 0 15 8 86 49 2 0 19 2 15 20 2 20 1 49 10 1 15 5 20 2 49 11 0 47 49 12 1 15 45 5 13 43 14 20 0 49 15 1 15 5 20 1 20 2 49 11 0 47 49 16 2 11 I 7 I 3 I 0 I 0 I -2 p 17 x 6 Object n x 3 new x 8 allocate x 10 initialize x 3 Ref n x 13 WeakReference n x 14 ReferenceQueue x 7 monitor x 5 shift x 10 assert_nil n x 4 Mock x 2 gc x 12 assert_equal p 15 I 0 I 29 I 1b I 2a I 3c I 2b I 59 I 2c I 61 I 2d I 6c I 2e I 77 I 2f I 84 x 60 /Users/bdurand/dev/projects/ref/test/reference_queue_test.rb p 3 x 3 obj x 3 ref x 5 queue x 3 use p 5 I -1 I 27 I 0 I 28 I b x 60 /Users/bdurand/dev/projects/ref/test/reference_queue_test.rb p 0 x 70 test_references_are_added_immediately_if_the_object_has_been_collected M 1 n n x 70 test_references_are_added_immediately_if_the_object_has_been_collected i 11 45 0 1 43 2 56 3 50 4 0 11 I 2 I 0 I 0 I 0 n p 5 x 3 Ref n x 4 Mock M 1 p 2 x 9 for_block t n x 70 test_references_are_added_immediately_if_the_object_has_been_collected i 121 45 0 1 13 71 2 47 9 21 47 49 3 0 13 47 49 4 0 15 8 24 49 2 0 19 0 15 45 5 6 43 7 13 71 2 47 9 52 47 49 3 0 13 20 0 47 49 4 1 15 8 57 20 0 49 2 1 19 1 15 45 5 8 43 9 20 0 49 10 1 15 45 5 11 43 12 13 71 2 47 9 94 47 49 3 0 13 47 49 4 0 15 8 97 49 2 0 19 2 15 20 2 20 1 49 13 1 15 5 20 1 20 2 49 14 0 47 49 15 2 11 I 7 I 3 I 0 I 0 I -2 p 16 x 6 Object n x 3 new x 8 allocate x 10 initialize x 3 Ref n x 13 WeakReference n x 4 Mock x 2 gc n x 14 ReferenceQueue x 7 monitor x 5 shift x 12 assert_equal p 13 I 0 I 35 I 1b I 36 I 3c I 37 I 47 I 38 I 64 I 39 I 6c I 3a I 79 x 60 /Users/bdurand/dev/projects/ref/test/reference_queue_test.rb p 3 x 3 obj x 3 ref x 5 queue x 3 use p 5 I -1 I 33 I 0 I 34 I b x 60 /Users/bdurand/dev/projects/ref/test/reference_queue_test.rb p 0 p 11 I 2 I 5 I 10 I 11 I 1e I 1c I 2c I 27 I 3a I 33 I 48 x 60 /Users/bdurand/dev/projects/ref/test/reference_queue_test.rb p 0 x 13 attach_method p 7 I 0 I 1 I 9 I 2 I 1c I 4 I 3f x 60 /Users/bdurand/dev/projects/ref/test/reference_queue_test.rb p 0 ref-1.0.2/test/reference_key_map_behavior.rb0000644000175000017500000001004012063250626020467 0ustar boutilboutilmodule ReferenceKeyMapBehavior def test_uses_the_proper_references assert_equal reference_class, map_class.reference_class end def test_keeps_entries_with_strong_references Ref::Mock.use do hash = map_class.new key_1 = Object.new key_2 = Object.new hash[key_1] = "value 1" hash[key_2] = "value 2" assert_equal "value 1", hash[key_1] assert_equal "value 2", hash[key_2] end end def test_removes_entries_that_have_been_garbage_collected Ref::Mock.use do hash = map_class.new key_1 = Object.new key_2 = Object.new hash[key_1] = "value 1" hash[key_2] = "value 2" assert_equal "value 1", hash[key_1] assert_equal "value 2", hash[key_2] Ref::Mock.gc(key_2) assert_equal "value 1", hash[key_1] assert_nil hash[key_2] end end def test_can_clear_the_map Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" key_1 = Object.new key_2 = Object.new hash[key_1] = value_1 hash[key_2] = value_2 hash.clear assert_nil hash[key_1] assert_nil hash[key_2] end end def test_can_delete_entries Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" key_1 = Object.new key_2 = Object.new hash[key_1] = value_1 hash[key_2] = value_2 Ref::Mock.gc(key_2) assert_nil hash.delete(key_2) assert_equal value_1, hash.delete(key_1) assert_nil hash[key_1] end end def test_can_merge_in_another_hash Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" value_3 = "value 3" key_1 = Object.new key_2 = Object.new key_3 = Object.new hash[key_1] = value_1 hash[key_2] = value_2 hash.merge!(key_3 => value_3) assert_equal "value 2", hash[key_2] assert_equal value_1, hash[key_1] Ref::Mock.gc(key_2) assert_nil hash[key_2] assert_equal value_1, hash[key_1] assert_equal value_3, hash[key_3] end end def test_can_get_all_keys Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" value_3 = "value 3" key_1 = Object.new key_2 = Object.new key_3 = Object.new hash[key_1] = value_1 hash[key_2] = value_2 hash[key_3] = value_3 assert_equal [], [key_1, key_2, key_3] - hash.keys Ref::Mock.gc(key_2) assert_equal [key_2], [key_1, key_2, key_3] - hash.keys end end def test_can_turn_into_an_array Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" value_3 = "value 3" key_1 = Object.new key_2 = Object.new key_3 = Object.new hash[key_1] = value_1 hash[key_2] = value_2 hash[key_3] = value_3 order = lambda{|a,b| a.last <=> b.last} assert_equal [[key_1, "value 1"], [key_2, "value 2"], [key_3, "value 3"]].sort(&order), hash.to_a.sort(&order) Ref::Mock.gc(key_2) assert_equal [[key_1, "value 1"], [key_3, "value 3"]].sort(&order), hash.to_a.sort(&order) end end def test_can_iterate_over_all_entries Ref::Mock.use do hash = map_class.new value_1 = "value 1" value_2 = "value 2" value_3 = "value 3" key_1 = Object.new key_2 = Object.new key_3 = Object.new hash[key_1] = value_1 hash[key_2] = value_2 hash[key_3] = value_3 keys = [] values = [] hash.each{|k,v| keys << k; values << v} assert_equal [], [key_1, key_2, key_3] - keys assert_equal ["value 1", "value 2", "value 3"], values.sort Ref::Mock.gc(key_2) keys = [] values = [] hash.each{|k,v| keys << k; values << v} assert_equal [key_2], [key_1, key_2, key_3] - keys assert_equal ["value 1", "value 3"], values.sort end end def test_inspect Ref::Mock.use do hash = map_class.new hash[Object.new] = "value 1" assert hash.inspect end end end ref-1.0.2/lib/0000755000175000017500000000000012063250626012414 5ustar boutilboutilref-1.0.2/lib/ref.rb0000644000175000017500000000454412063250626013524 0ustar boutilboutilmodule Ref autoload :AbstractReferenceValueMap, File.join(File.dirname(__FILE__), "ref", "abstract_reference_value_map.rb") autoload :AbstractReferenceKeyMap, File.join(File.dirname(__FILE__), "ref", "abstract_reference_key_map.rb") autoload :Mock, File.join(File.dirname(__FILE__), "ref", "mock.rb") autoload :Reference, File.join(File.dirname(__FILE__), "ref", "reference.rb") autoload :ReferenceQueue, File.join(File.dirname(__FILE__), "ref", "reference_queue.rb") autoload :SafeMonitor, File.join(File.dirname(__FILE__), "ref", "safe_monitor.rb") autoload :SoftKeyMap, File.join(File.dirname(__FILE__), "ref", "soft_key_map.rb") autoload :SoftValueMap, File.join(File.dirname(__FILE__), "ref", "soft_value_map.rb") autoload :StrongReference, File.join(File.dirname(__FILE__), "ref", "strong_reference.rb") autoload :WeakKeyMap, File.join(File.dirname(__FILE__), "ref", "weak_key_map.rb") autoload :WeakValueMap, File.join(File.dirname(__FILE__), "ref", "weak_value_map.rb") # Set the best implementation for weak references based on the runtime. if defined?(RUBY_PLATFORM) && RUBY_PLATFORM == 'java' # Use native Java references begin $LOAD_PATH.unshift(File.dirname(__FILE__)) require 'org/jruby/ext/ref/references' ensure $LOAD_PATH.shift if $LOAD_PATH.first == File.dirname(__FILE__) end else autoload :SoftReference, File.join(File.dirname(__FILE__), "ref", "soft_reference.rb") if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ironruby' # IronRuby has it's own implementation of weak references. autoload :WeakReference, File.join(File.dirname(__FILE__), "ref", "weak_reference", "iron_ruby.rb") elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' # If using Rubinius set the implementation to use WeakRef since it is very efficient and using finalizers is not. autoload :WeakReference, File.join(File.dirname(__FILE__), "ref", "weak_reference", "weak_ref.rb") elsif defined?(ObjectSpace._id2ref) # If ObjectSpace can lookup objects from their object_id, then use the pure ruby implementation. autoload :WeakReference, File.join(File.dirname(__FILE__), "ref", "weak_reference", "pure_ruby.rb") else # Otherwise, wrap the standard library WeakRef class autoload :WeakReference, File.join(File.dirname(__FILE__), "ref", "weak_reference", "weak_ref.rb") end end end ref-1.0.2/lib/org/0000755000175000017500000000000012063250626013203 5ustar boutilboutilref-1.0.2/lib/org/jruby/0000755000175000017500000000000012063250626014336 5ustar boutilboutilref-1.0.2/lib/org/jruby/ext/0000755000175000017500000000000012063250626015136 5ustar boutilboutilref-1.0.2/lib/org/jruby/ext/ref/0000755000175000017500000000000012063250626015712 5ustar boutilboutilref-1.0.2/lib/ref/0000755000175000017500000000000012063250626013170 5ustar boutilboutilref-1.0.2/lib/ref/soft_key_map.rb0000644000175000017500000000211112063250626016170 0ustar boutilboutilmodule Ref # Implementation of a map in which only softly referenced keys are kept to the map values. # This allows the garbage collector to reclaim these objects if the only reference to them # is the soft reference in the map. # # This is often useful for cache implementations since the map can be allowed to grow # without bound and the garbage collector can be relied on to clean it up as necessary. # One must be careful, though, when accessing entries since they can be collected at # any time until there is a strong reference to the key. # # === Example usage: # # cache = Ref::SoftKeyMap.new # obj = MyObject.find_by_whatever # obj_info = Service.lookup_object_info(obj) # cache[obj] = Service.lookup_object_info(obj) # cache[obj] # The values looked up from the service # obj = nil # ObjectSpace.garbage_collect # cache.keys # empty array since the keys and values have been reclaimed # # See AbstractReferenceKeyMap for details. class SoftKeyMap < AbstractReferenceKeyMap self.reference_class = SoftReference end end ref-1.0.2/lib/ref/weak_key_map.rb0000644000175000017500000000211112063250626016144 0ustar boutilboutilmodule Ref # Implementation of a map in which only weakly referenced keys are kept to the map values. # This allows the garbage collector to reclaim these objects if the only reference to them # is the weak reference in the map. # # This is often useful for cache implementations since the map can be allowed to grow # without bound and the garbage collector can be relied on to clean it up as necessary. # One must be careful, though, when accessing entries since they can be collected at # any time until there is a strong reference to the key. # # === Example usage: # # cache = Ref::WeakKeyMap.new # obj = MyObject.find_by_whatever # obj_info = Service.lookup_object_info(obj) # cache[obj] = Service.lookup_object_info(obj) # cache[obj] # The values looked up from the service # obj = nil # ObjectSpace.garbage_collect # cache.keys # empty array since the keys and values have been reclaimed # # See AbstractReferenceKeyMap for details. class WeakKeyMap < AbstractReferenceKeyMap self.reference_class = WeakReference end end ref-1.0.2/lib/ref/weak_reference/0000755000175000017500000000000012063250626016135 5ustar boutilboutilref-1.0.2/lib/ref/weak_reference/weak_ref.rb0000644000175000017500000000120212063250626020240 0ustar boutilboutilrequire 'weakref' module Ref class WeakReference < Reference # This implementation of a weak reference simply wraps the standard WeakRef implementation # that comes with the Ruby standard library. def initialize(obj) #:nodoc: @referenced_object_id = obj.__id__ @ref = ::WeakRef.new(obj) end def object #:nodoc: @ref.__getobj__ rescue => e # Jruby implementation uses RefError while MRI uses WeakRef::RefError if (defined?(RefError) && e.is_a?(RefError)) || (defined?(::WeakRef::RefError) && e.is_a?(::WeakRef::RefError)) nil else raise e end end end end ref-1.0.2/lib/ref/weak_reference/pure_ruby.rb0000644000175000017500000000640212063250626020500 0ustar boutilboutilmodule Ref # This is a pure ruby implementation of a weak reference. It is much more # efficient than the bundled WeakRef implementation because it does not # subclass Delegator which is very heavy to instantiate and utilizes a # fair amount of memory under Ruby 1.8. class WeakReference < Reference class ReferencePointer def initialize(object) @referenced_object_id = object.__id__ add_backreference(object) end def cleanup obj = ObjectSpace._id2ref(@referenced_object_id) rescue nil remove_backreference(obj) if obj end def object obj = ObjectSpace._id2ref(@referenced_object_id) obj if verify_backreferences(obj) rescue RangeError nil end private # Verify that the object is the same one originally set for the weak reference. def verify_backreferences(obj) #:nodoc: backreferences = obj.instance_variable_get(:@__weak_backreferences__) if obj.instance_variable_defined?(:@__weak_backreferences__) backreferences && backreferences.include?(object_id) end # Add a backreference to the object. def add_backreference(obj) #:nodoc: backreferences = obj.instance_variable_get(:@__weak_backreferences__) if obj.instance_variable_defined?(:@__weak_backreferences__) unless backreferences backreferences = [] obj.instance_variable_set(:@__weak_backreferences__, backreferences) end backreferences << object_id end # Remove backreferences from the object. def remove_backreference(obj) #:nodoc: backreferences = obj.instance_variable_get(:@__weak_backreferences__) if obj.instance_variable_defined?(:@__weak_backreferences__) if backreferences backreferences.dup.delete(object_id) obj.send(:remove_instance_variable, :@__weak_backreferences__) if backreferences.empty? end end end @@weak_references = {} @@lock = SafeMonitor.new # Finalizer that cleans up weak references when references are destroyed. @@reference_finalizer = lambda do |object_id| @@lock.synchronize do reference_pointer = @@weak_references.delete(object_id) reference_pointer.cleanup if reference_pointer end end # Create a new weak reference to an object. The existence of the weak reference # will not prevent the garbage collector from reclaiming the referenced object. def initialize(obj) #:nodoc: @referenced_object_id = obj.__id__ @@lock.synchronize do @reference_pointer = ReferencePointer.new(obj) @@weak_references[self.object_id] = @reference_pointer end ObjectSpace.define_finalizer(self, @@reference_finalizer) end # Get the reference object. If the object has already been garbage collected, # then this method will return nil. def object #:nodoc: if @reference_pointer obj = @reference_pointer.object unless obj @@lock.synchronize do @@weak_references.delete(object_id) @reference_pointer.cleanup @reference_pointer = nil end end obj end end end end ref-1.0.2/lib/ref/weak_reference/iron_ruby.rb0000644000175000017500000000053212063250626020472 0ustar boutilboutilmodule Ref class WeakReference < Reference # This implementation of a weak reference wraps the System::WeakReference class # that comes with IronRuby. def initialize(obj) #:nodoc: @referenced_object_id = obj.__id__ @ref = ::System::WeakReference.new(obj) end def object #:nodoc: @ref.target end end end ref-1.0.2/lib/ref/abstract_reference_key_map.rb0000644000175000017500000000612212063250626021044 0ustar boutilboutilmodule Ref # Abstract base class for WeakKeyMap and SoftKeyMap. # # The classes behave similar to Hashes, but the keys in the map are not strong references # and can be reclaimed by the garbage collector at any time. When a key is reclaimed, the # map entry will be removed. class AbstractReferenceKeyMap class << self def reference_class=(klass) #:nodoc: @reference_class = klass end def reference_class #:nodoc: raise NotImplementedError.new("#{name} is an abstract class and cannot be instantiated") unless @reference_class @reference_class end end # Create a new map. Values added to the hash will be cleaned up by the garbage # collector if there are no other reference except in the map. def initialize @values = {} @references_to_keys_map = {} @lock = SafeMonitor.new @reference_cleanup = lambda{|object_id| remove_reference_to(object_id)} end # Get a value from the map by key. If the value has been reclaimed by the garbage # collector, this will return nil. def [](key) rkey = ref_key(key) @values[rkey] if rkey end # Add a key/value to the map. def []=(key, value) ObjectSpace.define_finalizer(key, @reference_cleanup) @lock.synchronize do @references_to_keys_map[key.__id__] = self.class.reference_class.new(key) @values[key.__id__] = value end end # Remove the value associated with the key from the map. def delete(key) rkey = ref_key(key) if rkey @references_to_keys_map.delete(rkey) @values.delete(rkey) else nil end end # Get an array of keys that have not yet been garbage collected. def keys @values.keys.collect{|rkey| @references_to_keys_map[rkey].object}.compact end # Turn the map into an arry of [key, value] entries. def to_a array = [] each{|k,v| array << [k, v]} array end # Iterate through all the key/value pairs in the map that have not been reclaimed # by the garbage collector. def each @references_to_keys_map.each do |rkey, ref| key = ref.object yield(key, @values[rkey]) if key end end # Clear the map of all key/value pairs. def clear @lock.synchronize do @values.clear @references_to_keys_map.clear end end # Merge the values from another hash into this map. def merge!(other_hash) other_hash.each do |key, value| self[key] = value end end def inspect live_entries = {} each do |key, value| live_entries[key] = value end live_entries.inspect end private def ref_key (key) ref = @references_to_keys_map[key.__id__] if ref && ref.object ref.referenced_object_id else nil end end def remove_reference_to(object_id) @lock.synchronize do @references_to_keys_map.delete(object_id) @values.delete(object_id) end end end end ref-1.0.2/lib/ref/soft_value_map.rb0000644000175000017500000000217012063250626016521 0ustar boutilboutilmodule Ref # Implementation of a map in which soft references are kept to the map values. # This allows the garbage collector to reclaim these objects if the # only reference to them is the soft reference in the map. # # This is often useful for cache implementations since the map can be allowed to grow # without bound and the garbage collector can be relied on to clean it up as necessary. # One must be careful, though, when accessing entries since the values can be collected # at any time until there is a strong reference to them. # # === Example usage: # # cache = Ref::SoftValueMap.new # foo = "foo" # cache["strong"] = foo # add a value with a strong reference # cache["soft"] = "bar" # add a value without a strong reference # cache["strong"] # "foo" # cache["soft"] # "bar" # ObjectSpace.garbage_collect # ObjectSpace.garbage_collect # cache["strong"] # "foo" # cache["soft"] # nil # # See AbstractReferenceValueMap for details. class SoftValueMap < AbstractReferenceValueMap self.reference_class = SoftReference end end ref-1.0.2/lib/ref/weak_reference.rb0000644000175000017500000000161112063250626016461 0ustar boutilboutilmodule Ref # A WeakReference represents a reference to an object that is not seen by # the tracing phase of the garbage collector. This allows the referenced # object to be garbage collected as if nothing is referring to it. # # === Example usage: # # foo = Object.new # ref = Ref::WeakReference.new(foo) # ref.object # should be foo # ObjectSpace.garbage_collect # ref.object # should be nil class WeakReference < Reference # Create a weak reference to an object. def initialize(obj) raise NotImplementedError.new("This is an abstract class; you must require an implementation") end # Get the referenced object. If the object has been reclaimed by the # garbage collector, then this will return nil. def object raise NotImplementedError.new("This is an abstract class; you must require an implementation") end end end ref-1.0.2/lib/ref/safe_monitor.rb0000644000175000017500000000203612063250626016203 0ustar boutilboutilbegin require 'thread' rescue LoadError # Threads not available. Monitor will do nothing. end module Ref # The Monitor class in Ruby 1.8 has some bugs and also threads may not be available on all # runtimes. This class provides a simple, safe re-entrant mutex as an alternative. class SafeMonitor def initialize @owner = nil @count = 0 @mutex = defined?(Mutex) ? Mutex.new : nil end # Acquire an exclusive lock. def lock if @mutex if @owner != Thread.current.object_id @mutex.lock @owner = Thread.current.object_id end @count += 1 end true end # Release the exclusive lock. def unlock if @mutex if @owner == Thread.current.object_id @count -= 1 if @count == 0 @owner = nil @mutex.unlock end end end end # Run a block of code with an exclusive lock. def synchronize lock yield ensure unlock end end end ref-1.0.2/lib/ref/mock.rb0000644000175000017500000001067512063250626014457 0ustar boutilboutilmodule Ref # This module provides mock weak and strong references that are designed to be # used in tests. You can define a block where all weak and soft references created # will be mock references. You can then mimic running the garbage collector on # the objects pointed to by the references. # # Example usage: # # Ref::Mock.use do # obj = Object.new # ref = Ref::WeakReference.new(obj) # ref.object # obj # Ref::Mock.gc(obj) # mimics the garbage collector reclaiming the referenced object # ref.object # nil # end module Mock class << self # Use the mock implementation inside a block and then restore the original implementation. def use if object_space yield else setup begin yield ensure cleanup end end end # Start using mock references. def setup raise "Ref::Mock already setup" if object_space @object_space = {} class << ObjectSpace unless method_defined?(:define_finalizer_with_mock_reference) def define_finalizer_with_mock_reference(obj, finalizer) if ::Ref::Mock.object_space.include?(obj.__id__) ::Ref::Mock.object_space[obj.__id__] << finalizer else define_finalizer_without_mock_reference(obj, finalizer) end end end alias_method :define_finalizer_without_mock_reference, :define_finalizer alias_method :define_finalizer, :define_finalizer_with_mock_reference end class << WeakReference unless method_defined?(:new_with_mock_reference) def new_with_mock_reference(obj) if self == Mock::MockWeakReference new_without_mock_reference(obj) else Mock::MockWeakReference.new(obj) end end end alias_method :new_without_mock_reference, :new alias_method :new, :new_with_mock_reference end class << SoftReference unless method_defined?(:new_with_mock_reference) def new_with_mock_reference(obj) if self == Mock::MockSoftReference new_without_mock_reference(obj) else Mock::MockSoftReference.new(obj) end end end alias_method :new_without_mock_reference, :new alias_method :new, :new_with_mock_reference end end # Stop using mock references. def cleanup @object_space = nil class << ObjectSpace alias_method :define_finalizer_with_mock_reference, :define_finalizer alias_method :define_finalizer, :define_finalizer_without_mock_reference end class << WeakReference alias_method :new_with_mock_reference, :new alias_method :new, :new_without_mock_reference end class << SoftReference alias_method :new_with_mock_reference, :new alias_method :new, :new_without_mock_reference end end def object_space # :nodoc: @object_space if instance_variable_defined?(:@object_space) end # Simulate garbage collection of the objects passed in as arguments. If no objects # are specified, all objects will be reclaimed. def gc(*objects) objects = if objects.empty? object_space.keys else objects.map { |obj| obj.__id__ } end objects.each do |id| finalizers = object_space.delete(id) if finalizers finalizers.each{|finalizer| finalizer.call(id)} end end end end module MockReference #:nodoc: def initialize(obj) @object = obj @referenced_object_id = obj.__id__ raise "Reference::Mock not setup yet" unless Mock.object_space Mock.object_space[obj.__id__] ||= [] end def object if @object && Mock.object_space.include?(@object.__id__) @object else @object = nil end end end class MockWeakReference < WeakReference #:nodoc: include MockReference end class MockSoftReference < SoftReference #:nodoc: include MockReference end end end ref-1.0.2/lib/ref/reference_queue.rb0000644000175000017500000000477512063250626016674 0ustar boutilboutilmodule Ref # This class provides a simple thread safe container to hold a reference queue. Instances # of WeakReference can be added to the queue and as the objects pointed to by those references # are cleaned up by the garbage collector, the references will be added to the queue. # # The reason for using a reference queue is that it tends to be more efficient than adding # individual finalizers to objects and the cleanup code can be handled by a thread outside # of garbage collection. # # In general, you should create your own subclass of WeakReference that contains the logic # needed to complete the cleanup. The object pointed to will have already been cleaned up # and the reference cannot maintain a reference to the object. # # === Example usage: # # class MyRef < Ref::WeakReference # def cleanup # # Do something... # end # end # # queue = Ref::ReferenceQueue.new # ref = MyRef.new(Object.new) # queue.monitor(ref) # queue.shift # = nil # ObjectSpace.garbage_collect # r = queue.shift # = ref # r.cleanup class ReferenceQueue def initialize @queue = [] @references = {} @lock = SafeMonitor.new @finalizer = lambda do |object_id| @lock.synchronize do ref = @references.delete(object_id) @queue.push(ref) if ref end end end # Monitor a reference. When the object the reference points to is garbage collected, # the reference will be added to the queue. def monitor(reference) obj = reference.object if obj @lock.synchronize do @references[reference.referenced_object_id] = reference end ObjectSpace.define_finalizer(obj, @finalizer) else push(reference) end end # Add a reference to the queue. def push(reference) if reference @lock.synchronize do @queue.push(reference) end end end # Pull the last reference off the queue. Returns +nil+ if their are no references. def pop @lock.synchronize do @queue.pop end end # Pull the next reference off the queue. Returns +nil+ if there are no references. def shift @lock.synchronize do @queue.shift end end # Return +true+ if the queue is empty. def empty? @queue.empty? end # Get the current size of the queue. def size @queue.size end end end ref-1.0.2/lib/ref/abstract_reference_value_map.rb0000644000175000017500000000664512063250626021402 0ustar boutilboutilmodule Ref # Abstract base class for WeakValueMap and SoftValueMap. # # The classes behave similar to Hashes, but the values in the map are not strong references # and can be reclaimed by the garbage collector at any time. When a value is reclaimed, the # map entry will be removed. class AbstractReferenceValueMap class << self def reference_class=(klass) #:nodoc: @reference_class = klass end def reference_class #:nodoc: raise NotImplementedError.new("#{name} is an abstract class and cannot be instantiated") unless @reference_class @reference_class end end # Create a new map. Values added to the map will be cleaned up by the garbage # collector if there are no other reference except in the map. def initialize @references = {} @references_to_keys_map = {} @lock = SafeMonitor.new @reference_cleanup = lambda{|object_id| remove_reference_to(object_id)} end # Get a value from the map by key. If the value has been reclaimed by the garbage # collector, this will return nil. def [](key) ref = @references[key] value = ref.object if ref value end # Add a key/value to the map. def []=(key, value) ObjectSpace.define_finalizer(value, @reference_cleanup) key = key.dup if key.is_a?(String) @lock.synchronize do @references[key] = self.class.reference_class.new(value) keys_for_id = @references_to_keys_map[value.__id__] unless keys_for_id keys_for_id = [] @references_to_keys_map[value.__id__] = keys_for_id end keys_for_id << key end value end # Remove the entry associated with the key from the map. def delete(key) ref = @references.delete(key) if ref keys_to_id = @references_to_keys_map[ref.referenced_object_id] if keys_to_id keys_to_id.delete(key) @references_to_keys_map.delete(ref.referenced_object_id) if keys_to_id.empty? end ref.object else nil end end # Get the list of all values that have not yet been garbage collected. def values vals = [] each{|k,v| vals << v} vals end # Turn the map into an arry of [key, value] entries def to_a array = [] each{|k,v| array << [k, v]} array end # Iterate through all the key/value pairs in the map that have not been reclaimed # by the garbage collector. def each @references.each do |key, ref| value = ref.object yield(key, value) if value end end # Clear the map of all key/value pairs. def clear @lock.synchronize do @references.clear @references_to_keys_map.clear end end # Merge the values from another hash into this map. def merge!(other_hash) other_hash.each do |key, value| self[key] = value end end def inspect live_entries = {} each do |key, value| live_entries[key] = value end live_entries.inspect end private def remove_reference_to(object_id) @lock.synchronize do keys = @references_to_keys_map[object_id] if keys keys.each do |key| @references.delete(key) end @references_to_keys_map.delete(object_id) end end end end end ref-1.0.2/lib/ref/reference.rb0000644000175000017500000000147112063250626015456 0ustar boutilboutilmodule Ref # This class serves as a generic reference mechanism to other objects. The # actual reference can be either a WeakReference, SoftReference, or StrongReference. class Reference # The object id of the object being referenced. attr_reader :referenced_object_id # Create a new reference to an object. def initialize(obj) raise NotImplementedError.new("cannot instantiate a generic reference") end # Get the referenced object. This could be nil if the reference # is a WeakReference or a SoftReference and the object has been reclaimed by the garbage collector. def object raise NotImplementedError end def inspect obj = object "<##{self.class.name}: #{obj ? obj.inspect : "##{referenced_object_id} (not accessible)"}>" end end end ref-1.0.2/lib/ref/soft_reference.rb0000644000175000017500000000425712063250626016516 0ustar boutilboutilmodule Ref # A SoftReference represents a reference to an object that is not seen by # the tracing phase of the garbage collector. This allows the referenced # object to be garbage collected as if nothing is referring to it. # # A SoftReference differs from a WeakReference in that the garbage collector # is not so eager to reclaim soft references so they should persist longer. # # === Example usage: # # foo = Object.new # ref = Ref::SoftReference.new(foo) # ref.object # should be foo # ObjectSpace.garbage_collect # ref.object # should be foo # ObjectSpace.garbage_collect # ObjectSpace.garbage_collect # ref.object # should be nil class SoftReference < Reference @@strong_references = [{}] @@gc_flag_set = false # Number of garbage collection cycles after an object is used before a reference to it can be reclaimed. MIN_GC_CYCLES = 10 @@lock = SafeMonitor.new @@finalizer = lambda do |object_id| @@lock.synchronize do while @@strong_references.size >= MIN_GC_CYCLES do @@strong_references.shift end @@strong_references.push({}) if @@strong_references.size < MIN_GC_CYCLES @@gc_flag_set = false end end # Create a new soft reference to an object. def initialize(obj) @referenced_object_id = obj.__id__ @weak_reference = WeakReference.new(obj) add_strong_reference(obj) end # Get the referenced object. If the object has been reclaimed by the # garbage collector, then this will return nil. def object obj = @weak_reference.object # add a temporary strong reference each time the object is referenced. add_strong_reference(obj) if obj obj end private # Create a strong reference to the object. This reference will live # for three passes of the garbage collector. def add_strong_reference(obj) #:nodoc: @@lock.synchronize do @@strong_references.last[obj] = true unless @@gc_flag_set @@gc_flag_set = true ObjectSpace.define_finalizer(Object.new, @@finalizer) end end end end end ref-1.0.2/lib/ref/strong_reference.rb0000644000175000017500000000067512063250626017057 0ustar boutilboutilmodule Ref # This implementation of Reference holds a strong reference to an object. The # referenced object will not be garbage collected as long as the strong reference # exists. class StrongReference < Reference # Create a new strong reference to an object. def initialize(obj) @obj = obj @referenced_object_id = obj.__id__ end # Get the referenced object. def object @obj end end end ref-1.0.2/lib/ref/weak_value_map.rb0000644000175000017500000000212612063250626016476 0ustar boutilboutilmodule Ref # Implementation of a map in which weak references are kept to the map values. # This allows the garbage collector to reclaim these objects if the # only reference to them is the weak reference in the map. # # This is often useful for cache implementations since the map can be allowed to grow # without bound and the garbage collector can be relied on to clean it up as necessary. # One must be careful, though, when accessing entries since the values can be collected # at any time until there is a strong reference to them. # # === Example usage: # # cache = Ref::WeakValueMap.new # foo = "foo" # cache["strong"] = foo # add a value with a strong reference # cache["weak"] = "bar" # add a value without a strong reference # cache["strong"] # "foo" # cache["weak"] # "bar" # ObjectSpace.garbage_collect # cache["strong"] # "foo" # cache["weak"] # nil # # See AbstractReferenceValueMap for details. class WeakValueMap < AbstractReferenceValueMap self.reference_class = WeakReference end end ref-1.0.2/metadata.yml0000644000175000017500000000515312063250626014155 0ustar boutilboutil--- !ruby/object:Gem::Specification name: ref version: !ruby/object:Gem::Version version: 1.0.2 prerelease: platform: ruby authors: - Brian Durand autorequire: bindir: bin cert_chain: [] date: 2012-11-08 00:00:00.000000000 Z dependencies: [] description: Library that implements weak, soft, and strong references in Ruby that work across multiple runtimes (MRI, REE, YARV, Jruby, Rubinius, and IronRuby). Also includes implementation of maps/hashes that use references and a reference queue. email: - bdurand@embellishedvisions.com executables: [] extensions: [] extra_rdoc_files: - README.rdoc files: - README.rdoc - VERSION - MIT_LICENSE - lib/org/jruby/ext/ref/references.jar - lib/ref/abstract_reference_key_map.rb - lib/ref/abstract_reference_value_map.rb - lib/ref/mock.rb - lib/ref/reference.rb - lib/ref/reference_queue.rb - lib/ref/safe_monitor.rb - lib/ref/soft_key_map.rb - lib/ref/soft_reference.rb - lib/ref/soft_value_map.rb - lib/ref/strong_reference.rb - lib/ref/weak_key_map.rb - lib/ref/weak_reference/iron_ruby.rb - lib/ref/weak_reference/pure_ruby.rb - lib/ref/weak_reference/weak_ref.rb - lib/ref/weak_reference.rb - lib/ref/weak_value_map.rb - lib/ref.rb - test/mock_test.rb - test/reference_key_map_behavior.rb - test/reference_key_map_behavior.rbc - test/reference_queue_test.rb - test/reference_queue_test.rbc - test/reference_value_map_behavior.rb - test/reference_value_map_behavior.rbc - test/soft_key_map_test.rb - test/soft_key_map_test.rbc - test/soft_reference_test.rb - test/soft_reference_test.rbc - test/soft_value_map_test.rb - test/soft_value_map_test.rbc - test/strong_reference_test.rb - test/strong_reference_test.rbc - test/test_helper.rb - test/weak_key_map_test.rb - test/weak_key_map_test.rbc - test/weak_reference_test.rb - test/weak_reference_test.rbc - test/weak_value_map_test.rb - test/weak_value_map_test.rbc - ext/java/org/jruby/ext/ref/ReferencesService.java - ext/java/org/jruby/ext/ref/RubySoftReference.java - ext/java/org/jruby/ext/ref/RubyWeakReference.java homepage: http://github.com/bdurand/ref licenses: [] post_install_message: rdoc_options: - --charset=UTF-8 - --main - README.rdoc require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 1.8.11 signing_key: specification_version: 3 summary: Library that implements weak, soft, and strong references in Ruby. test_files: []