From: Jean-Hugues ROBERT Date: 2002-05-05T01:15:45+09:00 Subject: Re: Class methods defined in a module, how-to ? Hello, At 00:31 05/05/2002 +0900, you wrote: > >> class MyClass > >> extend MyModule > >> end > > > Thanks. However I would like to *include* the module, not extending it. >See the recepie at > http://www.rubycookbook.org/showrecipe.rb?recipeID=166 >// Niklas Thanks. I am using it in my CanValue module. When that module is included by YourClass, YourClass.create( an_obj ) will create a new object using an_obj's instance variables (or .clone() when appropriate). This is the equivalent of C++'s Copy Constructor (a Constructor that create an object whose "value" is the same as the original). Yours, Jean-Hugues # Typical synopsis: # class MyClassWithCopyConstructor # include CanValue # def initialize( some_stuff ) # return self if initValue( some_stuff) # ... init somehow differently here ... # end # ... # end # The module basically makes it easy to write copy constructors. Nota: the new # object is not a deep copy of the original, its instance variables have the # values of the original object's ones. # The module also defines a class.create() method that behaves like the # class's .new() method but will act as a copy constructor if called with # a parameter that is of the same class (or of a class derived from self). # # Bugs: The copy gets the instance variables of the source, including the ones # the ones that were added by derived class. The .create() does not handle # blocks the way .new() does. module CanValue class Value < Hash def toValue() self end end def initValue( a_value ) return nil unless a_value.respond_to? :toValue a_value.toValue().each_pair do | var_name, value | instance_eval "#{var_name}= value" # p "Setting #{var_name} instance variable" end self end def toValue() a_value = Value.new instance_variables().each do | var_name | a_value[var_name.intern()] = instance_eval( var_name) end a_value end # Defines a create() class method that will act as a copy constructor if # called with a parameter that is of the same kind. module ClassMethods def create( *param ) # p "self #{self} is a #{self.class()}" if param.length != 1 then self.new( *param) else if (src = param[1]).kind_of? self then # Use faster .clone() if source object's class is the good one return src.clone() if src.class() == self obj = self.new() src.toValue().each_pair do | var_name, value | obj.instance_eval "#{var_name}= value" end obj else self.new( param[1]) end end end end def self.append_features( includer ) super( includer) includer.extend ClassMethods end end # CanValue ------------------------------------------------------------------------- Web: http://hdl.handle.net/1030.37/1.1 Phone: +33 (0) 4 92 27 74 17