This might be known widely already, but its new to me and I couldn’t find anything about this in on the interwebs. I’ve been trying to call Elixir in some Erlang code for quite some time, and its always gone similar to this:
defmodule Test.Tester do
def hello() do
IO.puts "hello"
end
end
erl > 'Test.Tester':hello
BUT I made the discovery of the following interesting behavior today:
defmodule :tester do
def hello() do
IO.puts "Hello"
end
end
:tester.hello
Which compiles and prints “Hello” just fine.
While not idiomatic forsure, does anyone see any issue with using this extensively to add new functionality in Elixir to an existing Erlang code base?
I haven’t tested, but you could probably do -define(TEST_TESTER, 'Elixir.Test.Tester')., then your calls would be ?TEST_TESTER:hello(). I’m not really sure if that is any better though.
I have seen multiple libraries that use the following concept to allow a module to be usable both in Elixir and Erlang in an idiomatic way:
defmodule Test.Tester do
def hello() do
IO.puts "Hello!"
end
end
defmodule :test_tester do
@elixir_module Test.Tester
@args fn num -> Stream.iterate(0, fn x -> x + 1 end) |> Stream.map(&(Macro.var(:"arg#{&1}", nil))) |> Enum.take(num) end
for {name, arity} <- @elixir_module.__info__(:functions) do
defdelegate(unquote(name)(unquote_splicing(@args.(arity))), to: @elixir_module)
end
end