I have this module, which gets included in a class:
module MyModule
def self.included base
base.extend ClassMethods
end
module ClassMethods
def my_module_method data
include MyModule::InstanceMethods
after_save :my_module_process
attr_accessor :shared_data
shared_data = data
# instance_variable_set :@shared_data, data
end
end
module InstanceMethods
private
def my_module_process
raise self.shared_data.inspect
# raise instance_variable_get(:@shared_data).inspect
end
end
end
I want to use the data
(parameter) passed to my_module_method
within my_module_process
. I've used attr_accessor
as well as instance variables, but either of them return nil
.
Since you're using rails, your module can be greatly simplified by making it a AS::Concern
module MyModule
extend ActiveSupport::Concern
included do
# after_save :my_module_process # or whatever
cattr_accessor :shared_data
end
module ClassMethods
def my_module_method(data)
self.shared_data = data
end
end
def my_module_process
"I got this shared data: #{self.class.shared_data}"
end
end
The key points here are:
cattr_accessor
, which is similar to attr_accessor
, but defines class-level methodsself.class.shared_data
to access that class-level data from the instances.Usage:
class Foo
include MyModule
end
f = Foo.new
f.my_module_process # => "I got this shared data: "
Foo.my_module_method({foo: 'bar'})
f.my_module_process # => "I got this shared data: {:foo=>\"bar\"}"
I've used attr_accessor as well as instance variables, but either of them return nil.
In ruby, it is super-important to know what is self
at any given moment. This is what defines the methods and instance variables available to you. As an exercise, I offer you to find out, why user.name
returns nil here (and how to fix it).
class User
@name = 'Joe'
def name
@name
end
end
user = User.new
user.name # => nil