Module Code.Typespec is not available (even inside IEx.Introspection)

I put IEx.pry in IEx.Introspection (https://github.com/elixir-lang/elixir/blob/master/lib/iex/lib/iex/introspection.ex#L493) then started iex -S mix

I got the following error related to Code.Typespec not available.

iex(1)> IEx.Introspection.h({:proplists, :get_value})
** (UndefinedFunctionError) function Code.Typespec.fetch_specs/1 is undefined (module Code.Typespec is not available)
    Code.Typespec.fetch_specs(:proplists)
    (iex) lib/iex/introspection.ex:493: IEx.Introspection.get_spec/3
    (iex) lib/iex/introspection.ex:299: anonymous fn/5 in IEx.Introspection.h/1
    (elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
    (iex) lib/iex/introspection.ex:295: IEx.Introspection.h/1

Then I tried to use Typespec inside a simple iex and that didn’t work either.

iex(1)> Code.Typespec
Code.Typespec
iex(2)> Code.Typespec.fetch_callbacks(:proplists)
** (UndefinedFunctionError) function Code.Typespec.fetch_callbacks/1 is undefined (module Code.Typespec is not available)
    Code.Typespec.fetch_callbacks(:proplists)

What did I miss?

Update

I think it’s because Code didn’t get loaded automatically. I copy the Typespec file (https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/code/typespec.ex) and change the module name from Code.Typespec to Typespec, and put it under lib/iex/lib/iex. I also commented out alias Code.Typespec from IEx.Introspection. And now iex -S mix works because the code is able to call Typespec.fetch_specs:

iex(1)> IEx.Introspection.h({:proplists, :get_value})
Break reached: IEx.Introspection.get_spec/3 (lib/iex/introspection.ex:494)

I guess my question is what’s the correct way to load Code to IEx?

I looked elixir source code in my machine. There is no
Code.Typespec.fetch_specs(:proplists)
But there is
Kernel.Typespec.beam_specs(:proplists)

It’s in here: https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/code/typespec.ex

It turns out I can manually load typspec in the top of IEx.Introspection and it works fine.

Code.require_file("../../../../lib/elixir/lib/code/typespec.ex", __DIR__)

Whats your Elixir version? There are changes to typespec code on master after last stable release, so if you are not running master that could explain it.

2 Likes

That makes sense! Thanks!

I’m using Elixir (1.6.5). It’s making sense now. Sounds like the version of elixir my machine runs is different than the version the master branch expects. Is that right?

Sorry my comment was wrong as @wojtekmach said there was a change in code.
https://github.com/elixir-lang/elixir/commit/4f14aea9f6bf1c8ae5ed1da88b5168424616e11a#diff-9500c68886c2a36c242cdad92fe0f5e6

You are totally right, I was using the elixir(1.6.5) installed on my machine, not the one built from the master branch. Use the built elixir/iex (i.e. doing ../../bin/iex -S mix inside lib/iex) and everything works like a charm. And I can see now I’m running on the 1.7-dev version:

Interactive Elixir (1.7.0-dev) - press Ctrl+C to exit (type h() ENTER for help)

Thanks!

See my comment above. You were not wrong. :slight_smile:
Thanks for your help! I’m glad that it all make sense now. :tada:

1 Like