使用现有解决方案在这里扩展我的问题(ruby/rails: extending or including other modules),确定包含模块的最佳方法是什么?
我现在所做的是我在每个模块上定义了实例方法,因此当它们包含在其中时,便可以使用一个方法,然后我在其父模块中添加了一个catcher(method_missing()
),以便可以捕获是否包含它们。我的解决方案代码如下所示:
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
所以在我的模型中,我有:
# 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
然后我可以
Man.new.can_walk?
# => true
Car.new.can_run?
# => true
Car.new.can_walk? # method_missing catches this
# => false
我写的正确吗?或者,还有更好的方法?
最佳答案
如果我正确理解了您的问题,则可以执行以下操作:
Man.included_modules.include?(Features)?
例如:
module M
end
class C
include M
end
C.included_modules.include?(M)
#=> true
如
C.included_modules
#=> [M, Kernel]
其他方法:
正如@Markan所提到的:
C.include? M
#=> true
要么:
C.ancestors.include?(M)
#=> true
要不就:
C < M
#=> true