Daniel L. wrote:
Earle C. wrote:
The
result I’m trying to achieve is the same as if I had copied the module
source code and renamed the module.
I think stud number 7 was onto something. How about this:
CommonDef = %q{
def self.hello
puts “hello from #{self}”
end
}
module A
module_eval CommonDef
end
module B
module_eval CommonDef
end
A.hello
B.hello
module B
def self.hello
puts “different hello”
end
end
A.hello
B.hello
===>
hello from A
hello from B
hello from A
different hello
Seems to work right.
best,
Dan
As far as I can tell, your code is no different than this:
module A
def self.hello
puts “hello from #{self}”
end
end
module B
def self.hello
puts “hello from #{self}”
end
end
A.hello
B.hello
module B
def self.hello
puts “different hello”
end
end
A.hello
B.hello
-
You never cloned A. All you did was create two separate modules
which have similar methods.
-
Then you manually overwrote the method in B to do something else.
I don’t see how that addresses anything the op’s question. The problem
has to do with the fact that clone makes a shallow copy. In other
words, clone copies references to objects, so you end up with two
references to the same object. Therefore, a cloned object has
references to the same values as the original object.
However, I can’t figure out a way to make a ‘deep copy’ where the object
that a reference refers to is also copied. I tried deleting all the
class variables in the cloned module and then adding them back in with
new values–but they still refer to the same objects as the original
module, which is puzzling.
module A
@@num = 10
@@arr = [1, 2, 3]
def A.get_num
@@num
end
def A.set_num(x)
@@num = x
end
end
puts A.get_num
new_meth = %q{
def B.remove(arr)
arr.each do |name|
remove_class_variable(name.to_sym)
end
end
}
B = A.clone
B.module_eval(new_meth)
class_vars = B.class_variables
B.remove(class_vars)
puts “class variables in B:”
p B.class_variables
class_vars.each do |name|
B.module_eval("#{name} = 0")
end
B.set_num(“hello”)
puts ‘After cloning:’
puts A.get_num
puts B.get_num
A.set_num(“goodbye”)
puts A.get_num
puts B.get_num
–output:–
10
class variables in B:
[]
After cloning:
hello
hello
goodbye
goodbye
The Ruby Way says there is a hack to make deep copies using Marshal, but
it doesn’t work for me:
module A
@@num = 10
@@arr = [1, 2, 3]
def A.get_num
@@num
end
def A.set_num(x)
@@num = x
end
end
puts A.get_num
B = Marshal.load(Marshal.dump(A))
B.set_num(30)
puts “After deep copying:”
puts A.get_num
puts B.get_num
–output:–
10
After deep copying:
30
30