Hi, 2009/9/1 Carl Lerche <clerche / engineyard.com>: > Yusuke, > > The reason that something like #prepend would be needed is so that ruby can > provide a good way to do AOP. Your example is not exactly a 1-1 mapping onto > the prepend feature. Instead, you would need to do this: > >> module Speak >> def speak(words) >> puts words >> end >> end >> module Exclaim >> def speak(words) >> super("#{ words }!") >> end >> end >> class Person # Empty class that only includes the module >> include Speak >> end >> class Exclaimer < Person >> include Exclaim >> end > > > If your classes are NOT empty and only include modules, then it is > impossible to include a module "under" methods defined directly on the > class. Do you talk about the following behavior as a problem? class Person def speak(words) puts words end end module Exclaim def speak(words) super("#{ words }!") end end class Person include Exclaim end Person.new.speak("matz") #=> "matz", not "matz!" > This causes pain when you are using a ruby library that does not > assume that you will be extending classes. Rails "solved" this problem using > alias_method_chain, but this method can cause confusion. Thank you, now it's starting to make sense. However, I think that module inclusion is not such a patching tool; open class is. In the above case, we can achieve our intent by redefining `speak' directly: class Person def speak(words) puts "#{ words }!" end end Person.new.speak("matz") #=> "matz!" When `speak' has a more complex definition, this way is a pain because we cannot use super. It is possible to solve the pain by preserving the original definition of speak as a alias, for example, old_speak. But I admit the solution is ugly. Then, I guess that what we really need is a method wrapping feature: class Person refine_method(:speak) do |old_method, words| # old_method is a Method of original definition old_method.call("#{ words }!") end end Person.new.speak("matz") #=> "matz!" -- Yusuke ENDOH <mame / tsg.ne.jp>