Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elixir - Randomized numbers in Agent

I'm trying to implement an Agent that behaves as a dice :

defmodule Dice do
  @on_load :seed_generator

  def start_link(opts \\ []) do
    Agent.start_link(fn -> [] end, name: __MODULE__)
  end

  def roll(n, val) do
    Agent.cast(__MODULE__, fn(_) ->
      Stream.repeatedly(fn -> :random.uniform(val) end)
      |> Enum.take(n)
    end)
  end

  def seed_generator do
    :random.seed(:erlang.now)
    :ok
  end
end

However, the generated numbers are the same, every time I restart iex. What am I doing wrong ? Is the seed not working because the :random.uniform call is inside the Agent ? Or something related with the Stream maybe.

like image 353
Kernael Avatar asked May 25 '15 12:05

Kernael


1 Answers

The seed_generator function is called in a different process than the one your Agent will be using. In fact that process doesn't even exist at the point this code is loaded. Try seeding the generator when starting the Agent:

defmodule Dice do
  def start_link(opts \\ []) do
    Agent.start_link(fn -> :random.seed(:erlang.now) end, name: __MODULE__)
  end

  def roll(n, val) do
    Agent.get(__MODULE__, fn(_) ->
      Stream.repeatedly(fn -> :random.uniform(val) end)
      |> Enum.take(n)
    end)
  end
end
like image 65
Paweł Obrok Avatar answered Sep 26 '22 04:09

Paweł Obrok