Files
mruby-mruby/mrbgems/mruby-random/README.md
T
Yukihiro "Matz" Matsumoto 1b189bc1a2 mruby-random: add README.md
The document is written by Google Jules.
2025-06-14 01:02:52 +09:00

7.7 KiB

mruby-random

mruby-random is an mrbgem that provides pseudo-random number generation facilities for mruby.

Features

  • Provides Kernel#rand method for generating pseudo-random numbers.
  • Supports generating random numbers within a specific range.
  • Allows setting a seed for reproducible random number sequences using Kernel#srand.

Global Random Number Generation

Generating a random number

To generate a pseudo-random floating-point number between 0.0 (inclusive) and 1.0 (exclusive):

r = rand
p r # => 0.31415926535

To generate a pseudo-random integer number between 0 (inclusive) and a given maximum integer (exclusive):

r = rand(100)
p r # => 42

To generate a pseudo-random integer within a given Range:

r = rand(10..20) # or rand(10...20)
p r # => 15 (e.g., between 10 and 20, or 10 and 19)

Seeding the random number generator

To initialize the pseudo-random number generator with a specific seed:

srand(12345)
p rand(100) # => 81
p rand(100) # => 81 (if you re-seed with srand(12345) again)

# Using the same seed will produce the same sequence of random numbers
srand(12345)
p rand(100) # => 81
srand(12345)
p rand(100) # => 81

The Random Class

Besides the global Kernel#rand and Kernel#srand methods, mruby-random also provides a Random class for managing separate random number generators.

Creating an Instance

You can create a new instance of the Random class with a system-generated seed:

rng = Random.new
p rng.rand(100)

Or you can provide a specific seed:

rng = Random.new(12345)
p rng.rand(100) # => 81

Instance Methods

rand

The rand instance method behaves similarly to Kernel#rand, but operates on the specific Random instance.

  • Called with no arguments, it returns a pseudo-random floating-point number between 0.0 (inclusive) and 1.0 (exclusive).

    rng = Random.new
    p rng.rand # => 0.123456789
    
  • Called with an integer max argument, it returns a pseudo-random integer between 0 (inclusive) and max (exclusive).

    rng = Random.new
    p rng.rand(50) # => 23
    
  • Called with a Range argument (min..max or min...max), it returns a pseudo-random integer within that range (inclusive of min, and inclusive or exclusive of max depending on the range type).

    rng = Random.new
    p rng.rand(10..20) # => 15 (between 10 and 20, inclusive)
    p rng.rand(10...20) # => 12 (between 10 and 19, inclusive)
    

srand

The srand instance method is used to seed the specific Random instance. It allows you to re-initialize the random number generator for that instance with a specific seed, making its sequence of generated numbers predictable.

rng = Random.new(111)
p rng.rand(1000) # => 100
p rng.rand(1000) # => 283

rng.srand(111) # Re-seed the same instance
p rng.rand(1000) # => 100 (sequence repeats for this instance)

rng2 = Random.new(111) # A different instance with the same seed
p rng2.rand(1000) # => 100

It is important to note that Random#srand is an alias for Random#initialize. Re-seeding an existing Random object will reset its internal state.

bytes(n)

The bytes method returns a string containing n pseudo-random bytes.

rng = Random.new
p rng.bytes(5) # => "\xAB\xCD\xEF\x12\x34" (example output)

Class Methods (Using the Default Generator)

The Random class also provides class methods that operate on a global, default random number generator. This is the same generator used by Kernel#rand and Kernel#srand.

Random.rand

This method is equivalent to Kernel.rand (or simply rand).

  • With no arguments, returns a float between 0.0 and 1.0 (exclusive of 1.0):

    p Random.rand # => 0.7654321
    
  • With an integer max argument, returns an integer between 0 and max (exclusive of max):

    p Random.rand(10) # => 7
    
  • With a Range argument, returns an integer within the range:

    p Random.rand(50..60) # => 53
    

Random.srand(seed)

This method is equivalent to Kernel.srand(seed) (or simply srand(seed)). It seeds the global default random number generator.

Random.srand(123)
p Random.rand(100) # => 13
p rand(100)        # => 80 (uses the same seeded generator)

Random.srand(123)
p Random.rand(100) # => 13 (sequence repeats)

Random.bytes(n)

This method returns a string containing n pseudo-random bytes, generated by the global default random number generator.

p Random.bytes(3) # => "\xDE\xAD\xBE" (example output)

Array Methods

mruby-random extends the Array class with methods for shuffling elements and sampling random elements. These methods can optionally accept a Random instance to use a specific random number generator.

shuffle

The shuffle method returns a new array with the elements of the original array in a random order.

a = [1, 2, 3, 4, 5]
p a.shuffle # => [3, 1, 5, 2, 4] (example output)
p a         # => [1, 2, 3, 4, 5] (original array is unchanged)

You can provide a specific Random instance using the random: keyword argument. This is useful for reproducible shuffling.

rng = Random.new(123)
a = [1, 2, 3, 4, 5]
p a.shuffle(random: rng) # => [1, 5, 3, 2, 4] (example output, will be consistent with seed 123)

rng2 = Random.new(123) # Same seed
p a.shuffle(random: rng2) # => [1, 5, 3, 2, 4] (same shuffled order)

shuffle!

The shuffle! method shuffles the elements of the array in-place. It modifies the original array.

a = [1, 2, 3, 4, 5]
p a.shuffle! # => [4, 2, 1, 5, 3] (example output)
p a          # => [4, 2, 1, 5, 3] (original array is modified)

Similarly to shuffle, you can provide a specific Random instance using the random: keyword argument.

rng = Random.new(456)
a = [:a, :b, :c, :d, :e]
p a.shuffle!(random: rng) # => [:c, :a, :e, :d, :b] (example output, consistent with seed 456)
p a                       # => [:c, :a, :e, :d, :b] (original array is modified)

sample

The sample method chooses one or more random elements from the array.

  • When called with no arguments, it returns a single random element from the array. If the array is empty, it returns nil.

    a = ["apple", "banana", "cherry", "date"]
    p a.sample # => "cherry" (example output)
    
    empty_array = []
    p empty_array.sample # => nil
    
  • When called with an integer n as an argument, it returns a new array containing n unique random elements from the original array. If the array does not have enough unique elements, it returns all elements in a shuffled order. If the array is empty, it returns an empty array.

    a = ["apple", "banana", "cherry", "date", "elderberry"]
    p a.sample(3) # => ["date", "apple", "banana"] (example output)
    p a.sample(10) # => ["banana", "elderberry", "apple", "date", "cherry"] (all elements, shuffled)
    
    
    empty_array = []
    p empty_array.sample(3) # => []
    
  • You can provide a specific Random instance using the random: keyword argument for both forms of sample.

    rng = Random.new(789)
    a = [10, 20, 30, 40, 50]
    p a.sample(random: rng)    # => 30 (example output, consistent with seed 789)
    
    rng_b = Random.new(789) # Re-initialize with the same seed for predictable multi-sampling
    p a.sample(2, random: rng_b) # => [30, 50] (example output)
    

Algorithm

The mruby-random mrbgem primarily utilizes the xoshiro128++ 1.0 algorithm for pseudo-random number generation.

In certain 32-bit configurations (specifically when MRB_INT32 is defined and MRB_64BIT is not), a different algorithm, XORSHIFT96, might be employed.

License

The mruby-random mrbgem is released under the MIT License. See the LICENSE file for details.