Expanding on my question here (ruby/rails: extending or including other modules), using my existing solution, what's the best way to determine if my module is included?
What I did for now was I defined instance methods on each module so when they get included a method would be available, and then I just added a catcher (method_missing()
) to the parent module so I can catch if they are not included. My solution code looks like:
module Features FEATURES = [Running, Walking] # include Features::Running FEATURES.each do |feature| include feature end module ClassMethods # include Features::Running::ClassMethods FEATURES.each do |feature| include feature::ClassMethods end end module InstanceMethods def method_missing(meth) # Catch feature checks that are not included in models to return false if meth[-1] == '?' && meth.to_s =~ /can_(\w+)\z?/ false else # You *must* call super if you don't handle the method, # otherwise you'll mess up Ruby's method lookup super end end end def self.included(base) base.send :extend, ClassMethods base.send :include, InstanceMethods end end # lib/features/running.rb module Features::Running module ClassMethods def can_run ... # Define a method to have model know a way they have that feature define_method(:can_run?) { true } end end end # lib/features/walking.rb module Features::Walking module ClassMethods def can_walk ... # Define a method to have model know a way they have that feature define_method(:can_walk?) { true } end end end
So in my models I have:
# Sample models class Man < ActiveRecord::Base # Include features modules include Features # Define what man can do can_walk can_run end class Car < ActiveRecord::Base # Include features modules include Features # Define what man can do can_run end
And then I can
Man.new.can_walk? # => true Car.new.can_run? # => true Car.new.can_walk? # method_missing catches this # => false
Did I write this correctly? Or is there a better way?
What is the difference between a class and a module? Modules are collections of methods and constants. They cannot generate instances. Classes may generate instances (objects), and have per-instance state (instance variables).
A Module is a collection of methods, constants, and class variables. Modules are defined as a class, but with the module keyword not with class keyword. Important Points about Modules: You cannot inherit modules or you can't create a subclass of a module. Objects cannot be created from a module.
Dissecting Ruby on Rails 5 - Become a Professional Developer Modules are a way of grouping together methods, classes, and constants. Modules give you two major benefits. Modules provide a namespace and prevent name clashes. Modules implement the mixin facility.
If I understand your question correctly, you can use Module#include?
:
Man.include?(Features)
For example:
module M end class C include M end C.include?(M) # => true
Module#included_modules
This works, but it's a bit more indirect, since it generates intermediate included_modules
array.
C.included_modules.include?(M) # => true
since C.included_modules
has a value of [M, Kernel]
Module#ancestors
C.ancestors.include?(M) #=> true
since C.ancestors
has a value of [C, M, Object, Kernel, BasicObject]
<
The Module
class also declares several comparison operators:
Module#<
Module#<=
Module#==
Module#>=
Module#>
Example:
C < M # => true
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