Class: Flipflop::FeatureSet

Inherits:
Object
  • Object
show all
Defined in:
lib/flipflop/feature_set.rb

Constant Summary collapse

@@lock =
Monitor.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFeatureSet

Returns a new instance of FeatureSet.



35
36
37
38
39
# File 'lib/flipflop/feature_set.rb', line 35

def initialize
  @features = {}
  @strategies = {}
  @facade = Class.new.new
end

Instance Attribute Details

#facadeObject (readonly)

Returns the value of attribute facade.



33
34
35
# File 'lib/flipflop/feature_set.rb', line 33

def facade
  @facade
end

#raise_strategy_errorsObject

Returns the value of attribute raise_strategy_errors.



31
32
33
# File 'lib/flipflop/feature_set.rb', line 31

def raise_strategy_errors
  @raise_strategy_errors
end

Class Method Details

.currentObject



24
25
26
# File 'lib/flipflop/feature_set.rb', line 24

def current
  @current or @@lock.synchronize { @current ||= new }
end

Instance Method Details

#add(feature) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/flipflop/feature_set.rb', line 67

def add(feature)
  @@lock.synchronize do
    if @features.has_key?(feature.key)
      raise FeatureError.new(feature.key, "already defined")
    end
    @features[feature.key] = feature.freeze

    @facade.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
      def #{feature.key}?
        FeatureSet.current.enabled?(:#{feature.key})
      end
    RUBY
  end
end

#clear!(feature_key, strategy_key) ⇒ Object



131
132
133
134
135
136
# File 'lib/flipflop/feature_set.rb', line 131

def clear!(feature_key, strategy_key)
  strategy = strategy(strategy_key)
  feature = feature(feature_key)

  strategy.clear!(feature.key)
end

#configure(&block) ⇒ Object



41
42
43
44
45
46
47
# File 'lib/flipflop/feature_set.rb', line 41

def configure(&block)
  Module.new do
    extend Configurable
    instance_exec(&block)
  end
  self
end

#enabled?(feature_key) ⇒ Boolean

Returns:

  • (Boolean)


91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/flipflop/feature_set.rb', line 91

def enabled?(feature_key)
  FeatureCache.current.fetch(feature_key) do
    feature = feature(feature_key)

    result = @strategies.each_value.inject(nil) do |status, strategy|
      break status unless status.nil?
      strategy.enabled?(feature_key)
    end

    result.nil? ? feature.default : result
  end
end

#feature(feature_key) ⇒ Object



104
105
106
107
108
# File 'lib/flipflop/feature_set.rb', line 104

def feature(feature_key)
  @features.fetch(feature_key) do
    raise FeatureError.new(feature_key, "unknown")
  end
end

#featuresObject



110
111
112
# File 'lib/flipflop/feature_set.rb', line 110

def features
  @features.values
end

#replaceObject



49
50
51
52
53
54
55
56
57
58
# File 'lib/flipflop/feature_set.rb', line 49

def replace
  @@lock.synchronize do
    initialize
    yield if block_given?
    @features.freeze
    @strategies.freeze
    @facade.class.freeze
  end
  self
end

#strategiesObject



120
121
122
# File 'lib/flipflop/feature_set.rb', line 120

def strategies
  @strategies.values
end

#strategy(strategy_key) ⇒ Object



114
115
116
117
118
# File 'lib/flipflop/feature_set.rb', line 114

def strategy(strategy_key)
  @strategies.fetch(strategy_key) do
    raise StrategyError.new(strategy_key, "unknown")
  end
end

#switch!(feature_key, strategy_key, value) ⇒ Object



124
125
126
127
128
129
# File 'lib/flipflop/feature_set.rb', line 124

def switch!(feature_key, strategy_key, value)
  strategy = strategy(strategy_key)
  feature = feature(feature_key)

  strategy.switch!(feature.key, value)
end

#test!(strategy = Strategies::TestStrategy.new) ⇒ Object



60
61
62
63
64
65
# File 'lib/flipflop/feature_set.rb', line 60

def test!(strategy = Strategies::TestStrategy.new)
  @@lock.synchronize do
    @strategies = { strategy.key => strategy.freeze }.freeze
  end
  strategy
end

#use(strategy) ⇒ Object



82
83
84
85
86
87
88
89
# File 'lib/flipflop/feature_set.rb', line 82

def use(strategy)
  @@lock.synchronize do
    if @strategies.has_key?(strategy.key)
      raise StrategyError.new(strategy.name, "(#{strategy.class}) already defined with identical options")
    end
    @strategies[strategy.key] = strategy.freeze
  end
end