joeerl

joeerl

Creator of Erlang - Fondly Remembered

Module naming conventions

I have been studying the scenic code and have a question about the module naming convention.

Here’s my problem - I quickly discovered that the first module to be called was MyApp so I wondered where the code was. It happens to be in a file called my_app.ex- this then supplies a module name MyApp.Sensor.Supervisor so I thought to myself “where can I find this code” – the answer is in a module lib/sensors/supervisors.ex (the name changed from MyApp to my_app seems strange – file names are UTF8 so I don’t see why camel case files names are not used) keeping the file and module names identical seems to be fairly common in many languages …

Now lib/sensors/supervisors.ex just says:

defmodule MyApp.Sensor.Supervisor do

end

In other words it defines a single module MyApp.Sensor.Supervisor.

So now I wonder “is this a local convention or a global convention?”

In Erlang module names and file names are exactly the same, that is the module xyz will always be found in a file xyz.erl this makes finding module code (if you know the name) very easy - also since module names are unique we can put all the modules in the same directory (people tend not to do this - but I do, since it makes the problem of deciding a directory name go away).

If a .ex file contains a single module definition I don’t really understand why the file name should not be exactly the same as the module name. If this were the case finding where the code is can be done with a simple find command.

In the scenic case the names differ - firstly some CamelCase stuff happens and some pluralisation MyApp.Sensor.XXX is in a directory called lib/sensors/XXX.ex (note the plural) – is this a local convention or a widely adopted practise? Had there been only one sensor would the directory been called lib/sensor and the plural s dropped?

If the conventions here are widely used then where are they documented?

Cheers

Most Liked

wojtekmach

wojtekmach

Hex Core Team

I believe the reason that Phoenix has PostController instead of Controllers.Post is that it’s pretty common to alias modules and it wouldn’t be possible to have in the same module the following:

# contrived:
alias Controllers.Post
alias Views.Post
alias Blog.Post

A good example where not sticking to 1-1 mapping between file and module is in Elixir itself: elixir/lib/elixir/lib/calendar at main · elixir-lang/elixir · GitHub, we have lib/calendar/date.ex defines Date, instead of Calendar.Date. It’s very convenient to keep these files together.

What I personally try to do is to stick to 1-1 mapping in the vast majority of cases but sometimes, very rarely, diverge from it when it has some benefits.

boydm

boydm

Creator of Scenic

@joeerl This is a really good question.

When I set up the scenic_new project I took a look at Phoenix and tried to replicate the pluralization there. When you run mix phx.new my_app, it creates a lib/controllers folder, but the modules within have controller in the singular form.

Same goes for views.

When it comes to Scenic, it made sense to follow the Phoenix pattern. An app will have a collection of scenes. So put those in the scenes folder. However, each module defines a single scene, so it would have a name like MyApp.Scene.Whatever.

On further thinking, the folder structure in Phoenix generated apps doesn’t really map to the Module names. In other words,

lib/my_app_web/controllers/page_controller.ex contains MyAppWeb.PageController instead of MyAppWeb.Controller.Page or MyAppWeb.Controllers.Page

To me this breaks the philosophy @josevalim described above.

Personally, I would prefer a module name of MyAppWeb.Controller.Page, which (to me) denotes that it is a single controller. I could go either way if it should live in a folder named controller or controllers, although I have a slight preference for controllers, since that folder contains a collection of individual controllers.

That’s the philosophy I used in the scenic_new generator.

As far as the sensor supervisor goes, the version in master is MyApp.Sensor.Supervisor, which is singular. It lives in the sensors folder, which would be where I would put all the sensors. (I assume a real project would have more than one)

If there is a strong opinion on pluralization of the folders, I can change it, but for now I think it reflects the folder pluralization in Phoenix.

peerreynders

peerreynders

My perspective on MyAppWeb.Controllers.Page:

  • Page module
  • in the MyAppWeb.Controllers “namespace”
  • therefore I expect Page to be a single controller - one among many in the MyAppWeb.Controllers “namespace”.

So the pluralization isn’t in the service of a good folder or module name but to create the sense of a namespace.

Now when it comes to the wisdom of having separate MyAppWeb.Controllers and MyAppWeb.Views namespaces given how tightly coupled controllers and views tend to be - that is a separate discussion (as I recall there are technical reasons for this as views require very different build processing from controllers - I’ve never been fond of the Rails convention of collecting “like things” under the same namespace (when we are not dealing with a (standard) library); I’m more of a put things that work as a cohesive whole under the same namespace sort of guy).

Where Next?

Popular in Questions Top

beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> somethi...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New

Other popular topics Top

axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48342 226
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41989 114
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement