joeerl
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
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex










First Post!- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
josevalim
Hi @joeerl! In Elixir, we usually follow a direct mapping from module name to file name. So a file named
MyApp.Sensors.Supervisorshould be put inlib/my_app/sensors/supervisor.ex. So maybe you want to report this to the scenic project and get their $.02 on the topic.Note it is just a convention though, Elixir does not care about the filename as long as it ends with
.ex.Most Liked
wojtekmach
I believe the reason that Phoenix has
PostControllerinstead ofControllers.Postis that it’s pretty common to alias modules and it wouldn’t be possible to have in the same module the following: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.exdefinesDate, instead ofCalendar.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
@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 alib/controllersfolder, 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
scenesfolder. However, each module defines a single scene, so it would have a name likeMyApp.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.excontainsMyAppWeb.PageControllerinstead ofMyAppWeb.Controller.PageorMyAppWeb.Controllers.PageTo 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 namedcontrollerorcontrollers, although I have a slight preference forcontrollers, 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
My perspective on
MyAppWeb.Controllers.Page:PagemoduleMyAppWeb.Controllers“namespace”Pageto be a single controller - one among many in theMyAppWeb.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.ControllersandMyAppWeb.Viewsnamespaces 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).Last Post!
sribe
That is indeed pure insanity. FWIW, I’ve seen lots of projects that way on Windows–it seemed to be common practice. And historically there was a good reason for it. For a very long time, include paths in the predecessors of Visual Studio were comma-delimited in a single text field, they were not recursive, and the text field was limited to 255 characters. (Yes, that was INCREDIBLY stupid, but it was what it was.)