I’d like to add some custom helper functions to iex. I use .iex.exs
and can define a module there with my custom functions. But I can’t figure out how to auto-import the module into my iex environment. I’ve tried hacking the iex bash script (at /usr/local/bin/iex
), browsed thru the iex
source - no luck. Is there a way to extend IEx.Helpers
, or auto-import my .iex.exs
module?
I may be over simplifying, since I haven’t actually done this, but I would expect something like this in .iex.exs
to work:
defmodule MyHelpers do
#details
end
import MyHelpers
If you do in fact have that import step, can you show us your code to help with diagnosis?
My .iex.exs
is exactly as you suggested.
When I run iex
, I see this error message:
** (CompileError) .iex.exs:11: module MyHelpers is not loaded but was defined. This happens when you depend on a module in the same context it is defined. ... If the module is defined at the top-level and you are trying to use it at the top-level, such is not supported by Elixir
Right! I was just testing that out as I saw your reply
Are you looking to do something project-specific or global? Project-specific isn’t hard. You can have MyHelpers in your normal source tree, and import MyHelpers
in .iex.exs
and it works.
If you need something global, then it’ll be more complicated because you’ll need the compiled BEAM file stored somewhere like your home dir and use some sort of Code.load_file/2
or Code.require_file/2
call.
Looking for a global solution. I believe I tried Code.load_file
, but I’ll give it another shot…
So Code.load_file
didn’t work, but I found a solution:
- create a helper module (
cd ~ && vim my_helpers.ex
) - compile the helper module (
elixirc my_helpers.ex
) - add an import statement to
.iex.exs
(import MyHelpers
) - test in
iex
What happens is that iex
auto-loads the compiled beam file - then you can auto-import the helper module in .iex.exs
.
You can tweak the beam-path by hacking the iex
shell script (at /usr/local/bin/iex
).
@gregvaughn thanks for your suggestions!
I’m glad you got it working! I wasn’t so much help, just a kernel of an idea. The Code
module also has ways to adjust the BEAM’s load path, which might help you avoid hacking the shell script (and having to remember to re-hack it each time you upgrade).
I couldn’t figure out how to load .beam
files with the Code
module. I ended up putting my helper source and beam files in ~/.iex
, then made a bash alias ie=iex -pa ~/.iex
. The -pa
bit adds the .iex
directory to the load path.
I actually figured this out about a year ago, forgot my answer and have been poking around the various lists to find the answer I wrote. Thanks for figuring this out, my search skills were failing.
You can use Code.prepend_path/append_path to update the path that the Beam uses to load files.
Unfortunately, they don’t work in this context, I haven’t found a work around yet other than the -pa
option.
I bet an escript could be made to simplify all this…
Doesn’t work for me unfortunately.
I have the Elixir.IEXHelper.beam
file in my home folder and in
.iex.ex
I have
import IEXHelper
I get
** (CompileError) /Users/chazsconi/.iex.exs:1: module IEXHelper is not loaded and could not be found
Any suggestions for how to fix this?
You need to start iex with the -pa
option to append your home dir to the iex search path. Try iex -pa ~/
Also FYI you can use import_if_available
- prevents the error message if the module is not found.
Is there an easy way to define an IEx helper now? I’d prefer to keep the helper definition inside .iex.exs
if possible.
Unfortunately, no, because it is not possible to import a module in the same file as in which it was defined: you will get above compile error scenario.
Ah, ok. I’ll just define the helper somewhere else then.
In Elixir v1.14+ you will be able to import the module as you define it in .iex.exs files, as we now evaluate it line by line: Evaluate --dot-iex line by line · elixir-lang/elixir@395b053 · GitHub