Mix.install and structs

Hello people.

Is there any kind of restriction while using an exs script with Mix.install and structs defined by the modules in an installed dependency. I am trying an exs script with Mix.install and a struct in the installed mix package cannot be found by the script.

Here is a script that reproduces my scenario:

Mix.install([{:httpoison, "~> 1.8"}])

url = "https://httparrot.herokuapp.com/ip"

successful_response = fn
  {:ok, %HTTPoison.Response{status_code: 200} = response} ->
    {:ok, response}
  other ->
    {:error, "Unexpected response #{inspect(other)}"}
end

url
|> HTTPoison.get()
|> successful_response.()
|> IO.inspect()

I get a compiler error:

** (CompileError) struct.exs:6: HTTPoison.Response.__struct__/0 is undefined, cannot expand struct HTTPoison.Response. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code

Is this a known restriction?

1 Like

That’s a good question which I’m not sure why it doesn’t work right in the root level of the script.

But for sure it works if the struct is nested within a module. So the code below works,

Mix.install([{:httpoison, "~> 1.8"}])

url = "https://httparrot.herokuapp.com/ip"

defmodule Response do
  def successful_response(resp) do
    case resp do
    {:ok, %HTTPoison.Response{status_code: 200} = response} ->
      {:ok, response}
    other ->
      {:error, "Unexpected response #{inspect(other)}"}
    end
  end
end

url
|> HTTPoison.get()
|> Response.successful_response()
|> IO.inspect()
8 Likes

Excellent question and answer. I have documented it here: Highlight Mix.install/2 limitation · elixir-lang/elixir@0e07359 · GitHub

18 Likes

This documentation helped me, thanks!

I have created a kind of follow-up (related to protocols) here: