Nuo Yan

Problem Solved

Recent Posts

Tags

News


  • Follow me on twitter: @nuoyan
    Make a donation to this Blog by PayPal. Thanks!






    Nuo is currently a Software Development Engineer in a Seattle-based software company.




    Locations of visitors to this page

    The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my school or employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.


Community

Email Notifications

Archives

August 2009 - Posts

Class instance variable for ruby modules

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.