Search code examples
erlangerlang-shell

Accessing one erlang module by another when in different folders


I have a pretty simple doubt, but I can't seem to find a proper solution for it anywhere. I have 2 erlang modules, module1.erl and module2.erl. As defined by the submission guidelines for my project, both modules belong to different parts and are hence in different folders part1 and part2 respectively under the same directory. This is how the structure looks:

src/
   part1/
       module1.erl
   part2/
       module2.erl

Now module2 is dependent on module1, and calls various methods of module1 as module1:method(). I'm able to achieve full functionality when both module1.erl and module2.erl are in the same folder, but now they're in different folders, and I try to run module2.erl from part2 folder, I can't figure out how to allow module2 to compile and call the methods of module1.


Solution

  • Since the emulator is being used, the path to module1 is not in the code path by default when we are launching the emulator in the path of module2 directly and with default options. This can be verified using ...

    1> code:get_path().
    code:get_path().
    [".","/usr/local/lib/erlang/lib/kernel-8.2/ebin",
     "/usr/local/lib/erlang/lib/stdlib-3.17/ebin",
     "/usr/local/lib/erlang/lib/xmerl-1.3.28/ebin",
     "/usr/local/lib/erlang/lib/wx-2.1.1/ebin",
     "/usr/local/lib/erlang/lib/tools-3.5.2/ebin",
     "/usr/local/lib/erlang/lib/tftp-1.0.3/ebin",
     "/usr/local/lib/erlang/lib/syntax_tools-2.6/ebin",
     "/usr/local/lib/erlang/lib/ssl-10.6/ebin",
     "/usr/local/lib/erlang/lib/ssh-4.13/ebin",
     "/usr/local/lib/erlang/lib/snmp-5.11/ebin",
     "/usr/local/lib/erlang/lib/sasl-4.1.1/ebin",
     "/usr/local/lib/erlang/lib/runtime_tools-1.17/ebin",
     "/usr/local/lib/erlang/lib/reltool-0.9/ebin",
     "/usr/local/lib/erlang/lib/public_key-1.11.3/ebin",
     "/usr/local/lib/erlang/lib/parsetools-2.3.2/ebin",
     "/usr/local/lib/erlang/lib/os_mon-2.7.1/ebin",
     "/usr/local/lib/erlang/lib/odbc-2.13.5/ebin",
     "/usr/local/lib/erlang/lib/observer-2.10.1/ebin",
     "/usr/local/lib/erlang/lib/mnesia-4.20.1/ebin",
     "/usr/local/lib/erlang/lib/megaco-4.2/ebin",
     "/usr/local/lib/erlang/lib/inets-7.5/ebin",
     "/usr/local/lib/erlang/lib/hipe-4.0.1/ebin",
     "/usr/local/lib/erlang/lib/ftp-1.1/ebin",
     "/usr/local/lib/erlang/lib/eunit-2.7/ebin",
     "/usr/local/lib/erlang/lib/et-1.6.5/ebin",
     "/usr/local/lib/erlang/lib/erts-12.2/ebin",
     "/usr/local/lib/erlang/lib/erl_interface-5.1/ebin",
     [...]|...]
    

    This list has . in it, but not ../part1, so when when we are compiling, been in the part2 directory, it fails...

    2> c(module1).
    c(module1).
    {error,non_existing}
    

    There are several ways to work around this, few simple ones could be...

    1. c("../part1/module1.erl").. As per the documentation of c

    ...Module can be either a module name or a source file path, with or without .erl extension...

    And here, in the option above, we used the relative path to the source file of module1.

    1. Invoke erl with an option -pa which adds the path of part1 in the code path for that session of the erlang emulator.
    part2$ erl -pa "../part1"
    Erlang/OTP 25 [DEVELOPMENT] [erts-12.2] [source-c1ab4b5424] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns]
    
    Eshell V12.2  (abort with ^G)
    1> code:get_path().
    ["../part1",".","/usr/local/lib/erlang/lib/kernel-8.2/ebin",
     "/usr/local/lib/erlang/lib/stdlib-3.17/ebin",
     "/usr/local/lib/erlang/lib/xmerl-1.3.28/ebin",
     "/usr/local/lib/erlang/lib/wx-2.1.1/ebin",
     "/usr/local/lib/erlang/lib/tools-3.5.2/ebin",
     "/usr/local/lib/erlang/lib/tftp-1.0.3/ebin",
     "/usr/local/lib/erlang/lib/syntax_tools-2.6/ebin",
     "/usr/local/lib/erlang/lib/ssl-10.6/ebin",
     "/usr/local/lib/erlang/lib/ssh-4.13/ebin",
     "/usr/local/lib/erlang/lib/snmp-5.11/ebin",
     "/usr/local/lib/erlang/lib/sasl-4.1.1/ebin",
     "/usr/local/lib/erlang/lib/runtime_tools-1.17/ebin",
     "/usr/local/lib/erlang/lib/reltool-0.9/ebin",
     "/usr/local/lib/erlang/lib/public_key-1.11.3/ebin",
     "/usr/local/lib/erlang/lib/parsetools-2.3.2/ebin",
     "/usr/local/lib/erlang/lib/os_mon-2.7.1/ebin",
     "/usr/local/lib/erlang/lib/odbc-2.13.5/ebin",
     "/usr/local/lib/erlang/lib/observer-2.10.1/ebin",
     "/usr/local/lib/erlang/lib/mnesia-4.20.1/ebin",
     "/usr/local/lib/erlang/lib/megaco-4.2/ebin",
     "/usr/local/lib/erlang/lib/inets-7.5/ebin",
     "/usr/local/lib/erlang/lib/hipe-4.0.1/ebin",
     "/usr/local/lib/erlang/lib/ftp-1.1/ebin",
     "/usr/local/lib/erlang/lib/eunit-2.7/ebin",
     "/usr/local/lib/erlang/lib/et-1.6.5/ebin",
     "/usr/local/lib/erlang/lib/erts-12.2/ebin",
     [...]|...]
    2> c(module2).
    {ok,module2}
    3> c(module1).
    Recompiling /home/nalin/source/erlang/part2/../part1/module1.erl
    {ok,module1}
    4> module2:exec().
    "Module2"
    5> module1:exec().
    "Module1"
    6>
    

    I hope this much should be sufficient to get you going. Also, you must take an opportunity to read through the Compilation and Code Loading to have some idea around what goes on.



    WYSIWYG => WHAT YOU SHOW IS WHAT YOU GET