From: <brabuhr / gmail.com>
>
> Since a single Ruby process only has one PRNG, slave off an extra
> process for each Random class:
> 
> #!/usr/bin/env ruby
> 
> require 'rubygems'
> require 'slave'

Nifty.  I hadn't seen the slave library before.  Is it a wrapper
around fork?  gem --list doesn't find any description:

slave (1.2.1, 1.2.0, 1.1.0, 1.0.0, 0.2.0, 0.0.1, 0.0.0)
    slave


Anyway... I took a similar approach, but using popen.  I meant it
to be a somewhat tongue-in-cheek solution... but it does work.  :)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class Random

  def initialize(ceiling=0, seed=nil)
    @ceiling = ceiling
    @io = nil
    @seed = seed || (rand(0xFFFFFFFF) + 1)
  end

  def next
    restart_pipe unless @io
    n = @io.gets.chomp
    if n.index(".")
      Float(n)
    else
      Integer(n)
    end
  end
  
  def reset
    kill_pipe
  end
  
  protected
  
  def restart_pipe
    kill_pipe
    @io = IO.popen(%{ruby -e "srand(#@seed); loop{puts rand(#@ceiling)}"}, "r")
  end
  
  def kill_pipe
    if @io
      Process.kill("KILL", @io.pid)
      @io = nil
    end
  end
end


if $0 == __FILE__

# tests from brabuhr-at-gmail.com

require 'test/unit'

class RandomTest < Test::Unit::TestCase
  def test_001
    x = Random.new(100, 2112)
    assert_equal( [38,  1,  5, 57, 11], Array.new(5) { x.next })
    assert_equal( [ 1, 31,  3, 56, 14], Array.new(5) { x.next })
    x.reset
    assert_equal( [38,  1,  5, 57, 11], Array.new(5) { x.next })
    x.reset
  end

  def test_002
    x = Random.new(100, 2112)
    assert_equal( [38,  1,  5, 57, 11], Array.new(5) { x.next })
    y = Random.new(100, 1221)
    assert_equal( [ 5, 99, 88, 48, 86], Array.new(5) { y.next })
    x.reset
    assert_equal( [38,  1,  5, 57, 11], Array.new(5) { x.next })
    assert_equal( [34, 28, 72, 77, 87], Array.new(5) { y.next })
    assert_equal( [ 1, 31,  3, 56, 14], Array.new(5) { x.next })
    x.reset
    y.reset
  end
end

end

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Regards,

Bill