How to copy a method from one class to another

Hi Rubyists,

Is there a way to copy an instance method from one class to another?

class C1
def f
p self.class
end
end

class C2
end

Now I want C2 to have f method so that I can call C2.new.f.

Thanks.

Sam

On Tue, Sep 26, 2006 at 01:10:17AM +0900, Sam K. wrote:

class C2
end

Now I want C2 to have f method so that I can call C2.new.f.

You can inherit.

class C2 < C1
end

Or you can make C1 a module

module C1
def f
p self.class
end
end

class C2
include C1
end

Sam K. wrote:

class C2
end

Now I want C2 to have f method so that I can call C2.new.f.

Thanks.

Perhaps it would be better for you to describe the problem this idea
would
address. If you need to have a shared method, maybe it would be better
to
put it in a module and associate the module with any classes needing the
method. Or a parent-child relationship can be established between
classes
to make a particular method available to more than one class.

Sam K. 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:

module C1
def f
p self.class
end
end

class C2; end

class C3 < C2
include C1
end

C3.new.f # => “C3”

Regards,
Jordan

Sam K. wrote:

class C2
end

Now I want C2 to have f method so that I can call C2.new.f.

OK. I need to describe what I want.
Actually this problem is rather imaginary than practical.
While solving some other problem, this question came into my mind.
Normally, I would use inheritance or mix-in or maybe delegation.
This question is “What if…?”

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.
However, I want to add a method of C1 into my C2.
As someone jokingly mentioned, I can copy the source code.
Let’s assume that the method is implemented in C and we don’t have the
source.

Can we still copy(or reuse) the method?

Sam

Hi Jordan,

Jordan Callicoat wrote:

Sam K. 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:

module C1
def f
p self.class
end
end

Unfortunately, C1 is already a class.

Sam

Posted by Sam K.
on 25.09.2006 18:11

Hi Rubyists,

Is there a way to copy an instance method from one class to another?

How about using something like “inheritance and super function”?

http://www.ruby-forum.com/topic/81049

Hi Verno,

Verno Miller wrote:

Posted by Sam K.
on 25.09.2006 18:11

Hi Rubyists,

Is there a way to copy an instance method from one class to another?

How about using something like “inheritance and super function”?

Inheritance and super function - Ruby - Ruby-Forum

But C1 and C2 are in different class hierarchies.
C2 is not a kind of C1.
What I’m trying to do is to copy(or reuse) the implementation of another
class in a different hierarchy.

Sam

Hi Florian,

Florian F. wrote:

This wouldn’t work in the situation Sam describes:

This isn’t possible in Ruby, because of single inheritance and the fact
interesting_method
if @foo > 3
end
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 F.

I think you’re understanding my problem very correctly.
My need was sort of like multiple inheritance which is not supported in
Ruby.
Mix-in is the right way in Ruby.
However, for mix-in, all things should be designed before
implementation.
If you want to reuse some part of a class, there’s no easy way and
probably it’s not recommended like you said it’s tight-coupling.

Thank you for your time and expertise.

Sam

MonkeeSage wrote:

Sam K. 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.

On 9/25/06, Sam K. [email protected] wrote:

I think you’re understanding my problem very correctly.
My need was sort of like multiple inheritance which is not supported in
Ruby.

And even in a language like C++ which supports multiple inheritance,
you can’t pick and choose which functions you inherit.

In fact, it’s even harder because, unlike a dynamic language like
Ruby, where inheritance and mix-in is used only to compose
implementation, in a strongly typed language they also are the
mechanism of type composition.

It’s this tight-coupling of implementation and specification which
distinguishes the two approaches.

And it’s one good reason why Ruby is NOT C++, nor is it Java, and one
of the reasons so many things seem to be easier in Ruby once you get
acclimatized.

Mix-in is the right way in Ruby.
However, for mix-in, all things should be designed before
implementation.

Not necessarily before, but in concert with, it’s called iterative
design, the design evolves as you learn more about the problem by
implementing it.

Another difference in the strongly typed vs. dynamic languages is the
implications of refactoring. In a dynamic language it’s more like
rearranging furniture, while in a strongly-type one it’s more like
solving a 15-puzzle.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Hi,

In message “Re: How to copy a method from one class to another”
on Tue, 26 Sep 2006 05:15:20 +0900, “Sam K.”
[email protected] writes:

|Mix-in is the right way in Ruby.
|However, for mix-in, all things should be designed before
|implementation.

If you are not allowed to modify existing classes. Most of the cases
rewriting

class C1
def f
p self.class
end
end

to

module M1
def f
p self.class
end
end

class C1
include M1
end

class C2
include M1
end

is trivial. You don’t need to design everything before
implementation, but just have to evolve classes.

If you are not allowed to modify pre-existing class, you need to use
some kind of delegation.

						matz.