From: "Paulo Köch" Date: 2006-12-28T13:05:51+09:00 Subject: Re: override.rb Holy cow! Tell me, what do you want us to do with this, exactly? What are you challenging us to? Didn't get it. =/ On 12/28/06, ara.t.howard@noaa.gov wrote: > > 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 > >