Created
July 5, 2011 09:05
-
-
Save aisuii/1064520 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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