@@ -5,13 +5,18 @@ defmodule PatternMatching do
|
|||||||
assert match?(1, ___)
|
assert match?(1, ___)
|
||||||
end
|
end
|
||||||
|
|
||||||
koan "A pattern can change" do
|
koan "A value can be bound to a variable" do
|
||||||
|
a = 1
|
||||||
|
assert a == ___
|
||||||
|
end
|
||||||
|
|
||||||
|
koan "A variable can be rebound" do
|
||||||
a = 1
|
a = 1
|
||||||
a = 2
|
a = 2
|
||||||
assert a == ___
|
assert a == ___
|
||||||
end
|
end
|
||||||
|
|
||||||
koan "A pattern can also be strict" do
|
koan "A variable can be pinned to be prevent it from being rebound" do
|
||||||
a = 1
|
a = 1
|
||||||
assert_raise MatchError, fn() ->
|
assert_raise MatchError, fn() ->
|
||||||
^a = ___
|
^a = ___
|
||||||
@@ -44,12 +49,18 @@ defmodule PatternMatching do
|
|||||||
assert items == ___
|
assert items == ___
|
||||||
end
|
end
|
||||||
|
|
||||||
koan "Patterns show what you really care about" do
|
koan "Maps support partial pattern matching" do
|
||||||
%{make: make} = %{type: "car", year: 2016, make: "Honda", color: "black"}
|
%{make: make} = %{type: "car", year: 2016, make: "Honda", color: "black"}
|
||||||
|
|
||||||
assert make == ___
|
assert make == ___
|
||||||
end
|
end
|
||||||
|
|
||||||
|
koan "Lists must match exactly" do
|
||||||
|
assert_raise ___, fn ->
|
||||||
|
[a, b] = [1,2,3]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
koan "The pattern can make assertions about what it expects" do
|
koan "The pattern can make assertions about what it expects" do
|
||||||
assert match?([1, _second, _third], ___)
|
assert match?([1, _second, _third], ___)
|
||||||
end
|
end
|
||||||
@@ -58,7 +69,7 @@ defmodule PatternMatching do
|
|||||||
def make_noise(%{type: "dog"}), do: "Woof"
|
def make_noise(%{type: "dog"}), do: "Woof"
|
||||||
def make_noise(_anything), do: "Eh?"
|
def make_noise(_anything), do: "Eh?"
|
||||||
|
|
||||||
koan "Functions can declare what kind of arguments they accept" do
|
koan "Functions perform pattern matching on their arguments" do
|
||||||
cat = %{type: "cat"}
|
cat = %{type: "cat"}
|
||||||
dog = %{type: "dog"}
|
dog = %{type: "dog"}
|
||||||
snake = %{type: "snake"}
|
snake = %{type: "snake"}
|
||||||
@@ -99,4 +110,9 @@ defmodule PatternMatching do
|
|||||||
%Animal{name: name} = %Animal{kind: "dog", name: "Max"}
|
%Animal{name: name} = %Animal{kind: "dog", name: "Max"}
|
||||||
assert name == ___
|
assert name == ___
|
||||||
end
|
end
|
||||||
|
|
||||||
|
koan "Structs will even match with a regular map" do
|
||||||
|
%{name: name} = %Animal{kind: "dog", name: "Max"}
|
||||||
|
assert name == ___
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ defmodule Functions do
|
|||||||
String.duplicate(message, times)
|
String.duplicate(message, times)
|
||||||
end
|
end
|
||||||
|
|
||||||
koan "Not all arguments are always needed" do
|
koan "Functions can have default argument values" do
|
||||||
assert repeat_again("Hello ") == ___
|
assert repeat_again("Hello ") == ___
|
||||||
assert repeat_again("Hello ", 2) == ___
|
assert repeat_again("Hello ", 2) == ___
|
||||||
end
|
end
|
||||||
@@ -50,7 +50,7 @@ defmodule Functions do
|
|||||||
def the_length(0), do: "It was zero"
|
def the_length(0), do: "It was zero"
|
||||||
def the_length(number), do: "The length was #{number}"
|
def the_length(number), do: "The length was #{number}"
|
||||||
|
|
||||||
koan "For those individual one-offs, you can even guard on the arguments themselves" do
|
koan "For simpler cases, pattern matching is effective" do
|
||||||
assert the_length(0) == ___
|
assert the_length(0) == ___
|
||||||
assert the_length(5) == ___
|
assert the_length(5) == ___
|
||||||
end
|
end
|
||||||
@@ -72,6 +72,11 @@ defmodule Functions do
|
|||||||
assert times_five_and_then(2, &square/1) == ___
|
assert times_five_and_then(2, &square/1) == ___
|
||||||
end
|
end
|
||||||
|
|
||||||
|
koan "The '&' operation is not needed for anonymous functions" do
|
||||||
|
cube = fn number -> number * number * number end
|
||||||
|
assert times_five_and_then(2, cube) == ___
|
||||||
|
end
|
||||||
|
|
||||||
koan "Functions can be combined elegantly with the pipe operator" do
|
koan "Functions can be combined elegantly with the pipe operator" do
|
||||||
result = "full-name"
|
result = "full-name"
|
||||||
|> String.split("-")
|
|> String.split("-")
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ defmodule Processes do
|
|||||||
use Koans
|
use Koans
|
||||||
|
|
||||||
koan "You are a process" do
|
koan "You are a process" do
|
||||||
assert Process.alive?(self()) == ___
|
assert Process.alive?(self) == ___
|
||||||
end
|
end
|
||||||
|
|
||||||
koan "You can ask a process to introduce itself" do
|
koan "You can ask a process to introduce itself" do
|
||||||
information = Process.info(self())
|
information = Process.info(self)
|
||||||
|
|
||||||
assert information[:status] == ___
|
assert information[:status] == ___
|
||||||
end
|
end
|
||||||
@@ -18,7 +18,7 @@ defmodule Processes do
|
|||||||
end
|
end
|
||||||
|
|
||||||
koan "You can send messages to processes" do
|
koan "You can send messages to processes" do
|
||||||
send self(), "hola!"
|
send self, "hola!"
|
||||||
|
|
||||||
receive do
|
receive do
|
||||||
msg -> assert msg == ___
|
msg -> assert msg == ___
|
||||||
@@ -31,12 +31,12 @@ defmodule Processes do
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
send pid, {:hello, self()}
|
send pid, {:hello, self}
|
||||||
assert_receive ___
|
assert_receive ___
|
||||||
end
|
end
|
||||||
|
|
||||||
koan "Waiting for a message can get boring" do
|
koan "Waiting for a message can get boring" do
|
||||||
parent = self()
|
parent = self
|
||||||
spawn(fn -> receive do
|
spawn(fn -> receive do
|
||||||
after
|
after
|
||||||
5 -> send parent, {:waited_too_long, "I am impatient"}
|
5 -> send parent, {:waited_too_long, "I am impatient"}
|
||||||
@@ -47,7 +47,7 @@ defmodule Processes do
|
|||||||
end
|
end
|
||||||
|
|
||||||
koan "Killing a process will terminate it" do
|
koan "Killing a process will terminate it" do
|
||||||
pid = spawn(fn -> Process.exit(self(), :kill) end)
|
pid = spawn(fn -> Process.exit(self, :kill) end)
|
||||||
:timer.sleep(500)
|
:timer.sleep(500)
|
||||||
assert Process.alive?(pid) == ___
|
assert Process.alive?(pid) == ___
|
||||||
end
|
end
|
||||||
@@ -61,7 +61,7 @@ defmodule Processes do
|
|||||||
end
|
end
|
||||||
|
|
||||||
koan "Trapping will allow you to react to someone terminating the process" do
|
koan "Trapping will allow you to react to someone terminating the process" do
|
||||||
parent = self()
|
parent = self
|
||||||
pid = spawn(fn ->
|
pid = spawn(fn ->
|
||||||
Process.flag(:trap_exit, true)
|
Process.flag(:trap_exit, true)
|
||||||
send parent, :ready
|
send parent, :ready
|
||||||
@@ -101,7 +101,7 @@ defmodule Processes do
|
|||||||
end
|
end
|
||||||
|
|
||||||
koan "If you monitor your children, you'll be automatically informed for their depature" do
|
koan "If you monitor your children, you'll be automatically informed for their depature" do
|
||||||
spawn_monitor(fn -> Process.exit(self(), :normal) end)
|
spawn_monitor(fn -> Process.exit(self, :normal) end)
|
||||||
|
|
||||||
assert_receive {:DOWN, _ref, :process, _pid, ___}
|
assert_receive {:DOWN, _ref, :process, _pid, ___}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ defmodule FunctionsTests do
|
|||||||
6,
|
6,
|
||||||
6,
|
6,
|
||||||
100,
|
100,
|
||||||
|
1000,
|
||||||
"Full Name",
|
"Full Name",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ defmodule PatternsTests do
|
|||||||
|
|
||||||
test "Pattern Matching" do
|
test "Pattern Matching" do
|
||||||
answers = [
|
answers = [
|
||||||
|
1,
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
2,
|
2,
|
||||||
@@ -12,11 +13,13 @@ defmodule PatternsTests do
|
|||||||
3,
|
3,
|
||||||
"eggs, milk",
|
"eggs, milk",
|
||||||
"Honda",
|
"Honda",
|
||||||
|
MatchError,
|
||||||
[1,2,3],
|
[1,2,3],
|
||||||
{:multiple, ["Meow", "Woof", "Eh?"]},
|
{:multiple, ["Meow", "Woof", "Eh?"]},
|
||||||
{:multiple, ["Mickey", "Donald", "I need a name!"]},
|
{:multiple, ["Mickey", "Donald", "I need a name!"]},
|
||||||
"dog",
|
"dog",
|
||||||
"Max",
|
"Max",
|
||||||
|
"Max",
|
||||||
]
|
]
|
||||||
|
|
||||||
test_all(PatternMatching, answers)
|
test_all(PatternMatching, answers)
|
||||||
|
|||||||
Reference in New Issue
Block a user