Let's straight to the point. I have a class named "A". I also have another subclass inherited from "A", I named it "B". Now, I have an object created from "A" and it has complex instance variables. There are arrays, hashes, strings, etc. And for some reasons, I want to clone the object and its instance variables as well and have different class. It's the subclass I'm talking about, the class "B"
I can easily clone the object and its instance variables by using Marshal
Marshal.load(Marshal.dump(object))And the object will be completely "different" from the previous object
However, I can't think about how to change the object class
Any thought?
Clone an object. Same instance variables with different class?
● ARCHIVED · READ-ONLY
-
-
There are ways, but none of them actually should be used (e.g., manipulating the result of Marshal.dump). May I ask what problem you're trying to solve? Why not create an instance of B and then copy all instance variables? Or is this just a theoretical question?
-
I already have alternative way to solve my actual problem. But if I can make that works, it would be totally easier.
Well, you can consider it as theorical question.
By the way, how can you copy all instance variables? By using instance_variable_set and instance_variable_get? I'm not so familiar with those functions -
I've already mentioned a way (here is some official document on the format). Another way is using DL::CPtr and manipulate the bytes that decide the class of an object. But I won't get into details here as I really don't want to see someone doing that. And with some effort you can find code on the Internet that does this. There was a gem called evil once that could do this in old Ruby versions.I already have alternative way to solve my actual problem. But if I can make that works, it would be totally easier.
Well, you can consider it as theorical question.
Aren't these your classes? Then you already know what attributes you want to copy. But if you really want to copy all instance variables, then you can or even have to use these methods.By the way, how can you copy all instance variables? By using instance_variable_set and instance_variable_get? I'm not so familiar with those functions
Getting familiar with them is pretty easy. You just have to read the documentation (yes, sometimes it is poor and more importantly, people that refer to them suck) and experiment a bit, but here is an example:
class A def to_b # alternatively you can define B.from_a deepcopy = Marshal.load(Marshal.dump(self)) b = B.new deepcopy.instance_variables.each do |iv| b.instance_variable_set(iv, deepcopy.instance_variable_get(iv)) end b endendIt should work most of the time, it isn't perfect though. And I probably wouldn't use it or something like it in real code. -
Lol, these are advanced stuffs that I'm not sure I will get into it. Well, thank you anyway.I've already mentioned a way (here is some official document on the format). Another way is using DL::CPtr and manipulate the bytes that decide the class of an object. But I won't get into details here as I really don't want to see someone doing that. And with some effort you can find code on the Internet that does this. There was a gem called evil once that could do this in old Ruby versions.
Yes, the documentation isn't good enough and your sample code is much easier to understand. Thank youAren't these your classes? Then you already know what attributes you want to copy. But if you really want to copy all instance variables, then you can or even have to use these methods.
Getting familiar with them is pretty easy. You just have to read the documentation (yes, sometimes it is poor and more importantly, people that refer to them suck) and experiment a bit, but here is an example:
class A def to_b # alternatively you can define B.from_a deepcopy = Marshal.load(Marshal.dump(self)) b = B.new deepcopy.instance_variables.each do |iv| b.instance_variable_set(iv, deepcopy.instance_variable_get(iv)) end b endendIt should work most of the time, it isn't perfect though. And I probably wouldn't use it or something like it in real code.
By the way, the good thing is I scrapped this idea to solve my problem and the new one is much neat and makes sense. And on the second thought I agree with you it seems isn't a good idea either.
And If you want to see what I want to do is something like this
This topic can be closed :) -
That's great to hear.By the way, the good thing is I scrapped this idea to solve my problem and the new one is much neat and makes sense.
Cool!And If you want to see what I want to do is something like this
-
As an alternative, if you just want to alter some of an objects methods you can also extend it by a module instead of changing its class:
Code:module B def do_something(*args) super print "Extended!" endend # ... copy = self.deep_copy # <- Create a copy (Placeholder) copy.extend( -
This thread is being closed, due to being solved. If for some reason you would like this thread re-opened, please report this post and leave a message why. Thank you.