On 7/14/06, ara.t.howard / noaa.gov <ara.t.howard / noaa.gov> wrote: > On Fri, 14 Jul 2006, Sean O'Halpin wrote: > > > Hmmm. I'm still getting "singleton method called for a different > > object (TypeError)" for this (ruby 1.8.4 (2005-12-24) [i386-mswin32]). > > me too. > > harp:~ > cat a.rb > class X # role of IO > class << self > def x(*args,&block) # role of open > block.call(1764) if block > end > end > end > > OLD = X.method :x > > class Y < X # role of File > class << self > def x; "rubbish"; end > end > end > > class Y > class << self > define_method(:x, OLD ) > end > end > > Y.x{|a| puts a } > > > harp:~ > ruby a.rb > a.rb:23:in `x': singleton method called for a different object (TypeError) > from a.rb:23 > > > harp:~ > ruby -v && cat /etc/redhat-release && uname -srm > ruby 1.8.4 (2005-12-01) [i686-linux] > Red Hat Enterprise Linux WS release 3 (Taroon Update 7) > Linux 2.4.21-40.EL i686 > > you robert? > > > btw. this challenge was not arbitrary: the increase in metaprogramming > popularity means people are doing things like > > def class_method > alias '__instance_method__', 'instance_method' # push > > define_method 'instance_method' do > # ... > __instance_method__ 42 > # ... > end > > ensure > alias 'instance_method', '__instance_method__' # pop > end > > but this is neither thread safe (easy to fix) or re-entrant (not easy to fix). > what i mean is doing > > class_method{ > class_method{ > } > } > > blows up. > > to avoid this i wanted to develop this pattern > > def class_method > __instance_method__ = method 'instance_method' # push > > define_method 'instance_method' do > # ... > __instance_method__.call 42 > # ... > end > > ensure > define_method 'instance_method', __instance_method__ # pop > end > > but, of course, we are seeing that it doesn't work. > > regards. > > -a > -- > suffering increases your inner strength. also, the wishing for suffering > makes the suffering disappear. > - h.h. the 14th dali lama > > In most cases, this works: class Foo def self.open(*args, &block) p [args, block] yield if block_given? end end Foo.open(1) do puts "hello" end open_m = Foo.method 'open' class Foo def self.open(*a) p 42 end end Foo.open(2) do puts "hello" end (class << Foo; self; end).instance_eval do define_method(:open, open_m) end Foo.open(3) do puts "bye" end __END__ [[1], #<Proc:0x02869018@c:/rubylib/experiments/redefine-class-method.rb:8>] hello 42 [[3], #<Proc:0x02867728@c:/rubylib/experiments/redefine-class-method.rb:26>] bye but as we've seen, it doesn't work in the case of the File(IO) singleton. To be honest, I'm not clear about exactly what kind of object the File(IO) singleton is. Anyone offer any enlightenment? Regards, Sean