Ruby: Allocate another memory for included module variables -
Ruby: Allocate another memory for included module variables -
i have simple module , 3 classes:
module initsubclass @@subclass_instances = [] def initialize super @@subclass_instances << self end def self.instances? @@subclass_instances end end class animal attr_reader :type @@animal_instances = [] def self.instances? @@animal_instances end def initialize @type = self.class @@animal_instances << self puts "a new #{self} has been instantiated." end end class cow < animal include initsubclass end class dog < animal include initsubclass end now run:
cow = cow.new puts cow.type dog1 = dog.new dog2 = dog.new puts animal.instances?.inspect puts cow.instances?.inspect puts dog.instances?.inspect and output:
a new #<cow:0x000000028520a8> has been instantiated. cow new #<dog:0x00000002851f40> has been instantiated. new #<dog:0x00000002851e78> has been instantiated. [#<cow:0x000000028520a8 @type=cow>, #<dog:0x00000002851f40 @type=dog>, #<dog:0x0 0000002851e78 @type=dog>] [#<cow:0x000000028520a8 @type=cow>, #<dog:0x00000002851f40 @type=dog>, #<dog:0x0 0000002851e78 @type=dog>] [#<cow:0x000000028520a8 @type=cow>, #<dog:0x00000002851f40 @type=dog>, #<dog:0x0 0000002851e78 @type=dog>] this means uses same @@subclass_instances variable. if re-create code module , duplicate in subclasses works fine:
a new #<cow:0x000000028520a8> has been instantiated. cow new #<dog:0x00000002851f40> has been instantiated. new #<dog:0x00000002851e78> has been instantiated. [#<cow:0x000000028520a8 @type=cow>, #<dog:0x00000002851f40 @type=dog>, #<dog:0x0 0000002851e78 @type=dog>] [#<cow:0x000000028520a8 @type=cow>] [#<dog:0x00000002851f40 @type=dog>, #<dog:0x00000002851e78 @type=dog>] how can tell allocate var every include module ? thanks.
if overall goal track instances of , animals, can without module.
class animal attr_reader :type def self.instances @instances ||= [] end def initialize @type = self.class self.class.instances << self self.class.superclass.instances << self puts "a new #{self} has been instantiated." end end class cow < animal end class dog < animal end when executed:
a new #<cow:0x3c7bc48> has been instantiated. cow new #<dog:0x3c7bab0> has been instantiated. new #<dog:0x3c7b9f0> has been instantiated. dog instances: [#<cow:0x3c7bc48 @type=cow>, #<dog:0x3c7bab0 @type=dog>, #<dog:0x3c7b9f0 @type=dog>] [#<cow:0x3c7bc48 @type=cow>] [#<dog:0x3c7bab0 @type=dog>, #<dog:0x3c7b9f0 @type=dog>] it possible functionality through module. lastly example, goal set instance variables on class (specifically on eigenclass class). also, because need class methods , instance methods, using little trick include , extend.
module initsubclass def self.included base of operations base.extend initeigensubclass end def initialize super self.class.instance_variable_set(:@instances, (self.class.instance_variable_get(:@instances) || [])<< self) end module initeigensubclass def instances @instances end end end ruby
Comments
Post a Comment