Skip to content

Commit

Permalink
Revert to a ruby verison unless jruby.delegate.native=true, to ensure…
Browse files Browse the repository at this point in the history
… we're supporting the same features without the massive overhead of redefining those methods. Not sure whether the native version will be on or not.
  • Loading branch information
headius committed Mar 22, 2010
1 parent 8e593da commit 17dd4f5
Showing 1 changed file with 84 additions and 70 deletions.
154 changes: 84 additions & 70 deletions lib/ruby/1.8/delegate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,86 +114,100 @@
# subclasses. Subclasses should redefine \_\_getobj\_\_. For a concrete
# implementation, see SimpleDelegator.
#
require 'jruby'
require 'java'
if defined?(ENV_JAVA) && ENV_JAVA['jruby.delegate.native'] =~ /true/i
require 'jruby'
require 'java'

# we use a pure-Java Delegator to avoid the nastiness of the code below, and to
# boost performance a bit
require 'delegate_internal'
=begin
class Delegator
IgnoreBacktracePat = %r"\A#{Regexp.quote(__FILE__)}:\d+:in `"
#
# Pass in the _obj_ to delegate method calls to. All methods supported by
# _obj_ will be delegated to.
#
def initialize(obj)
preserved = ::Kernel.public_instance_methods(false)
preserved -= ["to_s","to_a","inspect","==","=~","==="]
for t in self.class.ancestors
preserved |= t.public_instance_methods(false)
preserved |= t.private_instance_methods(false)
preserved |= t.protected_instance_methods(false)
break if t == Delegator
end
preserved << "singleton_method_added"
for method in obj.methods
next if preserved.include? method
begin
eval <<-EOS, nil, __FILE__, __LINE__+1
def self.#{method}(*args, &block)
begin
__getobj__.__send__(:#{method}, *args, &block)
ensure
$@.delete_if{|s|IgnoreBacktracePat=~s} if $@
end
end
EOS
rescue SyntaxError
raise NameError, "invalid identifier %s" % method, caller(4)
# we use a pure-Java Delegator to avoid the nastiness of the code below, and to
# boost performance a bit
require 'delegate_internal'
else
# original, but slightly improved pure-Ruby Delegator
class Delegator
IgnoreBacktracePat = %r"\A#{Regexp.quote(__FILE__)}:\d+:in `"
DelegatorModules = Hash.new do |hash, classes|
objclass, deleclass = *classes
hash[classes] = Module.new do
preserved = ::Kernel.public_instance_methods(false)
preserved -= ["to_s","to_a","inspect","==","=~","==="]
for t in deleclass.ancestors
preserved |= t.public_instance_methods(false)
preserved |= t.private_instance_methods(false)
preserved |= t.protected_instance_methods(false)
break if t == Delegator
end
preserved << "singleton_method_added"
for method in objclass.instance_methods
next if preserved.include? method
begin
eval <<-EOS, nil, __FILE__, __LINE__+1
def #{method}(*args, &block)
begin
__getobj__.__send__(:#{method}, *args, &block)
ensure
$@.delete_if{|s|IgnoreBacktracePat=~s} if $@
end
end
EOS
rescue SyntaxError
raise NameError, "invalid identifier %s" % method, caller(4)
end
end
end
end
end
alias initialize_methods initialize

#
# Pass in the _obj_ to delegate method calls to. All methods supported by
# _obj_ will be delegated to.
#
def initialize(obj)
# This modification caches the generated set of methods for a given pair
# of object class + delegate subclass and extends it onto future objects.
# This avoids all the overhead of that class generation on each object
# construction, but introduces the overhead of .extend and does not
# properly define singleton methods (though they'll still dispatch ok
# through method_missing)
extend DelegatorModules[[obj.class, self.class]]
end
alias initialize_methods initialize

# Handles the magic of delegation through \_\_getobj\_\_.
def method_missing(m, *args)
target = self.__getobj__
unless target.respond_to?(m)
super(m, *args)
# Handles the magic of delegation through \_\_getobj\_\_.
def method_missing(m, *args)
target = self.__getobj__
unless target.respond_to?(m)
super(m, *args)
end
target.__send__(m, *args)
end
target.__send__(m, *args)
end

#
# Checks for a method provided by this the delegate object by fowarding the
# call through \_\_getobj\_\_.
#
def respond_to?(m, include_private = false)
return true if super
return self.__getobj__.respond_to?(m, include_private)
end
#
# Checks for a method provided by this the delegate object by fowarding the
# call through \_\_getobj\_\_.
#
def respond_to?(m, include_private = false)
return true if super
return self.__getobj__.respond_to?(m, include_private)
end

#
# This method must be overridden by subclasses and should return the object
# method calls are being delegated to.
#
def __getobj__
raise NotImplementedError, "need to define `__getobj__'"
end
#
# This method must be overridden by subclasses and should return the object
# method calls are being delegated to.
#
def __getobj__
raise NotImplementedError, "need to define `__getobj__'"
end

# Serialization support for the object returned by \_\_getobj\_\_.
def marshal_dump
__getobj__
end
# Reinitializes delegation from a serialized object.
def marshal_load(obj)
initialize_methods(obj)
__setobj__(obj)
# Serialization support for the object returned by \_\_getobj\_\_.
def marshal_dump
__getobj__
end
# Reinitializes delegation from a serialized object.
def marshal_load(obj)
initialize_methods(obj)
__setobj__(obj)
end
end
end
=end
#
# A concrete implementation of Delegator, this class provides the means to
# delegate all supported method calls to the object passed into the constructor
Expand Down

0 comments on commit 17dd4f5

Please sign in to comment.