People who are used to other programming languages usually use some kind of rand, rnd or similar function to generate random numbers. This article shows how you can do it in Eiffel.
Generating a random number
The base library's RANDOM class is modeled as a sequence of random numbers.
This gives you the well known interface with features such as
item which are probably also the most useful for a sequence.
The following method shows how one uses this class.
To get a new random number one first moves the cursor of the list to the next number by invoking
forth. And then calls
item to actually read a number.
This is a well known pattern in Eiffel and is named the command query separation. It takes some time to get used to, but once learned, its usage through Eiffel is pretty consistent.
Now the command query separation falls somewhat short when mathematical expressions rely on several random numbers. But that is not a big problem, because as can be seen above it's very easy do write a wrapper function.
random_integer returns a new random number each time when it is called.
Here we can also see why command query separation is a good thing: You could think that random_integer does not change but that it is simply a variable containing the same value. This can in other situations be even more misleading. That is why you should whenever possible apply the command query principle so that you can rely on the fact that no state changes are done by a query.
Initializing the random generator
Very few computers support true random number generators. Usually one uses a mathematical function which produces (hopefully) uncorrelated data. Some real randomness is then introduced by connecting the so called "seed" to a hopefully random event. The seed usually an integer number which is used to initialize the algorithm. In the RANDOM class "set_seed" is available as a creation feature. The question is now, what should the seed be? If you want each time the same random sequence yielding in the exact same behavior for each program execution you can initialize with an arbitrary fixed number, like 73 for example. If you like to have different random number sequences each time one usually does this by taking some kind of time measurement as the seed. This assumes that the program start or better the creation of the time object is actually a more or less random event.
This can be done in the following way
local l_time: TIME l_seed: INTEGER do -- This computes milliseconds since midnight. -- Milliseconds since 1970 would be even better. create l_time.make_now l_seed := l_time.hour l_seed := l_seed * 60 + l_time.minute l_seed := l_seed * 60 + l_time.second l_seed := l_seed * 1000 + l_time.milli_second create random_sequence.set_seed (l_seed) end