From: Daniel DeLorme Date: 2006-07-25T23:16:54+09:00 Subject: Re: I'll have the duck! dblack@wobblini.net wrote: > The problem is that "duck typing" is already "taken" :-) *sigh* And So, Faced With Insurmountable Semantic Opposition And A Total Lack Of Suggestions, I Was Faced With The Lonely Task Of Renaming My Proof-Of-Concept Module, Carefully Removing Any Offending Reference To The Word "Duck": module DependentMethods @@dependent_methods = Hash.new{ |h,k| h[k] = {} } def depending_on(*requisites, &block) o = self.is_a?(Class) ? self : self.class requisites.unshift(o) before = o.instance_methods o.class_eval(&block) after = o.instance_methods for methodname in (after - before) methodname = methodname.to_sym @@dependent_methods[methodname][requisites] = o.instance_method(methodname) o.send(:remove_method, methodname) end end def dependent_method(methodname) @@dependent_methods[methodname.to_sym].each do |requisites, m| if self.kind_of?(requisites[0]) if requisites[1..-1].all?{ |r| self.respond_to?(r) } return m end end end return nil end def method_missing(methodname, *args, &block) if m = dependent_method(methodname) m.bind(self).call(*args, &block) else super end end end Object.module_eval{ include DependentMethods } depending_on :quack do def quack_loudly ([quack.upcase]*(1+rand(3))).join end end class Anatidae def quack "quack!" end end d = Anatidae.new puts d.quack_loudly #=> "QUACK!"