Class: ConsistentRandom
- Inherits:
-
Object
- Object
- ConsistentRandom
- Defined in:
- lib/consistent_random.rb,
lib/consistent_random/active_job.rb,
lib/consistent_random/rack_middleware.rb,
lib/consistent_random/sidekiq_middleware.rb,
lib/consistent_random/sidekiq_client_middleware.rb
Defined Under Namespace
Modules: ActiveJob Classes: RackMiddleware, SidekiqClientMiddleware, SidekiqMiddleware
Class Method Summary collapse
-
.current_seed ⇒ String?
private
Get the current seed used to generate random numbers.
-
.scope(seed = nil) { ... } ⇒ Object
Define a scope where consistent random values will be generated.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
True if the other object is a ConsistentRandom that returns the same random number generator.
-
#bytes(size) ⇒ String
Generate a random array of bytes.
-
#initialize(name) ⇒ ConsistentRandom
constructor
A new instance of ConsistentRandom.
-
#rand(max = nil) ⇒ Numeric
Generate a random number.
-
#random ⇒ Random
Generate a random number generator for the given name.
-
#seed ⇒ Integer
Generate a seed that can be used to generate random numbers.
Constructor Details
#initialize(name) ⇒ ConsistentRandom
Returns a new instance of ConsistentRandom.
57 58 59 |
# File 'lib/consistent_random.rb', line 57 def initialize(name) @name = name end |
Class Method Details
.current_seed ⇒ String?
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.
Get the current seed used to generate random numbers. This will return nil if called outside of a scope.
51 52 53 |
# File 'lib/consistent_random.rb', line 51 def current_seed Thread.current[:consistent_random_seed] end |
.scope(seed = nil) { ... } ⇒ Object
Define a scope where consistent random values will be generated.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/consistent_random.rb', line 24 def scope(seed = nil) existing_seed = Thread.current[:consistent_random_seed] seed_value = case seed when nil existing_seed || SecureRandom.hex when String, Symbol, Integer seed.to_s when Array seed.map { |s| s.to_s }.join("\x1C") else raise ArgumentError, "Invalid seed value: #{seed.inspect}" end begin Thread.current[:consistent_random_seed] = seed_value yield ensure Thread.current[:consistent_random_seed] = existing_seed end end |
Instance Method Details
#==(other) ⇒ Boolean
Returns true if the other object is a ConsistentRandom that returns the same random number generator. If called outside of a scope, then it will always return false.
105 106 107 |
# File 'lib/consistent_random.rb', line 105 def ==(other) other.is_a?(self.class) && other.seed == seed end |
#bytes(size) ⇒ String
Generate a random array of bytes. The same number will be generated within a scope block. This method works the same as Random#bytes.
87 88 89 90 91 |
# File 'lib/consistent_random.rb', line 87 def bytes(size) bytes = [] ((size + 19) / 20).times { |i| bytes << seed_hash("#{@name}#{i}").to_s } bytes.join[0, size] end |
#rand(max = nil) ⇒ Numeric
Generate a random number. The same number will be generated within a scope block. This method works the same as Kernel#rand. It will generate a consistent value even across Ruby versions and platforms.
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/consistent_random.rb', line 70 def rand(max = nil) value = seed / SEED_DIVISOR case max when nil value when Numeric (value * max.to_i).to_i when Range cap_to_range(value, max) end end |
#random ⇒ Random
Generate a random number generator for the given name. The generator will always have the same seed within a scope.
This value is dependent on the Ruby Random class and may not generate consistent values across Ruby versions and platforms.
116 117 118 |
# File 'lib/consistent_random.rb', line 116 def random Random.new(seed) end |
#seed ⇒ Integer
Generate a seed that can be used to generate random numbers. This seed will be return a consistent value when called within a scope.
97 98 99 100 |
# File 'lib/consistent_random.rb', line 97 def seed hash = seed_hash(@name) hash.byteslice(0, 8).unpack1("Q>") end |