Skip to content
This repository has been archived by the owner on Oct 21, 2023. It is now read-only.

Commit

Permalink
Change randomness behaviour to be like it prior to go1.20
Browse files Browse the repository at this point in the history
Pre go1.20, rand.Seed needed to be called for randomness. Meaning, that
math/rand delivered deterministic values by default. This was changed
however. To restore the old behaviour, we need to manually seed our
random generator with a constant.

Additionally, this introduce a local instance of rand.Rand, in order
to prevent unexpected behaviour with other code that relies on the
global math/rand package.

Fixes dustinkirkland#10 (The readme and docs explain this, therefore I consider this
solved, as it is by design and not a bug)

Fixes dustinkirkland#15
  • Loading branch information
Bios-Marcel committed Aug 26, 2023
1 parent e794b93 commit 595be26
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,15 @@ var (
separator = flag.String("separator", "-", "The separator between words in the pet name")
)

func init() {
rand.Seed(time.Now().UTC().UnixNano())
}

func main() {
flag.Parse()
rand.Seed(time.Now().UnixNano())

// To have a predictable series of petnames. (This is the default)
petname.Seed(1)

// To have an unpredictable series of petnames.
petname.NonDeterministicMode()

fmt.Println(petname.Generate(*words, *separator))
}
```
Expand Down
22 changes: 17 additions & 5 deletions petname.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,36 @@ var (

// End word lists

// Call this function once before using any other to get real random results
var localRand *rand.Rand = rand.New(rand.NewSource(1))

// NonDeterministicMode configures the local random generator used internally
// to provide non deterministic results, instead of a pre-defined order that is
// reproducible even after a process restart. If you wish to specify a custom
// contant, call [Seed(int64)].
func NonDeterministicMode() {
rand.Seed(time.Now().UnixNano())
localRand.Seed(time.Now().UnixNano())
}

// Seed configures the local random generator, allowing you to specify a
// constant for reproducible "randomness" or provide a custom value for
// "true" randomness.
func Seed(seed int64) {
localRand.Seed(seed)
}

// Adverb returns a random adverb from a list of petname adverbs.
func Adverb() string {
return adverbs[rand.Intn(len(adverbs))]
return adverbs[localRand.Intn(len(adverbs))]
}

// Adjective returns a random adjective from a list of petname adjectives.
func Adjective() string {
return adjectives[rand.Intn(len(adjectives))]
return adjectives[localRand.Intn(len(adjectives))]
}

// Name returns a random name from a list of petname names.
func Name() string {
return names[rand.Intn(len(names))]
return names[localRand.Intn(len(names))]
}

// Generate generates and returns a random pet name.
Expand Down

0 comments on commit 595be26

Please sign in to comment.