Hans Solo
Hans Solo

Reputation: 53

The command elixirc is compiling and executing the code

I wrote a program to print the sum of two numbers in Elixir. I saved the file as solution.ex and when I compile it using elixirc as elixirc solution.ex it both compiles and executes the code. I thought that elixirc will only compile the code and generate a binary and running the binary using elixir will execute it. Any help will be appreciated.

defmodule Solution do
  defp sum(a, b), do: a + b

  def main() do
    a = IO.gets("") |> String.strip |> String.to_integer
    b = IO.gets("") |> String.strip |> String.to_integer
    sum(a, b) |> IO.puts
  end
end

Solution.main()

Upvotes: 2

Views: 1503

Answers (2)

Onorio Catenacci
Onorio Catenacci

Reputation: 15293

Just in case your question is how to keep elixirc from running the code, this is the answer:

defmodule Solution do
  defp sum(a, b), do: a + b

  def main() do
    a = IO.gets("") |> String.strip |> String.to_integer
    b = IO.gets("") |> String.strip |> String.to_integer
    sum(a, b) |> IO.puts
  end
end

#Solution.main()

As @whatyouhide said the code will get run regardless. But without the Solution.main() at the end of your code, it will simply compile the code and have nothing to execute so it will exit. So either comment out Solution.main() or remove it.


EDIT: Further comments by the original poster make me think that what he or she is looking for is the ability to take the compiled binary to a different machine and run it. If that's the case then what you probably want is exrm.

Elixir (and indeed Erlang) don't simply build a single binary image. Both of them depend on runtime binaries to execute as well. Exrm will figure out all the runtime files you need and bundle them into a single compressed file that you can move to the machine where you want to execute.

But there's not a single binary file that you can simply deploy on a different machine. At the least you'll also need the Erlang and Elixir runtimes.

Upvotes: 1

whatyouhide
whatyouhide

Reputation: 16781

Elixir has to run the code to compile it; that's just how it works. Compiling that file will correctly generate Solution.beam (bytecode for the Solution module) because it executes the defmodule macro. After that, it will blindly run Solution.main(). (just for clairty, the code inside defs is not run at compile-time)

If you want to build an executable out of this that you can call like $ elixir-sum, then you may want to look at escripts, which are executable Erlang (and therefore Elixir) scripts (that still need the Erlang VM installed in order to run). You can read more information about them in the documentation for the mix escript.build task or in a bunch of blog posts such as this one.

Roughly, you'd need to add this to the configuration of your project (returned by project/0 in your mix.exs file):

def project() do
  [...,
   main_module: Solution]
end

This way, the generated script will call the main/1 function of the Solution module passing the command-line arguments to it. Note that you don't have such a function, you only have main/0 (which takes no arguments), so you'd need to define main/1 (where you can just ignore the arguments).

Upvotes: 2

Related Questions