在这里扩展我的问题(ruby/rails:扩展或包含其他模块 https://stackoverflow.com/questions/28575328/ruby-rails-extending-or-including-other-modules),使用我现有的解决方案,确定我的模块是否包含在内的最佳方法是什么?
我现在所做的是在每个模块上定义实例方法,这样当它们被包含时,一个方法就可用,然后我只是添加了一个捕手(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
我写得对吗?或者,还有更好的方法?
如果我正确理解你的问题,你可以使用Module#include? https://ruby-doc.org/core-3.0.0/Module.html#method-i-include-3F:
Man.include?(Features)
例如:
module M
end
class C
include M
end
C.include?(M) # => true
其他方法
检查Module#included_modules https://ruby-doc.org/core-3.0.0/Module.html#method-i-included_modules
这是可行的,但它有点间接,因为它生成中间included_modules
array.
C.included_modules.include?(M) # => true
since C.included_modules
值为[M, Kernel]
检查Module#ancestors https://ruby-doc.org/core-3.0.0/Module.html#method-i-ancestors
C.ancestors.include?(M) #=> true
since C.ancestors
值为[C, M, Object, Kernel, BasicObject]
使用像这样的运算符<
The Module
类还声明了几个比较运算符:
- Module#< https://ruby-doc.org/core-3.0.0/Module.html#method-i-3C
- Module#<= https://ruby-doc.org/core-3.0.0/Module.html#method-i-3C-3D
- Module#== https://ruby-doc.org/core-3.0.0/Module.html#method-i-3D-3D
- Module#>= https://ruby-doc.org/core-3.0.0/Module.html#method-i-3E-3D
- Module#> https://ruby-doc.org/core-3.0.0/Module.html#method-i-3E
Example:
C < M # => true
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)