Skip to main content

Does Instance Variables of a module shared between class with the mixin?

I want to know how the instance variables of a Ruby module behaves across multiple classes which 'mix' it 'in'. I wrote a sample code to test it:

# Here is a module I created with one instance variable and two instance methods.
module SharedVar
  @color = 'red'
  def change_color(new_color)
    @color = new_color
  end
  def show_color
    puts @color
  end
end

class Example1
  include SharedVar
  def initialize(name)
    @name     = name
  end
end

class Example2
  include SharedVar
  def initialize(name)
    @name     = name
  end
end

ex1 = Example1.new("Bicylops")
ex2 = Example2.new("Cool")

# There is neither output or complains about the following method call.
ex1.show_color
ex1.change_color('black')
ex2.show_color

Why it doesn't work? And Could someone explain what will the actual behavior of @color across multiple Example$ instances?

Solved

In Ruby modules and classes are objects, so it's possible to set instance variables for them.

module Test
  @test = 'red'
  def self.print_test
    puts @test
  end
end

Test.print_test #=> red

Your mistake is thinking that the variable @color is the same for:

module SharedVar
  @color
end

and

module SharedVar
  def show_color
    @color
  end
end

which is not.

In the first example, the instance variable belongs to the SharedVar object and in the second example the instance variable belongs to the object you include the module in.

Another explanation by self pointer. In the first example the self pointer is set to the module object SharedVar, so typing @color will refer to the object SharedVar and there's no connection with another object. In the second example, the method show_color can be called only on some object, i.e. ex1.show_color, so the self pointer will point to ex1 object. So in this case the instance variable will refer to ex1 object.


You have included a module in to a class.. so the instance variable @color should be an instance variable of both the class Example1 and Example2

So if you want to access the @color variable means you suppose to create an object to the class and then you can accesss it

For Ex

irb(main):028:0> ex1.change_color('black')
=> "black"
irb(main):029:0> ex1.show_color
black
irb(main):031:0> ex2.change_color('red')
=> "red"
irb(main):032:0> ex2.show_color
red

Comments

Popular posts from this blog

How to declare a custom class in google scripts?

I want to create a class inside my script. Google Apps Script language is based on javaScript, so I took an example from a javaScript manual: class Polygon { constructor(height, width) { this.height = height; this.width = width; } } However, this doesn't work. I get this error message: Missing ; before statement. (line 1, file "Code") Does that mean it's not possible to create new classes in google scripts? Or is there a different syntax I'm supposed to use? Solved Historically Javascript is a "classless" language, classes are a newer feature which haven't been widely adopted yet, and apparently are not yet supported by Apps Script. Here's an example of how you can imitate class behaviour in Apps Script: var Polygon = function(height, width){ this.height = height; this.width = width; this.logDimension = function(){ Logger.log(this.height); Logger.log(this.width); } }; function testPoly(){ v...

Java - 404 after deploying servlet to Glassfish

I'm pretty new to servlets in Java and i was trying to deploy the following servlet with this GET method: protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); response.setContentType("text/html"); out.println(" "); out.println(" Welcome! "); out.println(" "); } I checked the console and it was deployed successfully, no errors. However, when i open my browser and go to: http://localhost:8080/web1/AddPassenger I get the HTTP Status 404 - Not Found error. What could be the problem? EDIT: Content of glassfish-web.xml : /Web1 Solved I'm not sure what was the problem, but i installed a new version of Eclipse (Oxygen, i used Mars before that) and it worked! Many thanks to everyone for their help!