I think I’m getting the hang of elixir pretty well (I love it!). I have this stylistic question that bothers me that I’d like to know.
What is your personal way to handle a start_link in a server when you dont need the arguments. Here’s the ways I see. Id love to hear your preferred way:
Style A
App: {SomeServer, []}
Code:
def start_link(state) do
GenServer.start_link(__MODULE__, state)
end
This way was suggested by someone here, but it seems really confusing because I constantly have to ask myself what state is or if I’m actually using it.
Style B
App: {SomeServer, :ok}
Code:
def start_link(:ok) do
GenServer.start_link(__MODULE__, :ok)
end
This way seems OK but 3 redundant :ok (or []) seems weird. I’d love if it could be something involving _ but that wont work because I also have to put something in the expression.
Any other ways you see too would be great, thankss!
Edit: I keep seeing examples where people don’t use any args, but whenever I try to do that it fails. How might I initiate a call to my module in application.ex such that I don’t need to pass args?
How would I call start_link without arguments from within application.ex? That is also a point that I can’t figure out (it seems you could do this with the old Supervisor.Spec)
defmodule MyApp.Application do
@moduledoc false
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [SomeServer] # not in tuple
Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
end
end
** (Mix) Could not start application my_app: exited in: MyApp.Application.start(:normal, [])
** (EXIT) an exception was raised:
** (ArgumentError) The module MyApp was given as a child to a supervisor
but it does not implement child_spec/1.
If you own the given module, please define a child_spec/1 function
that receives an argument and returns a child specification as a map.
For example:
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [opts]},
type: :worker,
restart: :permanent,
shutdown: 500
}
end
Note that "use Agent", "use GenServer" and so on automatically define
this function for you.
However, if you don't own the given module and it doesn't implement
child_spec/1, instead of passing the module name directly as a supervisor
child, you will have to pass a child specification as a map:
%{
id: MyApp,
start: {MyApp, :start_link, [arg1, arg2]}
}
See the Supervisor documentation for more information.
(elixir) lib/supervisor.ex:639: Supervisor.init_child/1
(elixir) lib/enum.ex:1314: Enum."-map/2-lists^map/1-0-"/2
(elixir) lib/supervisor.ex:625: Supervisor.init/2
(elixir) lib/supervisor.ex:576: Supervisor.start_link/2
(kernel) application_master.erl:277: :application_master.start_it_old/4
Reading the docs isnt the hard part, its when I haev 95 questions all in my mind at the same time its overwhelming to read docs because it just introduces more lol. I need to let the consumers (my brain) churn on some workload