Search code examples
elixirgen-server

Elixir Genserver access it's own struct data


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

Solution

  • 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.)