Skip to content

Instantly share code, notes, and snippets.

@aisuii
Created July 5, 2011 09:05
Show Gist options
  • Save aisuii/1064520 to your computer and use it in GitHub Desktop.
Save aisuii/1064520 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
#
# support_#{feature}? などというメソッドで、
# 機能をサポートしているかどうかを返せるようにするためのモジュール
#
# インクルードしたクラスで
#
# feature :foo, :baa
# feature :hoge, :support => false
# feature :fuga, :support => true
#
# などとすると、以下のようなメッセージを受けられるようになる。
#
# support_foo? #=> false と support_baa? #=> false
# support_hoge? #=> false
# support_fuga? #=> true
#
# 継承したクラスで独自に feature の true/false を上書きできる想定。
# 継承したクラスで feature を追加した場合は、親クラスは false を返せる想定。
#
module FeatureSupport
def self.included(klass)
klass.instance_eval do
class_inheritable_hash :features
def feature(*features_with_options)
features = features_with_options.dup
options = features.extract_options!
symbolized_features = features.map(&:to_sym)
@@features ||= []
@@features |= symbolized_features
feature_support_map = Hash[symbolized_features.map{|feature| [feature, !!options[:support]] }]
write_inheritable_hash :features, feature_support_map
end
end
end
private
def method_missing(name, *args)
respond_to?(name, true) or super
feature_query_method(name)
end
def respond_to?(name, priv = false)
feature_query_method_respond?(name) or super
end
def feature_query_method(method_name)
feature_name = extract_feature_from_query_method_name(method_name)
self.class.features[feature_name]
end
def feature_query_method_respond?(method_name)
feature_name = extract_feature_from_query_method_name(method_name)
return false unless feature_name
@@features.include? feature_name
end
def extract_feature_from_query_method_name(method_name)
match = method_name.to_s.match(/^support_(.+)\?$/)
match ? match[1].to_sym : nil
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment