Reputation: 1638
I have module
module SomeModule
@param = 'Hello'
end
module Reporter
include SomeModule
def self.put
puts @param
end
end
When I call Reporter::put
I get no output, I suppose that Reporter
module has no access to instance variable @param
. Is there any way to access that variable from Reporter
module?
Upvotes: 0
Views: 2164
Reputation: 13487
You can use class variable instead of instanse variable
module SomeModule
@@param = 'Hello'
end
module Reporter
include SomeModule
def self.put
puts @@param
end
end
Reporter.put
prints 123
and returns nil
in this case
Upvotes: 1
Reputation: 369458
Instance variables are called instance variables, because they belong to objects (aka "instances"). There are two objects in your example: SomeModule
and Reporter
. Both have their own instance variables. SomeModule
has an instance variable named @param
and Reporter
has an instance variable named @param
. Those two instance variables are completely unrelated, even though the have the same name. Imagine the chaos, if every object had to come up with its own names for instance variables!
Is there any way to access that variable from
Reporter
module?
No. You cannot access instance variables from different objects. An object only has access to its own instance variables.
[Note: it is possible using reflection (e.g. Object#instance_variable_get
, BasicObject#instance_eval
, or BasicObject#instance_exec
), of course. Lots of things are possible using reflection.]
What you can do, however, is create a method that gives you access to read that instance variable. Such a method is called an attribute reader:
module SomeModule
def self.param; @param end
@param = 'Hello'
end
module Reporter
def self.put
puts SomeModule.param
end
end
There is even a method which automatically generates such methods for you, it is called Module#attr_reader
:
module SomeModule
class << self; attr_reader :param end
@param = 'Hello'
end
module Reporter
def self.put
puts SomeModule.param
end
end
If you want to also write to the instance variable, you also need to define a corresponding attribute writer method:
module SomeModule
class << self
attr_reader :param
private
def param=(param)
@param = param
end
end
self.param = 'Hello'
end
module Reporter
def self.put
puts SomeModule.param
end
end
There is also a corresponding method named Module#attr_writer
which generates an attribute writer method for you:
module SomeModule
class << self
attr_reader :param
private
attr_writer :param
end
self.param = 'Hello'
end
module Reporter
def self.put
puts SomeModule.param
end
end
Upvotes: 0