Espandendo qui la mia domanda (ruby/rails: extending or including other modules), utilizzando la mia soluzione esistente, qual è il modo migliore per determinare se il mio modulo è incluso?ruby / rails: come determinare se il modulo è incluso?
Quello che ho fatto per ora è stato definire i metodi di istanza su ciascun modulo in modo che quando vengono inclusi sia disponibile un metodo, quindi ho aggiunto un catcher (method_missing()
) al modulo genitore in modo da poter rilevare se non lo sono incluso. Il mio codice soluzione si presenta come:
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
Così nei miei modelli che ho:
# 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
E poi posso
Man.new.can_walk?
# => true
Car.new.can_run?
# => true
Car.new.can_walk? # method_missing catches this
# => false
ho scritto questo in modo corretto? O c'è un modo migliore?
La questione è un po 'contorto, quindi non sono sicuro se questo è quello che stai cercando, ma per controllare se un modello è incluso puoi fare 'object.class.include? Module' – makhan
È possibile utilizzare 'respond_to?' Per verificare se un metodo è disponibile. – Lesleh