Skip to content
Permalink
Browse files

Merge pull request #556 from jstepien/random-srand

Random#srand
  • Loading branch information
alex committed Apr 12, 2013
2 parents 03fcbd8 + e1af197 commit 5acbb1c03b738447f87c6e00476e269a775c1fc9
@@ -1,6 +1,4 @@
fails:Random.new uses a random seed value if none is supplied
fails:Random.new accepts an Integer seed value as an argument
fails:Random.new accepts (and truncates) a Float seed value as an argument
fails:Random.new accepts (and converts to Integer) a Rational seed value as an argument
fails:Random.new accepts (and converts to Integer) a Complex (without imaginary part) seed value as an argument
fails:Random.new raises a RangeError if passed a Complex (with imaginary part) seed value as an argument
@@ -1,5 +1 @@
fails:Random#seed returns an Integer
fails:Random#seed returns an arbitrary seed if the constructor was called without arguments
fails:Random#seed returns the same generated seed when repeatedly called on the same object
fails:Random#seed returns the seed given in the constructor
fails:Random#seed returns the given seed coerced with #to_int

This file was deleted.

@@ -16,6 +16,7 @@
from topaz.objects.stringobject import W_StringObject
from topaz.objects.classobject import W_ClassObject
from topaz.objects.moduleobject import W_ModuleObject
from topaz.objects.randomobject import W_RandomObject


class Kernel(Module):
@@ -381,3 +382,9 @@ def method_catch(self, space, name, block):
if e.name == name:
return e.w_value
raise

@moduledef.method("srand")
def method_srand(self, space, w_seed=None):
random_class = space.getclassfor(W_RandomObject)
default = space.find_const(random_class, "DEFAULT")
return default.srand(space, w_seed)
@@ -1,3 +1,6 @@
import os
import time

from rpython.rlib.rrandom import Random

from topaz.module import ClassDef
@@ -11,6 +14,7 @@ class W_RandomObject(W_Object):

def __init__(self, space, seed=0, klass=None):
W_Object.__init__(self, space, klass)
self.w_seed = None
self.random = Random(abs(seed))

@classdef.setup_class
@@ -24,16 +28,25 @@ def method_allocate(self, space, seed=0):

@classdef.method("initialize")
def method_initialize(self, space, w_seed=None):
pass
self.srand(space, w_seed)

@classdef.method("srand")
def method_srand(self, space, args_w):
self.random = Random()
@classdef.method("seed")
def method_seed(self, space):
return self.w_seed

@classdef.singleton_method("srand")
def method_singleton_srand(self, space, args_w):
default = space.find_const(self, "DEFAULT")
return space.send(default, space.newsymbol("srand"), args_w)
def srand(self, space, seed=None):
previous_seed = self.w_seed
if seed is None:
seed = self._generate_seed()
else:
seed = Coerce.int(space, seed)
self.w_seed = space.newint(seed)
if previous_seed is None:
value = space.newfloat(self.random.random())
else:
value = previous_seed
self.random = Random(abs(seed))
return value

@classdef.method("rand")
def method_rand(self, space, w_max=None):
@@ -79,3 +92,13 @@ def _rand_int(self, space, integer):
raise space.error(space.w_ArgumentError, "invalid argument")
else:
return space.newint(int(random * max))

def _generate_seed(self):
seed = 0
if os.access('/dev/urandom', os.R_OK):
file = os.open('/dev/urandom', os.R_OK, 0644)
bytes = os.read(file, 4)
os.close(file)
for b in bytes:
seed = seed * 0xff + ord(b)
return seed + int(time.time()) + os.getpid()

0 comments on commit 5acbb1c

Please sign in to comment.
You can’t perform that action at this time.