Module: Frequency
Overview
A small DSL to execute blocks with controlled probability.
require "frequency"
# Module-function style:
Frequency.sometimes { puts "maybe" }
Frequency.rarely(with_probability: 0.01) { log_sample(event) }
Frequency.normally(with_probability: "24%") { do_thing }
# Or mixin style:
include Frequency
sometimes { puts "maybe" }
Constant Summary collapse
- VERSION =
"0.2.0"- Error =
Base error class. Catch this to handle any Frequency-raised error.
Class.new(StandardError)
- InvalidProbabilityError =
Raised when the probability value is not a number/string in [0, 1].
Class.new(Error)
- DEFAULTS =
{ normally: 0.75, sometimes: 0.50, rarely: 0.25 }.freeze
- PERCENT_PATTERN =
/\A-?\d+(?:\.\d+)?%\z/
Class Attribute Summary collapse
Class Method Summary collapse
- .__run(probability, &block) ⇒ Object private
-
.with_seed(seed) ⇒ Object
Run a block with a temporarily-seeded RNG, then restore the previous one.
Instance Method Summary collapse
-
#always ⇒ Object
Always run the block.
-
#never ⇒ Object
Never run the block.
-
#normally(with_probability: DEFAULTS[:normally], &block) ⇒ Object
Run the block ~75% of the time by default.
-
#rarely(with_probability: DEFAULTS[:rarely], &block) ⇒ Object
Run the block ~25% of the time by default.
-
#sometimes(with_probability: DEFAULTS[:sometimes], &block) ⇒ Object
(also: #maybe)
Run the block ~50% of the time by default.
Class Attribute Details
.random ⇒ Object
71 72 73 |
# File 'lib/frequency.rb', line 71 def random @random ||= Random.new end |
Class Method Details
.__run(probability, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
86 87 88 89 90 91 92 93 94 95 |
# File 'lib/frequency.rb', line 86 def __run(probability, &block) return nil unless block rate = __coerce(probability) unless (0.0..1.0).cover?(rate) raise InvalidProbabilityError, "probability must be in [0, 1], got #{rate}" end block.call if random.rand < rate end |
.with_seed(seed) ⇒ Object
Run a block with a temporarily-seeded RNG, then restore the previous one.
Frequency.with_seed(42) { sometimes { ... } }
77 78 79 80 81 82 83 |
# File 'lib/frequency.rb', line 77 def with_seed(seed) previous = @random @random = Random.new(seed) yield ensure @random = previous end |
Instance Method Details
#always ⇒ Object
Always run the block. Returns the block’s value, or nil if no block.
33 34 35 |
# File 'lib/frequency.rb', line 33 def always yield if block_given? end |
#never ⇒ Object
Never run the block. Returns nil. Ignores any arguments/block.
38 39 40 |
# File 'lib/frequency.rb', line 38 def never(*) nil end |
#normally(with_probability: DEFAULTS[:normally], &block) ⇒ Object
Run the block ~75% of the time by default.
43 44 45 |
# File 'lib/frequency.rb', line 43 def normally(with_probability: DEFAULTS[:normally], &block) Frequency.__run(with_probability, &block) end |