Instance variables in modules?
Think of the instance variable as something which will exist in any class that includes your module, and things make a bit more sense:
module Stacklike def stack @stack ||= [] end def add_to_stack(obj) stack.push(obj) end def take_from_stack stack.pop endendclass ClownStack include Stacklike def size @stack.length endendcs = ClownStack.newcs.add_to_stack(1)puts cs.size
will output "1"
See the below:
p RUBY_VERSIONmodule Stacklike def stack @stack ||= [] end def add_to_stack(obj) stack.push(obj) end def take_from_stack stack.pop endendclass Ainclude Stacklikeenda = A.newp a.instance_variables #<~~ Ep a.instance_variable_defined?(:@stack) #<~~ Aa.add_to_stack(10) #<~~ Bp a.instance_variable_defined?(:@stack) #<~~ Cp a.instance_variables #<~~ D
Output:
"1.9.3"[]falsetrue[:@stack]
Explanation: Yes, Module
instance variables are present in the class
when you would include
them inside the class. But you can see that p a.instance_variable_defined?(:@stack)
is showing false
as @stack
is still not defined till A. At point B I defined the instance variable @stack. Thus statement in point C, outputs as true
. Means module instance variables are not being created by the module itself,but that can be done by the class
instances if the class
included that module. Statement in E outputs []
as still that point the instance variable was not defined, but if you see the output for the line D, it is proved the @stack
is inside the object a
of class A
.
Why such design?
This is the design or sometimes come from the requirements. Say you have been asked to write a stack operation code which will be used by two ticket booking companies,Say A
and B
. Now A
are stack policy for their customers to serve but also they have any more formalities with that. B
company also using stack policy with their own formalities which is different from A
. Thus in case of designing Stack
operation inside class A
and class B
, better idea to write it in a common place,as Both A
and B
have this functionality common within them. In future if another company C
comes to you you can also use that module into their class, without rewriting the same functionality for each A
,B
and C
. There can be more thoughts but hope this will help you to answer your self for your last part of the questions.
That's all about the concept. Hope it helps.
Cheers!!