4

In Elixir's intro to GenServer, the client API starts the server with an :ok argument

def start_link(opts \\ []) do
  GenServer.start_link(__MODULE__, :ok, opts)
end

And the server's init function requires its argument to be :ok

def init(:ok) do
  {:ok, HashDict.new}
end

What's the point of passing and verifying :ok? Would it be any different if we were to omit this and instead write something like

def start_link(opts \\ []) do
  GenServer.start_link(__MODULE__, nil, opts)
end

def init(_) do
  {:ok, HashDict.new}
end

?

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
  • I don't think it matters as the tests still pass if you use `:ok` or `nil`. Passing `:ok` and having `init(:ok)` might just be an added check via pattern matching – AbM Nov 12 '15 at 02:10

1 Answers1

3

Its important to remember here that the second argument passed to start_link will become the argument of the init function. Because this is a simple example they have used atom like :ok and can be replaced by nil. You need to pass the second argument be it nil.

So answering your question, in this example :ok can be replaced by nil. I think they used :ok since there must be an argument and :ok looks like a good choice(just a preference)

In other situations you have to make use of this information to fetch some important data or for pattern matching

defmodule ServerDrop do
   use GenServer

defmodule State do
    defstruct count: 0
end

def start_link do
    GenServer.start_link(__MODULE__,:ok,[{:name,__MODULE__}])
    #GenServer.start_link(__MODULE__,[],[{:name,__MODULE__}])
end

def init(:ok) do
    {:ok,%State{count: 10}}
end

def init([]) do
    {:ok,%State{}}
end

#Code left out for brevity

In other situations you many need to get some data

def init(stash_pid) do
    current_number = Stash.get_value stash_pid
    {:ok,{current_number,stash_pid}}
end
coderVishal
  • 8,369
  • 3
  • 35
  • 56