mix help
mix help new
mix new hello_world
cd hello_world
mix test
> $ tree
├── _build
│ └── test
│ └── lib
│ └── hello_world
│ ├── consolidated
│ │ ├── Elixir.Collectable.beam
│ │ ├── Elixir.Enumerable.beam
│ │ ├── Elixir.IEx.Info.beam
│ │ ├── Elixir.Inspect.beam
│ │ ├── Elixir.List.Chars.beam
│ │ └── Elixir.String.Chars.beam
│ └── ebin
│ ├── Elixir.HelloWorld.beam
│ └── hello_world.app
├── config
│ └── config.exs
├── lib
│ └── hello_world.ex
├── mix.exs
├── README.md
└── test
├── hello_world_test.exs
└── test_helper.exs
Let's look at the lib/hello_world.ex file to check out our HelloWorld module:
defmodule HelloWorld do
@moduledoc """
Documentation for HelloWorld.
"""
@doc """
Hello world.
## Examples
iex> HelloWorld.hello
:world
"""
def hello do
:world
end
end
Before we move on, let's run the REPL with our project loaded into it. Normally, if you just run iex, you won't have these modules loaded. You can load your project by running:
iex -S mix
iex(1)> HelloWorld.hello()
:world
Let's create a division function:
defmodule HelloWorld do
# ...
def div(a, b) do
a / b
end
end
And we can use it:
iex -S mix
iex(1)> HelloWorld.div(1, 2)
0.5
Of course, this suffers from a bit of a problem:
iex(2)> HelloWorld.div(1, 0)
** (ArithmeticError) bad argument in arithmetic expression
(hello_world) lib/hello_world.ex:20: HelloWorld.div/2
defmodule HelloWorld do
# ...
def div(a, 0) do
:no_dice
end
def div(a, b) do
a / b
end
end
iex -S mix
iex(1)> HelloWorld.div(1, 0)
:no_dice
Let's change this a bit so we can pattern match on whether or not the function was successful:
defmodule HelloWorld do
def div(a, 0) do
{:error, "attempt at division by zero"}
end
def div(a, b) do
{:ok, a / b}
end
end
Now we can handle this result in a case statement. Let's do it in a test:
vim test/hello_world_test.exs
defmodule HelloWorldTest do
use ExUnit.Case
doctest HelloWorld
test "division" do
{:ok, result} = HelloWorld.div(2, 1)
assert result == 2.0
end
test "division by zero" do
{:error, err} = HelloWorld.div(1, 0)
assert err == "attempt at division by zero"
end
end
When you use a pipe, which looks like |>, you're really just moving the first argument to a function out of the function call, to the left of the pipe. We'll open an iex session to check it out:
iex -S mix
This:
iex(1)> HelloWorld.div(1, 2)
{:ok, 0.5}
is the same as this:
iex(2)> 1 |> HelloWorld.div(2)
{:ok, 0.5}
vim test/hello_world_test.exs
defmodule HelloWorldTest do
# ...
test "pipes and strings" do
# If we import the `String` module we can use its functions without
# qualifying them fully - so we get `upcase` instead of the more-verbose
# `String.upcase`
import String
val =
"josh"
|> reverse
|> capitalize
|> reverse
assert val == "josH"
end
end









网友评论