109: def feature_module
110: unless defined? @feature_module
111: @features ||= {}
112: @feature_module = ::Module.new
113: const_set("FeatureModule", @feature_module)
114: features = @features
115:
116:
117: @feature_module.send(:define_method, :feature?) do |name|
118: method = name.to_s + "?"
119: if respond_to?(method) and send(method)
120: return true
121: else
122: return false
123: end
124: end
125:
126:
127: @feature_module.send(:define_method, :features) do
128: return false unless defined?(features)
129: features.keys.find_all { |n| feature?(n) }.sort { |a,b|
130: a.to_s <=> b.to_s
131: }
132: end
133:
134:
135:
136: @feature_module.send(:define_method, :satisfies?) do |*needed|
137: ret = true
138: needed.flatten.each do |feature|
139: unless feature?(feature)
140: ret = false
141: break
142: end
143: end
144: ret
145: end
146:
147:
148:
149: @features.each do |name, feature|
150: method = name.to_s + "?"
151: @feature_module.send(:define_method, method) do
152: (is_a?(Class) ? declared_feature?(name) : self.class.declared_feature?(name)) or feature.available?(self)
153: end
154: end
155:
156:
157: @feature_module.send(:define_method, :has_features) do |*names|
158: @declared_features ||= []
159: names.each do |name|
160: name = symbolize(name)
161: @declared_features << name
162: end
163: end
164:
165: @feature_module.send(:alias_method, :has_feature, :has_features)
166: end
167: @feature_module
168: end