Class: TrailGuide::Variant
- Inherits:
-
Object
- Object
- TrailGuide::Variant
- Defined in:
- lib/trail_guide/variant.rb
Instance Attribute Summary collapse
-
#experiment ⇒ Object
readonly
Returns the value of attribute experiment.
-
#metadata ⇒ Object
readonly
Returns the value of attribute metadata.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#weight ⇒ Object
readonly
Returns the value of attribute weight.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #===(other) ⇒ Object
-
#as_json(opts = {}) ⇒ Object
export the variant state (not config) as json.
-
#control! ⇒ Object
mark this variant as the control.
-
#control? ⇒ Boolean
check if this variant is the control.
- #converted(checkpoint = nil) ⇒ Object
- #delete! ⇒ Object
- #dup(experiment) ⇒ Object
- #increment_conversion!(checkpoint = nil) ⇒ Object
- #increment_participation! ⇒ Object
-
#initialize(experiment, name, metadata: {}, weight: 1, control: false) ⇒ Variant
constructor
A new instance of Variant.
- #measure(goal = nil, against = nil) ⇒ Object
- #participants ⇒ Object
- #persisted? ⇒ Boolean
- #reset! ⇒ Object
- #save! ⇒ Object
- #storage_key ⇒ Object
- #to_s ⇒ Object
- #unconverted ⇒ Object
-
#variant! ⇒ Object
unmark this variant as the control.
Constructor Details
#initialize(experiment, name, metadata: {}, weight: 1, control: false) ⇒ Variant
Returns a new instance of Variant.
9 10 11 12 13 14 15 |
# File 'lib/trail_guide/variant.rb', line 9 def initialize(experiment, name, metadata: {}, weight: 1, control: false) @experiment = experiment @name = name.to_s.underscore.to_sym = @weight = weight @control = control end |
Instance Attribute Details
#experiment ⇒ Object (readonly)
Returns the value of attribute experiment.
3 4 5 |
# File 'lib/trail_guide/variant.rb', line 3 def experiment @experiment end |
#metadata ⇒ Object (readonly)
Returns the value of attribute metadata.
3 4 5 |
# File 'lib/trail_guide/variant.rb', line 3 def end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
3 4 5 |
# File 'lib/trail_guide/variant.rb', line 3 def name @name end |
#weight ⇒ Object (readonly)
Returns the value of attribute weight.
3 4 5 |
# File 'lib/trail_guide/variant.rb', line 3 def weight @weight end |
Instance Method Details
#==(other) ⇒ Object
17 18 19 20 21 22 23 24 25 |
# File 'lib/trail_guide/variant.rb', line 17 def ==(other) if other.is_a?(self.class) # TODO eventually remove the experiment requirement here once we start # taking advantage of === below return name == other.name && experiment == other.experiment elsif other.is_a?(String) || other.is_a?(Symbol) return name == other.to_s.underscore.to_sym end end |
#===(other) ⇒ Object
27 28 29 30 |
# File 'lib/trail_guide/variant.rb', line 27 def ===(other) return false unless other.is_a?(self.class) return name == other.name && experiment == other.experiment end |
#as_json(opts = {}) ⇒ Object
export the variant state (not config) as json
111 112 113 114 115 116 117 118 119 120 |
# File 'lib/trail_guide/variant.rb', line 111 def as_json(opts={}) if experiment.goals.empty? conversions = converted else conversions = experiment.goals.map { |g| [g.name, converted(g)] }.to_h end { name => { participants: participants, converted: conversions } } end |
#control! ⇒ Object
mark this variant as the control
36 37 38 |
# File 'lib/trail_guide/variant.rb', line 36 def control! @control = true end |
#control? ⇒ Boolean
check if this variant is the control
41 42 43 |
# File 'lib/trail_guide/variant.rb', line 41 def control? !!@control end |
#converted(checkpoint = nil) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/trail_guide/variant.rb', line 71 def converted(checkpoint=nil) if experiment.goals.empty? raise InvalidGoalError, "You provided the checkpoint `#{checkpoint}` but the experiment `#{experiment.experiment_name}` does not have any goals defined." unless checkpoint.nil? (TrailGuide.redis.hget(storage_key, 'converted') || 0).to_i elsif !checkpoint.nil? goal = experiment.goals.find { |g| g == checkpoint } raise InvalidGoalError, "Invalid goal checkpoint `#{checkpoint}` for experiment `#{experiment.experiment_name}`." if goal.nil? (TrailGuide.redis.hget(storage_key, goal.to_s) || 0).to_i else experiment.goals.sum do |goal| (TrailGuide.redis.hget(storage_key, goal.to_s) || 0).to_i end end end |
#delete! ⇒ Object
58 59 60 |
# File 'lib/trail_guide/variant.rb', line 58 def delete! TrailGuide.redis.del(storage_key) end |
#dup(experiment) ⇒ Object
5 6 7 |
# File 'lib/trail_guide/variant.rb', line 5 def dup(experiment) self.class.new(experiment, name, metadata: , weight: weight, control: control?) end |
#increment_conversion!(checkpoint = nil) ⇒ Object
101 102 103 104 105 106 107 108 |
# File 'lib/trail_guide/variant.rb', line 101 def increment_conversion!(checkpoint=nil) if checkpoint.nil? checkpoint = 'converted' else checkpoint = experiment.goals.find { |g| g == checkpoint }.to_s end TrailGuide.redis.hincrby(storage_key, checkpoint, 1) end |
#increment_participation! ⇒ Object
97 98 99 |
# File 'lib/trail_guide/variant.rb', line 97 def increment_participation! TrailGuide.redis.hincrby(storage_key, 'participants', 1) end |
#measure(goal = nil, against = nil) ⇒ Object
90 91 92 93 94 95 |
# File 'lib/trail_guide/variant.rb', line 90 def measure(goal=nil, against=nil) superset = against ? converted(against) : participants converts = converted(goal) return 0 if superset.zero? || converts.zero? converts.to_f / superset.to_f end |
#participants ⇒ Object
67 68 69 |
# File 'lib/trail_guide/variant.rb', line 67 def participants (TrailGuide.redis.hget(storage_key, 'participants') || 0).to_i end |
#persisted? ⇒ Boolean
50 51 52 |
# File 'lib/trail_guide/variant.rb', line 50 def persisted? TrailGuide.redis.exists(storage_key) end |
#reset! ⇒ Object
62 63 64 65 |
# File 'lib/trail_guide/variant.rb', line 62 def reset! delete! save! end |
#save! ⇒ Object
54 55 56 |
# File 'lib/trail_guide/variant.rb', line 54 def save! TrailGuide.redis.hsetnx(storage_key, 'name', name) end |
#storage_key ⇒ Object
126 127 128 |
# File 'lib/trail_guide/variant.rb', line 126 def storage_key "#{experiment.experiment_name}:#{name}" end |
#to_s ⇒ Object
122 123 124 |
# File 'lib/trail_guide/variant.rb', line 122 def to_s name.to_s end |
#unconverted ⇒ Object
86 87 88 |
# File 'lib/trail_guide/variant.rb', line 86 def unconverted participants - converted end |
#variant! ⇒ Object
unmark this variant as the control
46 47 48 |
# File 'lib/trail_guide/variant.rb', line 46 def variant! @control = false end |