I am using Ruby on Rails 3.2.2. I am implementing a module and including that in a my class by using the RoR ActiveSupport::Concern feature. It makes available the included do ... end
block making code stated inside that to be executed in the class context of the class where the module is included.
My doubt is: What should I not include in the included do ... end
block? That is, for instance, is it a "common" / "good" practice to make the following?
module MyModule
extend ActiveSupport::Concern
class MyModuleClass
attr_accessor :attr1, :attr2, :attr3
def initialize(attrs)
@attr1 = attrs[:attr1]
@attr2 = attrs[:attr2]
@attr3 = attrs[:attr3]
end
end
included do
@my_module_class = MyModuleClass.new(some_attrs)
end
end
More, will be the @my_module_class
variable available as an attribute in the including class of MyModule
(BTW: I would like to make the @my_module_class
to be "visible" only internally to MyModule
since it is intended to be used only in that module)? Are there some "advanced" examples or tutorials on how to handle situations like that I am trying to instantiate in the included do ... end
block of the above code? What do you advice about?
It is a bit of Rails carbohydrates sprinkled upon a Ruby module. What ActiveSupport::Concern does for you is it allows you to put code that you want evaluated inside the included block. For example, you want to extract the trashing logic out of your model.
include is the standard Ruby idiom for mixing in methods from a module to a class and you should stick to it.
Ruby's BEGIN and END blocks (in uppercase) are reserved keywords in Ruby and are pretty straightforward to use. They enable you to specify blocks of code that you want your program to run at the beginning and end of its execution, regardless of their position in the source file.
@my_class will be an instance of MyClass and not MyModule. If you want to make all instances of MyClass be an instance of MyModule you should write:
include MyModule
inside the class definition.
I think my answer makes sense if you look at the original version of this question before it was edited.
EDIT 1:
Let's add on to your example and say you have a class called Foo:
class Foo
include MyModule
end
You want to make an instance of MyModuleClass that is associated with Foo but it sounds like you don't really want to modify Foo or give it access to the MyModuleClass. I propose that you use a hash table:
module MyModule
# ...
@hash = {}
class << self
attr_accessor :hash
end
included do
MyModule.hash[self] = MyModuleClass.new(some_attrs)
end
end
I think that will work, and it avoids adding an instance variable to to the Foo
class object. Technically, any part of the ruby code can access MyModule.hash but you should put a comment in the source code telling people NOT to do that, and don't advertise that the hash exists.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With