1
votes

I have an elixir Genserver module that gets initialized with a defstruct But I can't figure out how to access the data from that strict in its own private modules.

Here's the struct it gets initialized with:

  defstruct info:   "test_data"
  ...

Here's part of the code. If a different process wants to get information from it, it needs to know it's pid. and the state gets passed in automatically.

  def get_info(pid), do: GenServer.call(pid, :get_info)
  ...
  def handle_call(:get_info, _from, state), do: {:reply, state.info, state}

But how can the module itself access the struct it was initialized with?

  def do_test(pid), do: GenServer.info(pid, :print_your_own_data_test)
  ...
  def handle_info(:print_your_own_data_test, state) do
    print_your_own_data_test()
    {:noreply, state}
  end
  ...
  defp print_your_own_data_test() do      #do I have to pass state here? from handle_info?
    IO.put  self.info      # what goes here?
  end
1
Yes, you'll need to pass the state manually. Did you try it and encountered any errors?Dogbert
no I was doing something stupid until I made this question: I was doing IO.puts get_info(pid) so it was trying to call a handle call from a handle info, ridiculous, but I'll give this a try and see if it gives errors.Legit Stack

1 Answers

2
votes

But how can the module itself access the struct it was initialized with?

A function cannot access the state of itself directly; you'll need to pass the state received in handle_* functions to the functions that need the state manually:

def handle_info(:print_your_own_data_test, state) do
  print_your_own_data_test(state)
  {:noreply, state}
end

defp print_your_own_data_test(state) do
  IO.inspect state
end

There is a :sys.get_state/{1,2} function which can return the state of a GenServer process but you cannot invoke it from within the process since it's a synchronous GenServer call which will create a deadlock if the process calls it itself. (That function also has a note saying it should only be used for debugging.)