Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ruby/rails: How to determine if module is included?

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?

like image 606
index Avatar asked Feb 23 '15 05:02

index


People also ask

What is the difference between a class and a module Ruby?

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).

What is module in Ruby?

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.

What is module function in Ruby on Rails?

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.


1 Answers

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 

Other ways

Checking 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]

Checking Module#ancestors

C.ancestors.include?(M) #=> true 

since C.ancestors has a value of [C, M, Object, Kernel, BasicObject]

Using operators like <

The Module class also declares several comparison operators:

  • Module#<
  • Module#<=
  • Module#==
  • Module#>=
  • Module#>

Example:

C < M # => true  
like image 151
Cary Swoveland Avatar answered Oct 02 '22 13:10

Cary Swoveland