7stud -- wrote: > Daniel Lucraft wrote: >> Earle Clubb 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 > > > 1) You never cloned A. All you did was create two separate modules > which have similar methods. > > 2) 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 I'm trying a different approach than I was initially, but I get the same result. Instead of cloning the module, I'm generating each copy on the fly. So instead of this: --------------- module A @@str = 'hello' def self.str @@str end def self.str=(s) @@str = s end class Test def self.bye puts "#{self}: bye" end end end B = A.clone puts "A: #{A.str}" puts "B: #{B.str}" B.str = 'test' puts "A: #{A.str}" puts "B: #{B.str}" --- output --- A: hello B: hello A: test B: test --------------- which causes @@str in module B to change if I change it in module A, I'm now doing this: --------------- def define_module Module.new do @@str = 'hello' def self.str @@str end def self.str=(s) @@str = s end const_set(:Test, Class.new do def self.bye puts "#{self}: bye" end end) end end A = define_module B = define_module puts "A: #{A.str}" puts "B: #{B.str}" B.str = 'test' puts "A: #{A.str}" puts "B: #{B.str}" --- output --- A: hello B: hello A: test B: test --------------- Somehow the class variables are still shared between the modules. Earle -- Posted via http://www.ruby-forum.com/.