Relative paths defined in dependencies

I am doing the Elixir for Programmers course and really enjoying it. I’ve come up against an issue where a relative path defining an asset for one subcomponent of the project is incorrect when running another component that uses it as a dependency.
The project structure is this:

root/
    |_dictionary/
    |           |_assets/
    |           |       |_words.txt
    |           |
    |           |_lib/
    |           |    |_impl/
    |           |    |     |_word_list.ex # this file contains call to read the above words.txt file
    |           |    |
    |           |    |_runtime/ # rest of stuff I believe irrelevant to this ?
    |           |
    |           |_dictionary.ex # defined as application in mix.exs so this is what the other components are calling to
    |
    |_hangman/ # duplicates above structure essentially, again probably not relevant to ? below this level in large part
             |_mix.exs # contains {:dictionary, path: "../dictionary"} in deps

When calling the Dictionary app in iex launched from the dictionary directory the relative path assets/words.txt works. When calling the Hangman app in iex launched from the hangman directory, the relative path needs to be ../dictionary/assets/words.txt. I understand why this would be, however I need to be able to define the path in such a way that would be correct regardless of the directory I’m in when I open iex. Any suggestions or tips?

1 Like

Hi @stevensonmt,

Is this the Dave Thomas course? If so I did this some time ago and from memory he refactors to rectify the issue.

I jumped on and there is a lesson called Our Dictionary Module needs help, he addresses the issue there.

Andrew

2 Likes

Would using Application.app_dir/2 to get the path of the asset solve your problem?

https://hexdocs.pm/elixir/1.12/Application.html#app_dir/2

Which section is that lesson in? I can’t find it. I looked at his code on Github and somewhere around lesson 7 his code uses the path “…/…/assets/words.txt” and passes it to Path.expand(__DIR__), which seems to solve my issue, I guess by converting it to an absolute path. I don’t understand why that works though because calling iex from directories with absolute paths /home/project_root/hangman/ and /home/project_root/dictionary works in both cases, but the ../../assets/words.txt would be expanded to /home/assets/words.txt right?

TIL Application.app_dir. Thanks! I don’t think it solves my problem though b/c it is returning a path from the _build/dev/lib directory for each app.

1 Like

The __DIR__ special form refers to the path of the file where it’s used. So resolving ../../assets/words.txt from /home/project_root/dictionary/lib/impl/word_list.ex does in fact point you to the correct path.

3 Likes

That is brilliant! Thanks @awerment. Filing this away for future use.