7

I checked out rebar, but that seems way too complex. Maybe someone could post something that says, %Post your code here in the following rebar app:

%%%-------------------------------------------------------------------
%% @doc myapp public API
%% @end
%%%-------------------------------------------------------------------

-module('myapp_app').

-behaviour(application).

%% Application callbacks
-export([start/2
        ,stop/1]).

%%====================================================================
%% API
%%====================================================================

start(_StartType, _StartArgs) ->
    'myapp_sup':start_link().

%%--------------------------------------------------------------------
stop(_State) ->
    ok.

Is there some easier alternative for beginners?

7stud
  • 46,922
  • 14
  • 101
  • 127

6 Answers6

5

You cannot escape having to learn your language's build system if you're going to create anything non-trivial. If you are familiar with GNU Make you can use erlang.mk instead of Rebar, but I believe Rebar3 is the most beginner-friendly.


To solve the specific problem of running someone's library code inside of the REPL, try the following with rebar3:

rebar3 new app

Ignore the source files that it creates for now. Edit rebar.config and add dependencies. Then, launch a REPL that has those dependencies loaded (along with any source files you've created in the src/ directory):

rebar3 shell

Nathaniel Waisbrot
  • 23,261
  • 7
  • 71
  • 99
3

I don't think there is an easier way. Learning rebar looks like the logical step here. I also think that there is a lots of effort went into rebar and rebar3 to mare Erlang more appealing to newcomers.

Istvan
  • 7,500
  • 9
  • 59
  • 109
2

I began learning erlang last year and what I found really helpful to get familiar with erlang was writing code in a simple notepad of your choice, and saving it as myapp_app.erl. Then I would open up the erlang console, and use the compile command, c, to compile my module which would then let me call my functions.

> c(myapp_app).
> myapp_app:start(a,b).
liam_g
  • 314
  • 1
  • 5
  • 15
  • 1
    The problem is that I want to call a function which doesn't exist in erlang. The function I want to call is in a third party module. You see, when someone is programming in erlang (as well as in any other language), and they want to do something pretty complicated, often they post their solution in a module and make it freely available. Most languages, e.g. perl, python, ruby, have *module installers*, which allow you to download and install third party modules that do all sorts of complex things. For instance, convert a JSON string into an erlang Map. – 7stud Dec 15 '15 at 11:34
  • Another option you could do is to create an escript, it lets you write erlang code and run the script from the console which will perform whatever the code does in your functions inside. Would it be of help to you? – liam_g Dec 15 '15 at 15:45
  • Try it: `func() -> jsx:decode(<<"{\"hello\": \"world\"}">>).` Did it work? – 7stud Dec 15 '15 at 20:59
  • Just got to try it now, it did not work, and fortunately/unfortunately for it seems that rebar will be needed. Most likely rebar3 – liam_g Dec 16 '15 at 09:40
2

Here's what I ended up doing:

Install rebar3:

$ git clone https://github.com/rebar/rebar3.git
$ cd rebar3
.../rebar3$ ./bootstrap

And now you have the script rebar3 and can copy it to somewhere in your $PATH as described in the previous section.

Or, you can download the .zip file, unzip it, then change into the rebar3 directory and issue the ./bootstrap command.

That creates the executable rebar3 inside the /rebar3 directory. I moved the rebar3 executable into /usr/local/bin, which is a directory listed in my PATH environment variable (various possible PATH locations are discussed here):

.../rebar3$ sudo mv rebar3 /usr/local/bin

That allows me to use the rebar3 command at any prompt. As an alternative, after you create your app(see the next step) you can copy rebar3 into your app's directory and from that directory issue rebar commands like this:

$ ./rebar3 .....

Then I created a new app:

~/erlang_programs$ rebar3 new app myapp

(Substitute your app name in place of: myapp)

Then:

~/erlang_programs$ cd myapp
~/erlang_programs/myapp$ 

In order to use jsx, a third party JSON library, I added jsx as a dependency:

Dependencies are listed in rebar.config file under the deps key:

{erl_opts, [debug_info]}.
{deps, [
  {jsx, "2.8.0"}
]}.

rebar.config resides here:

~/erlang_programs/myapp$ ls
LICENSE     _build      rebar.lock
README.md   rebar.config    src

Then I added my erlang program to the myapp/src directory:

my_app/src/my.erl:

-module(my).
-export([test/0]).

test() ->
    jsx:decode(<<"{\"data\": [1, 2, 3]}">>).

Finally:

~/erlang_programs/myapp$ rebar3 shell

===> Verifying dependencies...
===> Fetching jsx ({pkg,<<"jsx">>,<<"2.8.0">>})
===> Version cached at /Users/7stud/.cache/rebar3/hex/default/packages/jsx-2.8.0.tar is up to date, reusing it
===> Compiling jsx
===> Compiling myapp

Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V6.4  (abort with ^G)
1> my:test().
[{<<"data">>,[1,2,3]}]

If you make changes to your .erl file, in my case the file my.erl, you don't need to exit the shell--just compile as usual, e.g. c(my).

Community
  • 1
  • 1
7stud
  • 46,922
  • 14
  • 101
  • 127
1

If you want to experiment erlang, with some toy application, in order to master the language, the processes creation, communication and even simple supervision tree, you do not really need an application, a simple standard otp directory structure is enough and start function in.

On the other hand, if you intend to build an application with dependencies, if you want to create a library, a release, manage unitary test and functional test... then rebar (and rebar3) will make your life much simpler.

You will find in learn you some erlang: Building application with OTP and the following chapters the basic to understand how the application or release are defined.

Pascal
  • 13,977
  • 2
  • 24
  • 32
0

Erlang will look for modules in the code path.

You can see the code path by invoking code:get_path():

4> code:get_path().
[".","/usr/lib/erlang/lib/kernel-3.0.3/ebin",
 "/usr/lib/erlang/lib/stdlib-2.2/ebin",
 "/usr/lib/erlang/lib/xmerl-1.3.7/ebin",
 ...
 ...

As you can see, the current directory is included, and probably everything else will be in some default system installation location. For me that means everything will be under '/usr/lib/erlang/lib' because that's where the library path is with Debian Linux, and the rest of the path 'APP-VERSION/ebin' is expanded from the library path (see below)...

The library path can be seen by invoking code:lib_dir():

5> code:lib_dir().
"/usr/lib/erlang/lib"
6> 

The library path is expanded by finding everything under it that looks like an application, i.e. for every 'APP-VERSION/ebin' that exists under it, that's added to the code path. That's how the code path is generated. And the current directory is added of course.

The code module (worth a read) has various functions for changing the code path, and there are environment variables such as ERL_LIBS which allow you to add more paths, and the -pa argument to erl lets you add code paths as well.

Note that ERL_LIBS adds a lib, which will be searched for APP-VERSION/ebin occurrences, where as -pa adds a code path exactly as it is.

So, once you know all this, the simplest way of installing a module is...

  • Copy the compiled beam file to the current directory.

OK! That is the easiest, but a slightly more advanced solution is probably appropriate...

  • Create some directories under the library path (let's say 'my_app-1.0/ebin', so that would be '/usr/lib/erlang/lib/my_app-1.0/ebin' on my system), and copy your beam file to that.

Once that's done, start Erlang and it should add 'my_app-1.0/ebin' to the code path and any beam files in there should be found. They are installed.

Note that 'my_app-1.0' CAN be anything. It's convention only that says this should be the name of the app with a dash and the version. A useful convention though.

This is just installing a module, which was your question, but for completeness it's worth mentioning that installing an app can be done by copying the .app file to a code path location as well. It is that simple.

For beginners, isn't having module source in the current directory (and compiling them there) ok and not too difficult? And it's only a small step to copying files to the system location then. Generally third party applications you download and compile will generate an ebin directory with the app file and all the beam files in, so it's just a question of coping that ebin to my_app-version/ebin...

Michael
  • 3,639
  • 14
  • 29
  • *Copy the compiled beam file to the current directory* Where would a beginner get the compiled beam file for, say, `jsx` (a third party JSON library)? – 7stud Dec 15 '15 at 21:00
  • Well, to be fair, your question title says "install a module". I covered installing an application/library anyway though for completeness, and because I felt it was almost on topic, and useful. If however the beginner isn't capable of googling and reading a basic Erlang tutorial, and discovering they can turn a source file into a beam file by `erlc source` or `c(module)` in the shell, they aren't a developer, or ready to be one, and they should use their package management system to install binaries that just work! – Michael Dec 15 '15 at 23:55