Run this notebook

Use Livebook to open this notebook and explore new ideas.

It is easy to get started, on your machine or the cloud.

Click below to open and run it in your Livebook at .

(or change your Livebook location)

# Mix ```elixir Mix.install([ {:jason, "~> 1.4"}, {:kino, "~> 0.9", override: true}, {:youtube, github: "brooklinjazz/youtube"}, {:hidden_cell, github: "brooklinjazz/hidden_cell"} ]) ``` ## Navigation <div style="display: flex; align-items: center; width: 100%; justify-content: space-between; font-size: 1rem; color: #61758a; background-color: #f0f5f9; height: 4rem; padding: 0 1rem; border-radius: 1rem;"> <div style="display: flex;"> <i class="ri-home-fill"></i> <a style="display: flex; color: #61758a; margin-left: 1rem;" href="../start.livemd">Home</a> </div> <div style="display: flex;"> <i class="ri-bug-fill"></i> <a style="display: flex; color: #61758a; margin-left: 1rem;" href="https://github.com/DockYard-Academy/curriculum/issues/new?assignees=&labels=&template=issue.md&title=Mix">Report An Issue</a> </div> <div style="display: flex;"> <i class="ri-arrow-left-fill"></i> <a style="display: flex; color: #61758a; margin-left: 1rem;" href="../exercises/pascals_triangle.livemd">Pascal's Triangle</a> </div> <div style="display: flex;"> <a style="display: flex; color: #61758a; margin-right: 1rem;" href="../exercises/games.livemd">Games Project</a> <i class="ri-arrow-right-fill"></i> </div> </div> ## Review Questions Upon completing this lesson, a student should be able to answer the following questions. * What is the purpose of Mix? * Where should our application go inside of a mix project? * How do we compile a mix project and explore it using the IEx shell? ## Mix [Mix](https://hexdocs.pm/mix/Mix.html) is a build tool that ships with Elixir that automates tasks for creating, compiling, and testing your application. We start a new Mix application by running the following in the command line. ``` mix new app_name ``` Where `app_name` is the name of the project. <!-- livebook:{"break_markdown":true} --> ### Your Turn Create a `hello_world` application. You should notice that the command generated several files. ``` $ mix new hello_world * creating README.md * creating .formatter.exs * creating .gitignore * creating mix.exs * creating lib * creating lib/hello_world.ex * creating test * creating test/test_helper.exs * creating test/hello_world_test.exs Your Mix project was created successfully. You can use "mix" to compile it, test it, and more: cd hello_world mix test Run "mix help" for more commands. ``` Your project should have the following file and folder structure. ``` hello_world/ lib/ hello_world.ex test/ hello_world_test.exs test_helper.exs .formatter.exs .gitignore mix.exs README.md ``` We'll walk through the mix project structure and how you can build Elixir applications. ## The `lib` Folder The `lib/` folder contains the files for the project. We start with a single module named after the project. You should have a `HelloWorld` module in the `lib/hello_world.ex` file. We use `@moduledoc` and `@doc` to document our code. ```elixir defmodule HelloWorld do @moduledoc """ Documentation for `HelloWorld`. """ @doc """ Hello world. ## Examples iex> HelloWorld.hello() :world """ def hello do :world end end ``` ## Running A Mix Project To execute the Elixir code for our Mix project, you can load the project into the IEx Shell by running the following command in the project folder. ``` iex -S mix ``` Now, all of the `.ex` files and modules under the `lib/` folder are available in the [IEx](https://hexdocs.pm/iex/IEx.html) shell environment. [Mix](https://hexdocs.pm/mix/Mix.html) ignores `.exs` files, so any modules in a `.exs` file will not be available in the [IEx](https://hexdocs.pm/iex/IEx.html) shell. ### Your Turn Load your project into the IEx Shell. ``` iex -S mix ``` Call the `hello/0` function. ``` iex> HelloWorld.hello() :world ``` Notice that the `iex -S mix` command compiles your project into the `_build` folder. This folder contains `.beam` files which are executable files generated by the Erlang compiler. You can also compile the project by running `mix compile` in the command line. ## Tests [ExUnit](https://hexdocs.pm/ex_unit/ExUnit.html) is a built-in testing framework. Test files are under the `test/` folder in `.exs` files. In your `hello_world` project, there should be an example test file `test/hello_world_test.exs` with the following content. <!-- livebook:{"force_markdown":true} --> ```elixir defmodule HelloWorldTest do use ExUnit.Case doctest HelloWorld test "greets the world" do assert HelloWorld.hello() == :world end end ``` Test files generally correspond to another file in the `lib/` folder. For example, a `lib/greeting/hola.ex` file might have a corresponding `test/greeting/hola_test.exs` file. We will dive deeper into how to test Elixir projects in the [ExUnit](exunit.livemd) section. For now, know that you can execute all of your tests by running the following in the command line. <!-- livebook:{"force_markdown":true} --> ```elixir $ mix test ``` ### Your Turn Run `mix test` in your `hello_world` project folder from the command line, and you should see an output similar to the following. <!-- livebook:{"force_markdown":true} --> ```elixir Compiling 1 file (.ex) Generated hello_world app .. Finished in 0.02 seconds (0.00s async, 0.02s sync) 1 doctest, 1 test, 0 failures Randomized with seed 768874 ``` ## File And Module Names Mix compiles all `.ex` files under the `lib/` folder and bundles them together into a project. Generally, Elixir projects organize modules under the main project namespace. So all of the modules in the `HelloWorld` application would be grouped under the `HelloWorld` namespace. For example, a new `Greeting` module would be defined under `HelloWorld.Greeting`. ```elixir defmodule HelloWorld.Greeting do def salutations(name) do "Salutations, #{name}!" end end ``` Nested modules generally relate to each other, often sub-modules deal with a more specific application of the higher-level module. For example, a `Formal` module would be under the `Greeting` module. ```elixir defmodule HelloWorld.Greeting.Formal do def charmed() do "Charmed, I'm sure." end end ``` While not enforced, module and file structure often follow a pattern, where the module name matches its folder and file. For example, the `HelloWorld.Greeting.Formal` module would be in a `lib/greeting/formal.ex` file, and the `HelloWorld.Greeting` will be in the `lib/greeting.ex` file. ``` lib/ greeting.ex hello_world.ex greeting/ formal.ex ``` ### Your Turn Modules can call functions from any other modules in `.ex` files under the `lib/` folder, just as you have already seen in livebook cells. ```elixir defmodule ModuleA do def run do "A" end end defmodule ModuleB do def run do ModuleA.run() <> "B" end end ModuleB.run() ``` In your `hello_world` application, create a new module, `HelloWorld.Name` in a `lib/name.ex` file, which will return a random name. ```elixir defmodule HelloWorld.Name do def random do Enum.random(["Peter", "Bruce", "Tony"]) end end ``` Then, call the `HelloWorld.Name.random/0` function from the `HelloWorld` module in `hello_world.ex`. <!-- livebook:{"break_markdown":true} --> <!-- livebook:{"force_markdown":true} --> ```elixir defmodule HelloWorld do def hello do "Hello, #{HelloWorld.Name.random()}." end end ``` <!-- livebook:{"break_markdown":true} --> Run your project in the [IEx](https://hexdocs.pm/iex/IEx.html) shell and ensure the `HelloWorld.hello/0` function works as expected. <!-- livebook:{"force_markdown":true} --> ```elixir $ iex -S mix iex> HelloWorld.hello() "Hello, Peter." ``` ## Mix.exs The `mix.exs` file's main responsibility is to configure the mix project. It defines two public functions, `project/0` and `application/0`. The `project/0` function returns project configuration such as the project name, current version, and installed dependencies. The `project/0` function relies on the private `deps/0` function to provide a list of dependencies. The `application/0` function returns application configuration used to generate an application manifest file in the `_build` folder. This file is used under the hood to run the project. For more, you can see the [Application](https://hexdocs.pm/elixir/main/Application.html) module on HexDocs. Sometimes removing the `_build` folder and recompiling a project can resolve compilation bugs. ## Dependencies Other developers create open-source Elixir projects hosted on GitHub, which we can add as dependencies to our project. There is a massive ecosystem of Elixir projects, which means you don't have to reinvent the wheel and solve already solved problems. The [Hex.pm](https://hex.pm/) contains a list of available Elixir projects you may find useful. For a curated list, check out the [awesome-elixir](https://github.com/h4cc/awesome-elixir) project. To install a dependency, include the name of the project and desired version in a tuple inside the `deps/0` function in `mix.exs`. Notice that `mix.exs` includes comments on installing a dependency using the project version or GitHub URL. <!-- livebook:{"force_markdown":true} --> ```elixir defp deps do [ # {:dep_from_hexpm, "~> 0.3.0"}, # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} ] end ``` ### Your Turn Add the [Faker](https://hex.pm/packages/faker) project to your `hello_world` application. [Faker](https://hexdocs.pm/faker/readme.html) provides functions for generating fake data, often useful for randomized test data. It's often most reliable to check the [Hex page](https://hex.pm/packages/faker) of a project for the latest version. Ensure you add `:faker` with the latest version to the `deps/0` function in `mix.exs`. <!-- livebook:{"force_markdown":true} --> ```elixir defp deps do [ {:faker, "~> 0.17.0"} ] end ``` Then run `mix deps.get` to update your project dependencies. Once installed, you have access to the [Faker](https://hexdocs.pm/faker/readme.html) module. Use the `Faker.Person.first_name/0` function in your `HelloWorld.hello/0` function. For more on how to use [Faker](https://hexdocs.pm/faker/readme.html), you can read the [Faker Documentation](https://hexdocs.pm/faker/readme.html). <!-- livebook:{"force_markdown":true} --> ```elixir def hello do "Hello, #{Faker.Person.first_name()}." end ``` Ensure your `hello/0` function works in the IEx shell. <!-- livebook:{"force_markdown":true} --> ```elixir iex -S mix iex> HelloWorld.hello() "Hello, Salvador." # The name will be random each time. ``` <!-- livebook:{"break_markdown":true} --> ### Versions Project [Versions](https://hexdocs.pm/elixir/Version.html) are generally represented by `Major.Minor.Patch` numbers. When installing dependencies, we specify a [version requirement](https://hexdocs.pm/elixir/Version.html#module-requirements). We can even specify a version between two numbers using comparison operators. i.e. `>= 2.0.0 and < 2.1.0`, The locally installed dependency may not exactly match the version requirement, but must belong in the range specified. The `~>` symbol you see in dependencies means it will never go above its upper bound. * `~> 2.1` would allow any version below `3.0.0` and above or equal to `2.1.0`. * `~> 2.1.2` would allow any version below `2.2.0` and above or equal to `2.1.2`. The [Version documentation](https://hexdocs.pm/elixir/Version.html) goes into further depth. You can automatically update project versions by running the following in your command line. ``` mix deps.update example_dep ``` Or with the `--all` option to update all deps. ``` mix deps.update --all ``` ## Formatting The `.formatter.exs` file contains project configuration for how to format Elixir source code files automatically. You can run `mix format` from the command line in the project folder to format elixir code. ### Your Turn Indent the code in `hello_world.ex`. Then, run `mix format` and notice the code automatically formats. If it does not, ensure that you do not have syntax errors that prevent code formatting. ## README.md Most projects include a README.md file which contains basic information about the project written in markdown. There is no universal README structure however it's common to include: * The repository name. * The project purpose. * Setup instructions. * Collaborators on the project. GitHub pages display the README on the front of the repository page for the project. When building your own projects, you'll want to make sure you update the default README to include relevant information. View the [Markdown cheat-sheet](https://www.markdownguide.org/cheat-sheet/) for a quick guide on markdown syntax. ## Mix Environments Mix projects can run in different environments. The default environment is your development `:dev` environment. Run your `hello_world` project in the IEx shell and call `Mix.env()` to see that `:dev` is the current environment. <!-- livebook:{"force_markdown":true} --> ```elixir $ iex -S mix iex> Mix.env() :dev ``` The project will use the `:test` environment when running tests and `:prod` when deployed to production. We can change project behavior or configuration based on the current environment. For example, if you had SMS (text) notifications in your project, you might want to disable them in the `:dev` and `:test` environment to ensure that developers don't accidentally send out text messages to users. ## Further Reading For more on [Mix](https://hexdocs.pm/mix/Mix.html), consider reading the following. * [elixir-lang: Intro to Mix](https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html) * [HexDocs: Mix](https://hexdocs.pm/mix/Mix.html#content) ## Commit Your Progress DockYard Academy now recommends you use the latest [Release](https://github.com/DockYard-Academy/curriculum/releases) rather than forking or cloning our repository. Run `git status` to ensure there are no undesirable changes. Then run the following in your command line from the `curriculum` folder to commit your progress. ``` $ git add . $ git commit -m "finish Mix reading" $ git push ``` We're proud to offer our open-source curriculum free of charge for anyone to learn from at their own pace. We also offer a paid course where you can learn from an instructor alongside a cohort of your peers. We will accept applications for the June-August 2023 cohort soon. ## Navigation <div style="display: flex; align-items: center; width: 100%; justify-content: space-between; font-size: 1rem; color: #61758a; background-color: #f0f5f9; height: 4rem; padding: 0 1rem; border-radius: 1rem;"> <div style="display: flex;"> <i class="ri-home-fill"></i> <a style="display: flex; color: #61758a; margin-left: 1rem;" href="../start.livemd">Home</a> </div> <div style="display: flex;"> <i class="ri-bug-fill"></i> <a style="display: flex; color: #61758a; margin-left: 1rem;" href="https://github.com/DockYard-Academy/curriculum/issues/new?assignees=&labels=&template=issue.md&title=Mix">Report An Issue</a> </div> <div style="display: flex;"> <i class="ri-arrow-left-fill"></i> <a style="display: flex; color: #61758a; margin-left: 1rem;" href="../exercises/pascals_triangle.livemd">Pascal's Triangle</a> </div> <div style="display: flex;"> <a style="display: flex; color: #61758a; margin-right: 1rem;" href="../exercises/games.livemd">Games Project</a> <i class="ri-arrow-right-fill"></i> </div> </div>
See source

Have you already installed Livebook?

If you already installed Livebook, you can configure the default Livebook location where you want to open notebooks.
Livebook up Checking status We can't reach this Livebook (but we saved your preference anyway)
Run notebook

Not yet? Install Livebook in just a minute

Livebook is open source, free, and ready to run anywhere.

Run on your machine

with Livebook Desktop

Run in the cloud

on select platforms

To run on Linux, Docker, embedded devices, or Elixir’s Mix, check our README.

PLATINUM SPONSORS
SPONSORS
Code navigation with go to definition of modules and functions Read More ×