diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | lib/delegate.rb | 76 | ||||
-rw-r--r-- | lib/weakref.rb | 11 |
3 files changed, 53 insertions, 51 deletions
@@ -2,6 +2,12 @@ Thu Aug 11 23:29:03 2005 Nobuyoshi Nakada <nobu@ruby-lang.org> * ext/stringio/stringio.c: keep holding string after closed. +Thu Aug 11 20:48:40 2005 Tadashi Saito <shiba@mail2.accsnet.ne.jp> + + * numeric.c (fix_equal, fix_cmp, fix_gt, fix_ge, fix_lt, fix_le): + reduce coercing when a method knows about a operand type. + [ruby-dev:26789] + Thu Aug 11 13:01:48 2005 Kouhei Sutou <kou@cozmixng.org> * lib/rss: fixed sort bug. [ruby-list:41018] @@ -26,6 +32,11 @@ Thu Aug 11 13:01:48 2005 Kouhei Sutou <kou@cozmixng.org> (RSS::TestSetupMaker10::test_setup_maker_items_sort): added some tests for RSS::Maker::ItemsBase#do_sort. +Wed Aug 10 12:01:20 2005 Yukihiro Matsumoto <matz@ruby-lang.org> + + * lib/delegate.rb: simplifies Delegator classes; SimpleDelegator + now uses method_missing for all methods. + Wed Aug 10 10:38:50 2005 Yukihiro Matsumoto <matz@ruby-lang.org> * bignum.c (rb_big_mul0): multiply two numbers (x, y) without @@ -251,12 +262,12 @@ Wed Aug 3 21:59:16 2005 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> Wed Aug 3 12:40:28 2005 Tadashi Saito <shiba@mail2.accsnet.ne.jp> - * numeric.c (fix_minus, fix_mul, fix_quo, fix_div, fix_mod, - fix_divmod, fix_pow): ditto. - * numeric.c (fix_plus): reduce coercing when a method knows about a operand type. [ruby-dev:26723] + * numeric.c (fix_minus, fix_mul, fix_quo, fix_div, fix_mod, + fix_divmod, fix_pow): ditto. + * bignum.c (rb_big_div, rb_big_modulo): export to reduce coercing. diff --git a/lib/delegate.rb b/lib/delegate.rb index 1d0ebed07a..83aaf292a5 100644 --- a/lib/delegate.rb +++ b/lib/delegate.rb @@ -17,44 +17,27 @@ # end class Delegator + preserved = ["__id__", "object_id", "__send__", "respond_to?"] + instance_methods.each do |m| + next if preserved.include?(m) + undef_method m + end 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 - def self.#{method}(*args, &block) - begin - __getobj__.__send__(:#{method}, *args, &block) - rescue Exception - $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` - $@.delete_if{|s| /^\\(eval\\):/ =~ s} - ::Kernel::raise - end - end - EOS - rescue SyntaxError - raise NameError, "invalid identifier %s" % method, caller(4) - end - end + __setobj__(obj) end - alias initialize_methods initialize def method_missing(m, *args) - target = self.__getobj__ - unless target.respond_to?(m) - super(m, *args) + begin + target = self.__getobj__ + unless target.respond_to?(m) + super(m, *args) + end + target.__send__(m, *args) + rescue Exception + $@.delete_if{|s| /^#{__FILE__}:\d+:in `method_missing'$/ =~ s} #` + ::Kernel::raise end - target.__send__(m, *args) end def respond_to?(m) @@ -66,21 +49,19 @@ class Delegator raise NotImplementedError, "need to define `__getobj__'" end + def __setobj__(obj) + raise NotImplementedError, "need to define `__setobj__'" + end + def marshal_dump __getobj__ end def marshal_load(obj) - initialize_methods(obj) + __setobj__(obj) end end class SimpleDelegator<Delegator - - def initialize(obj) - super - @_sd_obj = obj - end - def __getobj__ @_sd_obj end @@ -91,12 +72,14 @@ class SimpleDelegator<Delegator end def clone - super - __setobj__(__getobj__.clone) + copy = super + copy.__setobj__(__getobj__.clone) + copy end def dup - super - __setobj__(__getobj__.dup) + copy = super + copy.__setobj__(__getobj__.dup) + copy end end @@ -108,8 +91,11 @@ SimpleDelegater = SimpleDelegator def DelegateClass(superclass) klass = Class.new methods = superclass.public_instance_methods(true) - methods -= ::Kernel.public_instance_methods(false) - methods |= ["to_s","to_a","inspect","==","=~","==="] + methods -= [ + "__id__", "object_id", "__send__", "respond_to?", + "initialize", "method_missing", "__getobj__", "__setobj__", + "clone", "dup", "marshal_dump", "marshal_load", + ] klass.module_eval { def initialize(obj) @_dc_obj = obj diff --git a/lib/weakref.rb b/lib/weakref.rb index c790055d01..a398ebf1fe 100644 --- a/lib/weakref.rb +++ b/lib/weakref.rb @@ -18,7 +18,8 @@ class WeakRef<Delegator @@id_map = {} # obj -> [ref,...] @@id_rev_map = {} # ref -> obj - @@final = lambda{|id| + @@final = lambda {|id| + printf "final: %p\n", id __old_status = Thread.critical Thread.critical = true begin @@ -42,6 +43,7 @@ class WeakRef<Delegator def initialize(orig) @__id = orig.object_id + printf "orig: %p\n", @__id ObjectSpace.define_finalizer orig, @@final ObjectSpace.define_finalizer self, @@final __old_status = Thread.critical @@ -53,7 +55,7 @@ class WeakRef<Delegator end @@id_map[@__id].push self.object_id @@id_rev_map[self.object_id] = @__id - super + super end def __getobj__ @@ -66,6 +68,8 @@ class WeakRef<Delegator Kernel::raise RefError, "Illegal Reference - probably recycled", Kernel::caller(2) end end + def __setobj__(obj) + end def weakref_alive? @@id_rev_map[self.object_id] == @__id @@ -73,11 +77,12 @@ class WeakRef<Delegator end if __FILE__ == $0 - require 'thread' +# require 'thread' foo = Object.new p foo.to_s # original's class foo = WeakRef.new(foo) p foo.to_s # should be same class ObjectSpace.garbage_collect + ObjectSpace.garbage_collect p foo.to_s # should raise exception (recycled) end |