From: ara.t.howard@... Date: 2006-12-28T12:40:50+09:00 Subject: override.rb since the threads split all over the place i figured i'd start yet another. can people break this? harp:~ > cat a.rb class Module module OverRiding class << self def new Module.new{ @added_methods = [] @parent = nil class << self attr :added_methods attr :parent def method_added m super if defined? super ensure added_methods << m.to_s end def remove_method m super if defined? super ensure added_methods.delete_at(added_methods.rindex(m.to_s)) rescue nil end def add_parent m include(@parent = m) end def cache mname, m mname = mname.to_s const = mname.gsub(%r/[!]/,'__bang__').gsub(%r/[?]/,'__what__').upcase const_set const, m module_eval <<-code def #{ mname } *a, &b #{ const }.bind(self).call *a, &b end code end def walking_up m = self loop{ yield m break unless((m=m.parent) rescue nil) } end end } end end end def overriding &b this = self m = OverRiding.new m.module_eval &b unless defined? @overriding @overriding = OverRiding.new m.added_methods.each do |mname| @overriding.cache mname, this.instance_method(mname) this.remove_method mname end end m.add_parent @overriding include m @overriding = m end alias_method 'override', 'overriding' def restore mname if defined? @overriding mname = mname.to_s @overriding.walking_up do |m| break( m.remove_method mname ) if m.added_methods.include?(mname) end end instance_method mname end def restoring *a, &b o = Object.new sc = class << o; self; end sc.module_eval{ instance_methods.each{|m| remove_method m unless m[/^__/] rescue nil} define_method('method_missing'){|m, *a| a << m } } o.instance_eval &b a.flatten.compact.each{|m| restore m} end end if $0 == __FILE__ class C c = new def m() 'a' end p c.m #=> 'a' override{ def m() super + 'b' end } p c.m #=> 'ab' override{ def m() super + 'c' end } p c.m #=> 'abc' override{ def m() super + 'd' end } p c.m #=> 'abcd' restore 'm' p c.m #=> 'abc' restore 'm' p c.m #=> 'ab' restore 'm' p c.m #=> 'a' end end harp:~ > ruby a.rb "a" "ab" "abc" "abcd" "abc" "ab" "a" -a -- if you find yourself slandering anybody, first imagine that your mouth is filled with excrement. it will break you of the habit quickly enough. - the dalai lama