1. Technology
You can opt-out at any time. Please refer to our privacy policy for contact information.

Generating Random Numbers in Ruby

By

Generating Random Numbers in Ruby

It can be useful in a range programs, typically games and simulations, to generate random numbers. While no computer can generate truly random numbers, Ruby does provide access to a method that will return pseudorandom numbers.

Not Exactly Random

No computer can generate truly random numbers purely by computation. The best they can do is to generate pseudorandom numbers, a sequence of numbers that appears random but is not random. To a human observer, these numbers are indeed random. There will be no short repeating sequences, and, at least to the human observer, be completely random. However, given enough time and motivation, the original seed can be discovered, the sequence recreated and the next number in the sequence guessed. For this reason, the methods discussed in this article should probably not be used to generate numbers that must be cryptographically secure.

As mentioned above, pseudorandom number generators PRNGs must be seeded in order to produce sequences that differ each time a new random number is generated. Remember that no method is magical, these seemingly random numbers are generated using relatively simple algorithms using relatively simple arithmetic. By seeding the PRNG, you're starting it off at a different point every time. If you didn't seed it, it would generate the same sequence of numbers each time. But, at least in Ruby, the developers have thought of this.

In Ruby, the Kernel#srand method can be called with no arguments. It will choose a random number seed based on the time, the process ID and a sequence number. Simply by calling srand anywhere at the beginning of your program, your program will generate a different series of seemingly random numbers each time you run it. Though this method is called implicitly when the program starts up, and seeds the PRNG with the time and process ID (no sequence number).

Generating Numbers

Once the program is running and Kernel#srand was either implicitly and explicitly called, the Kernel#rand method can be called. This method, called with no arguments, will return a random number from 0 to 1. In the past, this number was typically scaled to the maximum number you'd wish to generate and perhaps to_i called on it to convert it to an integer.


# Generate an integer from 0 to 10
puts (rand() * 10).to_i

However, Ruby makes things a bit easier if you're using Ruby 1.9.x. The Kernel#rand method can take a single argument. If this argument is a Numeric of any kind, Ruby will generate an integer from 0 up to (and not including) that number.


# Generate a number from 0 to 10
# In a more readable way
puts rand(10)

But what if you want to generate a number from 10 to 15? In the past, typically you'd generate a number from 0 to 5 and add it to 10. But, again, Ruby makes it easier. You can pass a Range object to Kernel#rand and it will do just as you'd expect, generate a random integer in that range. By sure to pay attention to the two types of ranges. If you called rand(10..15), that would generate a number from 10 to 15 including 15. Whereas rand(10...15) (with 3 dots) would generate a number from 10 to 15 not including 15.


# Generate a number from 10 to 15
# Including 15
puts rand(10..15)

Non-Random Random Numbers

Sometimes you need a random-looking sequence of numbers, but need to generate the same sequence every time. For example, if you generate random numbers in a unit test, you should generate the same sequence of numbers every time. A unit test that fails on one sequence should fail again the next time it's run, if it generated a difference sequence the next time it might not fail. To do that, call Kernel#srand with a known and constant value.


# Generate the same sequence of numbers every time
# the program is run
srand(5)

# Generate 10 random numbers
puts (0..10).map{rand(0..10)}

A Caveat

The implementation of Kernel#rand is rather un-Ruby. It doesn't abstract the PRNG in any way, nor does it allow you to instantiate the PRNG. There is one global state for the PRNG that all the code shares. If you change the seed or otherwise change the state of the PRNG, it may have a wider range of effect than you anticipated. However, since programs expect the result of this method to be random (since that's its purpose), this will probably never be a problem. Only if the program expects to see an expected sequence of numbers, such as if it had called srand with a constant value, should it see unexpected results.

  1. About.com
  2. Technology
  3. Ruby
  4. Beginning Ruby
  5. New in Ruby 1.9.x
  6. Generating Random Numbers in Ruby - Kernel#srand

©2014 About.com. All rights reserved.