Sorry if the title is a bit misleading, but this post talks about the scenario such that I have several classes, all extending the same module, and I need to avoid using shared or class variables (@@) in the module because the classes extending the module may change the shared or class variable at the same time and cause problem.
So basically we have:
class Test
extend TestModule
end
class TestTwo
extend TestModule
end
module TestModule
@@val
def somemethod
#do something with @@val
end
end
And the goal is the replace the @@val class variable with a class instance variable so that if the Test.somemethod and TestTwo.somemethod happens at the same time, there won’t be any problem.
The easiest way (I can think of) of doing this is to set the variable within the class, instead of setting it in the module. For example:
class Test
@val = “abc”
class << self; attr_accessor :val; end
extend TestModule
end
But the problem of doing this is that everybody else using TestModule will need to update their code after this update, which is unacceptable.
Is there a way to move the variable definition and accessor to the module and has exactly the same effect as defining them in the class? Yes. define the self.extended(base) method.
module TestModule
def self.extended(base)
class << base; attr_accessor :val; end
base.val = “abc”
end
def somemethod
#do something with self.val
end
end
class Test
extend TestModule
end
Here base refers to the class extending this module. self. extended is called when the module is initialized, and the accessors for the base class is then created (class << base; attr_accessor :val; end), base.val = abc sets the default value.
By doing it this way, the module works exactly the same as before, and multiple classes can extend it and call the same method without affecting each other.
Hope this helps.
dfffd
Nice writeup…
Do take a look at this:
http://adhirajrankhambe.wordpress.com/2009/01/04/a-word-about-modules-in-ruby/
This was exactly what I was looking for. Thank you.