Exercise: File Handler Module
If you'd like some practice creating files and modules, put all the handle_file functions into their own module named FileHandler, for example.
You'll need to then import this new module in the existing Handler module.
By default, when you use import it imports all the module's functions and macros into the current namespace. As we did in the video, you can use the only option to explicitly import specific functions:
import Servy.Plugins, only: [rewrite_path: 1, log: 1, track: 1] import Servy.Parser, only: [parse: 1]
Using only is optional, but it's recommended so as to avoid importing all the functions into the current namespace and potentially ending up with name collisions. Conversely, there's a rarely used except option to import all the functions except those that are specified.
For completeness sake, you might bump into two other variations worth noting:
import SomeModule, only: :functions import SomeModule, only: :macros
Using the :functions atom imports only functions whereas using the :macros atom only imports macros.
Alternate Way to Get Absolute Paths
In the previous video we expanded the path to the pages directory relative to the directory of the current file (__DIR__) like so:
@pages_path Path.expand("../../pages", __DIR__)
Now that we're running the application using iex -S mix, you can optionally expand the path using a slightly different approach, as follows:
@pages_path Path.expand("pages", File.cwd!)
We've removed the ../../ part of the first argument and called the File.cwd! function as the second argument. File.cwd! returns the current working directory.
But wait, you say, won't that vary depending on where we run the application? Yes, but mix always runs from the root project directory which is the top-level servy directory in our case. So calling File.cwd! always returns the top-level servy directory. And relative to that directory, the pages directory is just one level down.
Kind of a neat trick!
As an aside, this is the first time we've seen a function name ending with !. Generally speaking, this is a naming convention that conveys that the function will raise an exception if it fails. In particular, calling File.cwd! is the same as calling File.cwd but it raises an exception if for some reason there's a problem.
The Kernel Module
Functions and macros defined in Elixir's Kernel module are automatically imported into every module for convenience. It's worth scanning through these functions and macros.
Code So Far
The code for this video is in the
organizing-code directory found within the
video-code directory of the code bundle.