class Experiment

Constants

DEFAULT_COMPARISON
DEFAULT_ENABLER

Public Class Methods

new(name) click to toggle source
# File lib/experiment.rb, line 30
def initialize(name)
  @name = name
  @compare_with = DEFAULT_COMPARISON
  @enable = DEFAULT_ENABLER
end
protocol(name) { |experiment| ... } click to toggle source
# File lib/experiment.rb, line 5
def protocol(name)
  name = String(name)
  raise('Please provide an experiment name') if name.empty?
  experiment = Experiment.new(name)
  yield(experiment)
  experiment.raise_on_diff! if rails_test_mode?
  experiment.result
end
rails_test_mode?() click to toggle source
# File lib/experiment.rb, line 14
def rails_test_mode?
  defined?(Rails) && Rails.env.test?
end

Public Instance Methods

compare_with(&block) click to toggle source
# File lib/experiment.rb, line 48
def compare_with(&block)
  raise 'Missing block' unless block
  @compare_with = block
  self
end
enable(&block) click to toggle source
# File lib/experiment.rb, line 54
def enable(&block)
  raise 'Missing block' unless block
  @enable = block
  self
end
experiment(&block) click to toggle source
# File lib/experiment.rb, line 42
def experiment(&block)
  raise 'Missing block' unless block
  @experiment = block
  self
end
legacy(&block) click to toggle source
# File lib/experiment.rb, line 36
def legacy(&block)
  raise 'Missing block' unless block
  @legacy = block
  self
end
on_diff(&block) click to toggle source
# File lib/experiment.rb, line 60
def on_diff(&block)
  raise 'Missing block' unless block
  @on_diff = block
  self
end
raise_on_diff!() click to toggle source
# File lib/experiment.rb, line 82
def raise_on_diff!
  on_diff do |legacy_result, experiment_result|
    raise ExperimentError,
      "Experiment: #{@name}; "\
      "Legacy result: #{legacy_result.inspect}; "\
      "Experiment result: #{experiment_result.inspect}"
  end
end
result() click to toggle source
# File lib/experiment.rb, line 66
def result
  raise 'Please call the legacy helper in your protocol block' unless @legacy
  raise 'Please call the experiment helper in your protocol block' unless @experiment
  legacy_result = exec(@legacy)
  return forward(legacy_result) unless self.class.rails_test_mode? || @enable.call
  experiment_result = exec(@experiment)
  if @on_diff
    if legacy_result.error.class != experiment_result.error.class ||
        legacy_result.error&.message != experiment_result.error&.message ||
        !@compare_with.call(legacy_result.value, experiment_result.value)
      @on_diff.call(legacy_result, experiment_result)
    end
  end
  forward(legacy_result)
end

Private Instance Methods

exec(block) click to toggle source
# File lib/experiment.rb, line 98
def exec(block)
  Result.new(value: block.call)
rescue StandardError => error
  Result.new(error: error)
end
forward(result) click to toggle source
# File lib/experiment.rb, line 93
def forward(result)
  raise result.error if result.error
  result.value
end