From: Florian Frank Date: 2006-09-26T03:57:01+09:00 Subject: Re: How to copy a method from one class to another MonkeeSage wrote: > Sam Kong wrote: > >> Let's say that there's a class (C1) in a library and I'm building my >> own class hierarchy including C2 (class C2 < SomeOtherClass). >> In such a case, Inheritance or mix-in is not an option. >> > > Unless I misunderstand, a mixin is fine: > This wouldn't work in the situation Sam describes: class Rubyforge::C1 # for example in some rubyforge library def interesting_method if @foo > 3 @bar += 2 else @baz /= 2 end end end Sam wonders how to call interesting_method from his class C2, that cannot inherit from C1, because it already inherits from SomeOtherClass: class C2 < SomeOtherClass def my_method interesting_method # ??? end end This isn't possible in Ruby, because of single inheritance and the fact that Sam doesn't control the rubyforge library and thus cannot create a module to include in C2. The only way to get interesting_method's functionality into C2 is to copy & paste it. If there was a way in Ruby to do that like: class C2 < SomeOtherClass include Rubyforge::C1.to_module(:interesting_method) def my_method interesting_method end end This would introduce a tight coupling between C2 and C1 on the same level like inheritance would do. In some way it would be equivalent to real multiple inheritance. Now the author of C1 can break your code by refactoring e. g.: class Rubyforge::C1 # for example in some rubyforge library def interesting_method if @foo > 3 add_two else @baz /= 2 end end private def add_two @bar += 2 end end I was in the same situation and ended up copying & pasting. I wished at the time, that it would have been possible to just import those methods, even if it meant that I might ending up shooting myself into the foot. There is an additional problem, that occurs when someone attempts to import methods from a Ruby class implemented in C, that uses a macro like RSTRING(foo)->len. In these cases it would be possible to trigger a Ruby segmentation fault by calling those methods. Of course it would perhaps be possible to mark C implemented methods and let Ruby refuse to export them. This would at least cause an ordinary exception during class loading time. -- Florian Frank