Class: ConsistentRandom
- Inherits:
-
Object
- Object
- ConsistentRandom
- Defined in:
- lib/consistent_random.rb,
lib/consistent_random/testing.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, Testing
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
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.
- .testing ⇒ Object
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.
63 64 65 |
# File 'lib/consistent_random.rb', line 63 def initialize(name) @name = (name.is_a?(String) ? name.dup : name.to_s).freeze end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
60 61 62 |
# File 'lib/consistent_random.rb', line 60 def 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. The functionality is designed to be similar to the same behavior as Random.
121 122 123 |
# File 'lib/consistent_random.rb', line 121 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.
93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/consistent_random.rb', line 93 def bytes(size) test_bytes = Testing.current&.bytes_for(name) test_bytes = nil if test_bytes&.empty? chunk_size = (test_bytes ? test_bytes.length : 20) bytes = [] (size / chunk_size.to_f).ceil.times do |i| bytes << (test_bytes || seed_hash("#{name}#{i}").to_s) end 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.
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/consistent_random.rb', line 76 def rand(max = nil) value = Testing.current&.rand_for(name) || 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.
132 133 134 |
# File 'lib/consistent_random.rb', line 132 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.
109 110 111 112 113 114 115 |
# File 'lib/consistent_random.rb', line 109 def seed test_seed = Testing.current&.seed_for(name) return test_seed if test_seed hash = seed_hash(name) hash.byteslice(0, 8).unpack1("Q>") end |