From: Freeman Pascal Date: 2001-03-13T17:09:52+09:00 Subject: [ruby-talk:12561] RE: Accessing caller of include or extend... My apologies, I seem to have slaughtered the case..when...end structure below in my code please do the appropriate regex in your head as you read it =) -Freeman -----Original Message----- From: Freeman Pascal [mailto:pascal@pascal.org] Sent: Monday, March 12, 2001 11:35 PM To: ruby-talk ML Cc: Freeman P Pascal IV Subject: [ruby-talk:12557] Accessing caller of include or extend... Hi, I'm fairly new to Ruby and OO in general, but have read the pickaxe book through twice already and have been browsing the mailing list archives. I have a couple of questions for the more seasoned Ruby users. First, when creating a module for inclusion by a class, is there a way to initialize module instance variables being added to the including class? The following does not work (though runs without error) and I now understand it's because I'm adding the instance variables to the module class not the module I'm creating: module ThreeDSpace @position = Vector.new () # current position @vector = Vector.new () # speed and heading attr_accessor :position attr_accessor :vector end class MyEntity include ThreeDSpace end ball = MyEntity.new Sphere p ball.position # -> nil p ball.vector # -> nil ball.position = Vector.new (0,0,0) p ball.position # -> [Vector: @x=0, @y=0, @z=0] This seems counter intuitive and surprised me. I was expecting to have my instance variables initialized and available to the accessors much the same way that method variables (@@symbol) are. I naively tried even adding an "initialize" method to the module which didn't work. How does one initialize module instance variables without resorting to defining a method to do so and calling it within the class after including the module? Second, is there a way to determine within the module definition at run-time who the including class is (i.e. who called "include")? I'd like to use modules to implement feature sets that extend my classes, but don't want to resort to uniquely identifying and including modules that are tightly coupled to the including class. module ThreeDSpace switch (self.including_class) # NO SUCH METHOD! with VEEnvironment # Environment extensions here with Entity attr_accessor :position # Vector attr_accessor :velocity # Vector end end module Simple Gravity switch (self.including_class) # NO SUCH METHOD!!! with VEEnvironment def simple gravity (entity) # implementation of simple gravity end VEEnvironment.register_law (simple_gravity) with VEEntity attr_accessor :simple_gravity_exempt end end class VEEnvironment # Base class for simulated environment def register_law (&proc) # ... end def add_entity (entity) # ... end end class VEEntity # base class for simulated entities end class MyEnvironment << VEEnvironment include ThreeDSpace include SimpleGravity end class MyEntity << VEEntity include ThreeDSpace include SimpleGravity end env = MyEnvironment.new ball = MyEntity.new env.add_entity ball The closest I've been able to come to doing this is providing modules specific to the class doing the inclusion and specifically including that module within the class. Ideally, I did like to see something like: method SimpleGravity extend VEEnvironment def simple_gravity (entity) # ... end extend VEEntity attr_accessor :simple_gravity_exempt end -Freeman