Skip to content

Commit

Permalink
Showing 6 changed files with 113 additions and 159 deletions.
1 change: 0 additions & 1 deletion core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -1704,7 +1704,6 @@ private void initBuiltins() {
addLazyBuiltin("bigdecimal.jar", "bigdecimal", "org.jruby.ext.bigdecimal.BigDecimalLibrary");
addLazyBuiltin("io/wait.jar", "io/wait", "org.jruby.ext.io.wait.IOWaitLibrary");
addLazyBuiltin("etc.jar", "etc", "org.jruby.ext.etc.EtcLibrary");
addLazyBuiltin("weakref.rb", "weakref", "org.jruby.ext.weakref.WeakRefLibrary");
addLazyBuiltin("timeout.rb", "timeout", "org.jruby.ext.timeout.Timeout");
addLazyBuiltin("socket.jar", "socket", "org.jruby.ext.socket.SocketLibrary");
addLazyBuiltin("rbconfig.rb", "rbconfig", "org.jruby.ext.rbconfig.RbConfigLibrary");
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/RubyObjectSpace.java
Original file line number Diff line number Diff line change
@@ -214,6 +214,11 @@ public IRubyObject op_aref(ThreadContext context, IRubyObject key, IRubyObject v
return context.runtime.newFixnum(System.identityHashCode(value));
}

@JRubyMethod(name = "key?")
public IRubyObject key_p(ThreadContext context, IRubyObject key) {
return context.runtime.newBoolean(map.get(key) != null);
}

private final WeakValuedIdentityMap<IRubyObject, IRubyObject> map = new WeakValuedIdentityMap<IRubyObject, IRubyObject>();
}
}
112 changes: 0 additions & 112 deletions core/src/main/java/org/jruby/ext/weakref/WeakRef.java

This file was deleted.

46 changes: 0 additions & 46 deletions core/src/main/java/org/jruby/ext/weakref/WeakRefLibrary.java

This file was deleted.

107 changes: 107 additions & 0 deletions lib/ruby/stdlib/weakref.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# frozen_string_literal: false
require "delegate"

# Weak Reference class that allows a referenced object to be
# garbage-collected.
#
# A WeakRef may be used exactly like the object it references.
#
# Usage:
#
# foo = Object.new # create a new object instance
# p foo.to_s # original's class
# foo = WeakRef.new(foo) # reassign foo with WeakRef instance
# p foo.to_s # should be same class
# GC.start # start the garbage collector
# p foo.to_s # should raise exception (recycled)
#
# == Example
#
# With help from WeakRef, we can implement our own rudimentary WeakHash class.
#
# We will call it WeakHash, since it's really just a Hash except all of it's
# keys and values can be garbage collected.
#
# require 'weakref'
#
# class WeakHash < Hash
# def []= key, obj
# super WeakRef.new(key), WeakRef.new(obj)
# end
# end
#
# This is just a simple implementation, we've opened the Hash class and changed
# Hash#store to create a new WeakRef object with +key+ and +obj+ parameters
# before passing them as our key-value pair to the hash.
#
# With this you will have to limit your self to String keys, otherwise you
# will get an ArgumentError because WeakRef cannot create a finalizer for a
# Symbol. Symbols are immutable and cannot be garbage collected.
#
# Let's see it in action:
#
# omg = "lol"
# c = WeakHash.new
# c['foo'] = "bar"
# c['baz'] = Object.new
# c['qux'] = omg
# puts c.inspect
# #=> {"foo"=>"bar", "baz"=>#<Object:0x007f4ddfc6cb48>, "qux"=>"lol"}
#
# # Now run the garbage collector
# GC.start
# c['foo'] #=> nil
# c['baz'] #=> nil
# c['qux'] #=> nil
# omg #=> "lol"
#
# puts c.inspect
# #=> WeakRef::RefError: Invalid Reference - probably recycled
#
# You can see the local variable +omg+ stayed, although its reference in our
# hash object was garbage collected, along with the rest of the keys and
# values. Also, when we tried to inspect our hash, we got a WeakRef::RefError.
# This is because these objects were also garbage collected.

class WeakRef < Delegator

##
# RefError is raised when a referenced object has been recycled by the
# garbage collector

class RefError < StandardError
end

@@__map = ::ObjectSpace::WeakMap.new

##
# Creates a weak reference to +orig+
#
# Raises an ArgumentError if the given +orig+ is immutable, such as Symbol,
# Fixnum, or Float.

def initialize(orig)
case orig
when true, false, nil
@delegate_sd_obj = orig
else
@@__map[self] = orig
end
super
end

def __getobj__ # :nodoc:
@@__map[self] or defined?(@delegate_sd_obj) ? @delegate_sd_obj :
Kernel::raise(RefError, "Invalid Reference - probably recycled", Kernel::caller(2))
end

def __setobj__(obj) # :nodoc:
end

##
# Returns true if the referenced object is still alive.

def weakref_alive?
@@__map.key?(self) or defined?(@delegate_sd_obj)
end
end
1 change: 1 addition & 0 deletions tool/globals_2_3_3.rb
Original file line number Diff line number Diff line change
@@ -66,6 +66,7 @@
unicode_normalize.rb
uri
uri.rb
weakref.rb
webrick
webrick.rb
xmlrpc

0 comments on commit 1b4a2f3

Please sign in to comment.