mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* eval.c (rb_mod_define_method): should save safe_level in the
proc object. [ruby-dev:28146] * test/drb/drbtest.rb (DRbService::self.ext_service): increase timeout limit. a patch from Kazuhiro NISHIYAMA <zn at mbf.nifty.com>. [ruby-dev:28132] * eval.c (ev_const_get): fixed a bug in constant reference during instance_eval. [yarv-dev:707] * eval.c (ev_const_defined): ditto. * lib/yaml.rb (YAML::add_domain_type): typo fixed. a patch from Joel VanderWerf <vjoel at path.berkeley.edu>. [ruby-talk:165285] [ruby-core:6995] * ext/digest/sha2/sha2.c (ULL): support AIX C. a patch from Kailden <kailden at gmail.com>. [ruby-core:06984] * ext/syck/rubyext.c (rb_syck_compile): avoid potential memory leak. * ext/syck/rubyext.c (syck_set_ivars): avoid potential memory leak by explicit symbol allocation. * lib/delegate.rb (Delegator::method_missing): should delegate block as well. * lib/cgi.rb (CGI::QueryExtension::MorphingBody): fix criteria to use Tempfile. A fix from Zev Blut <rubyzbibd at ubit.com>. [ruby-core:06076] * string.c: remove global functions work on $_. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9757 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
e5226ea394
commit
de3bff164c
13 changed files with 342 additions and 370 deletions
179
lib/delegate.rb
179
lib/delegate.rb
|
@ -121,61 +121,93 @@ class Delegator
|
|||
undef_method m
|
||||
end
|
||||
|
||||
#
|
||||
# Pass in the _obj_ to delegate method calls to. All methods supported by
|
||||
# _obj_ will be delegated to.
|
||||
#
|
||||
def initialize(obj)
|
||||
__setobj__(obj)
|
||||
end
|
||||
module MethodDelegation
|
||||
#
|
||||
# Pass in the _obj_ to delegate method calls to. All methods supported by
|
||||
# _obj_ will be delegated to.
|
||||
#
|
||||
def initialize(obj)
|
||||
__setobj__(obj)
|
||||
end
|
||||
|
||||
# Handles the magic of delegation through \_\_getobj\_\_.
|
||||
def method_missing(m, *args)
|
||||
begin
|
||||
target = self.__getobj__
|
||||
unless target.respond_to?(m)
|
||||
super(m, *args)
|
||||
# Handles the magic of delegation through \_\_getobj\_\_.
|
||||
def method_missing(m, *args, &block)
|
||||
begin
|
||||
target = self.__getobj__
|
||||
unless target.respond_to?(m)
|
||||
super(m, *args, &block)
|
||||
else
|
||||
target.__send__(m, *args, &block)
|
||||
end
|
||||
rescue Exception
|
||||
$@.delete_if{|s| /^#{__FILE__}:\d+:in `method_missing'$/ =~ s} #`
|
||||
::Kernel::raise
|
||||
end
|
||||
target.__send__(m, *args)
|
||||
rescue Exception
|
||||
$@.delete_if{|s| /^#{__FILE__}:\d+:in `method_missing'$/ =~ s} #`
|
||||
::Kernel::raise
|
||||
end
|
||||
|
||||
#
|
||||
# Checks for a method provided by this the delegate object by fowarding the
|
||||
# call through \_\_getobj\_\_.
|
||||
#
|
||||
def respond_to?(m)
|
||||
return true if super
|
||||
return self.__getobj__.respond_to?(m)
|
||||
end
|
||||
|
||||
#
|
||||
# Returns true if two objects are considered same.
|
||||
#
|
||||
def ==(obj)
|
||||
return true if obj.equal?(self)
|
||||
self.__getobj__ == obj
|
||||
end
|
||||
|
||||
#
|
||||
# Returns true only if two objects are identical.
|
||||
#
|
||||
def equal?(obj)
|
||||
self.object_id == obj.object_id
|
||||
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 change the object delegate
|
||||
# to _obj_.
|
||||
#
|
||||
def __setobj__(obj)
|
||||
raise NotImplementedError, "need to define `__setobj__'"
|
||||
end
|
||||
|
||||
# Serialization support for the object returned by \_\_getobj\_\_.
|
||||
def marshal_dump
|
||||
__getobj__
|
||||
end
|
||||
# Reinitializes delegation from a serialized object.
|
||||
def marshal_load(obj)
|
||||
__setobj__(obj)
|
||||
end
|
||||
|
||||
# Clone support for the object returned by \_\_getobj\_\_.
|
||||
def clone
|
||||
new = super
|
||||
new.__setobj__(__getobj__.clone)
|
||||
new
|
||||
end
|
||||
# Duplication support for the object returned by \_\_getobj\_\_.
|
||||
def dup
|
||||
new = super
|
||||
new.__setobj__(__getobj__.dup)
|
||||
new
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Checks for a method provided by this the delegate object by fowarding the
|
||||
# call through \_\_getobj\_\_.
|
||||
#
|
||||
def respond_to?(m)
|
||||
return true if super
|
||||
return self.__getobj__.respond_to?(m)
|
||||
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 change the object delegate
|
||||
# to _obj_.
|
||||
#
|
||||
def __setobj__(obj)
|
||||
raise NotImplementedError, "need to define `__setobj__'"
|
||||
end
|
||||
|
||||
# Serialization support for the object returned by \_\_getobj\_\_.
|
||||
def marshal_dump
|
||||
__getobj__
|
||||
end
|
||||
# Reinitializes delegation from a serialized object.
|
||||
def marshal_load(obj)
|
||||
__setobj__(obj)
|
||||
end
|
||||
include MethodDelegation
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -208,19 +240,6 @@ class SimpleDelegator<Delegator
|
|||
raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
|
||||
@_sd_obj = obj
|
||||
end
|
||||
|
||||
# Clone support for the object returned by \_\_getobj\_\_.
|
||||
def clone
|
||||
copy = super
|
||||
copy.__setobj__(__getobj__.clone)
|
||||
copy
|
||||
end
|
||||
# Duplication support for the object returned by \_\_getobj\_\_.
|
||||
def dup
|
||||
copy = super
|
||||
copy.__setobj__(__getobj__.dup)
|
||||
copy
|
||||
end
|
||||
end
|
||||
|
||||
# :stopdoc:
|
||||
|
@ -243,24 +262,12 @@ def DelegateClass(superclass)
|
|||
klass = Class.new
|
||||
methods = superclass.public_instance_methods(true)
|
||||
methods -= [
|
||||
"__id__", "object_id", "__send__", "respond_to?",
|
||||
"__id__", "object_id", "__send__", "respond_to?", "==", "equal?",
|
||||
"initialize", "method_missing", "__getobj__", "__setobj__",
|
||||
"clone", "dup", "marshal_dump", "marshal_load",
|
||||
]
|
||||
klass.module_eval {
|
||||
def initialize(obj) # :nodoc:
|
||||
@_dc_obj = obj
|
||||
end
|
||||
def method_missing(m, *args) # :nodoc:
|
||||
unless @_dc_obj.respond_to?(m)
|
||||
super(m, *args)
|
||||
end
|
||||
@_dc_obj.__send__(m, *args)
|
||||
end
|
||||
def respond_to?(m) # :nodoc:
|
||||
return true if super
|
||||
return @_dc_obj.respond_to?(m)
|
||||
end
|
||||
include Delegator::MethodDelegation
|
||||
def __getobj__ # :nodoc:
|
||||
@_dc_obj
|
||||
end
|
||||
|
@ -268,14 +275,6 @@ def DelegateClass(superclass)
|
|||
raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
|
||||
@_dc_obj = obj
|
||||
end
|
||||
def clone # :nodoc:
|
||||
super
|
||||
__setobj__(__getobj__.clone)
|
||||
end
|
||||
def dup # :nodoc:
|
||||
super
|
||||
__setobj__(__getobj__.dup)
|
||||
end
|
||||
}
|
||||
for method in methods
|
||||
begin
|
||||
|
@ -309,15 +308,23 @@ if __FILE__ == $0
|
|||
p ary.class
|
||||
ary.push 25
|
||||
p ary
|
||||
ary.push 42
|
||||
ary.each {|x| p x}
|
||||
|
||||
foo = Object.new
|
||||
def foo.test
|
||||
25
|
||||
end
|
||||
def foo.iter
|
||||
yield self
|
||||
end
|
||||
def foo.error
|
||||
raise 'this is OK'
|
||||
end
|
||||
foo2 = SimpleDelegator.new(foo)
|
||||
p foo2
|
||||
foo2.instance_eval{print "foo\n"}
|
||||
p foo.test == foo2.test # => true
|
||||
p foo2.iter{[55,true]} # => true
|
||||
foo2.error # raise error!
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue