1
0
mirror of https://github.com/adambard/learnxinyminutes-docs.git synced 2025-08-05 06:17:36 +02:00

Added one more example with guards, fixed typos and identation.

This commit is contained in:
mrshankly
2013-07-03 00:03:44 +01:00
parent 231a211ef2
commit a136cfe86a

View File

@@ -141,33 +141,33 @@ number < atom < reference < functions < port < pid < tuple < list < bit string
# `if` expression # `if` expression
if false do if false do
"This will never be seen" "This will never be seen"
else else
"This will" "This will"
end end
# There's also `unless` # There's also `unless`
unless true do unless true do
"This will never be seen" "This will never be seen"
else else
"This will" "This will"
end end
# Remember pattern matching? Many control-flow structures in elixir rely on it. # Remember pattern matching? Many control-flow structures in elixir rely on it.
# `case` allows us to compare a value against many patterns: # `case` allows us to compare a value against many patterns:
case {:one, :two} do case {:one, :two} do
{:four, :five} -> {:four, :five} ->
"This won't match" "This won't match"
{:one, x} -> {:one, x} ->
"This will match and assign `x` to `:two`" "This will match and assign `x` to `:two`"
_ -> _ ->
"This will match any value" "This will match any value"
end end
# It's common practive to assign a value to `_` if we don't need it. # It's common practive to assign a value to `_` if we don't need it.
# For example, if only the head of a list matters to us: # For example, if only the head of a list matters to us:
[head | _] = [1,2,3] [head | _] = [1,2,3]
head #=> 1 head #=> 1
# For better readability we can do the following: # For better readability we can do the following:
@@ -177,35 +177,35 @@ head #=> :a
# `cond` lets us check for many conditions at the same time. # `cond` lets us check for many conditions at the same time.
# Use `cond` instead of nesting many `if` expressions. # Use `cond` instead of nesting many `if` expressions.
cond do cond do
1 + 1 == 3 -> 1 + 1 == 3 ->
"I will never be seen" "I will never be seen"
2 * 5 == 12 -> 2 * 5 == 12 ->
"Me neither" "Me neither"
1 + 2 == 3 -> 1 + 2 == 3 ->
"But I will" "But I will"
end end
# It is common to see a last condition equal to `true`, which will always match. # It is common to see a last condition equal to `true`, which will always match.
cond do cond do
1 + 1 == 3 -> 1 + 1 == 3 ->
"I will never be seen" "I will never be seen"
2 * 5 == 12 -> 2 * 5 == 12 ->
"Me neither" "Me neither"
true -> true ->
"But I will (this is essentially an else)" "But I will (this is essentially an else)"
end end
# `try/catch` is used to catch values that are thrown, it also supports an # `try/catch` is used to catch values that are thrown, it also supports an
# `after` clause that is invoked whether or not a value is catched. # `after` clause that is invoked whether or not a value is catched.
try do try do
throw(:hello) throw(:hello)
catch catch
message -> "Got #{message}." message -> "Got #{message}."
after after
IO.puts("I'm the after clause.") IO.puts("I'm the after clause.")
end end
#=> I'm the after clause #=> I'm the after clause
# "Got :hello" # "Got :hello"
## --------------------------- ## ---------------------------
## -- Modules and Functions ## -- Modules and Functions
@@ -218,8 +218,8 @@ square.(5) #=> 25
# They also accept many clauses and guards. Guards let you fine tune pattern matching, # They also accept many clauses and guards. Guards let you fine tune pattern matching,
# they are indicated by the `when` keyword: # they are indicated by the `when` keyword:
f = fn f = fn
x, y when x > 0 -> x + y x, y when x > 0 -> x + y
x, y -> x * y x, y -> x * y
end end
f.(1, 3) #=> 4 f.(1, 3) #=> 4
@@ -234,32 +234,32 @@ elem({1,2,3}, 0) #=> 1
# You can group several functions into a module. Inside a module use `def` # You can group several functions into a module. Inside a module use `def`
# to define your functions. # to define your functions.
defmodule Math do defmodule Math do
def sum(a, b) do def sum(a, b) do
a + b a + b
end end
def square(x) do def square(x) do
x * x x * x
end end
end end
Math.sum(1, 2) #=> 3 Math.sum(1, 2) #=> 3
Match.square(3) #=> 9 Match.square(3) #=> 9
# To compile our little Math module save it as `math.ex` and use `elixirc` # To compile our simple Math module save it as `math.ex` and use `elixirc`
elixirc math.ex # in your terminal: elixirc math.ex
# Inside a module we can define functions with `def` and private functions with `defp`. # Inside a module we can define functions with `def` and private functions with `defp`.
# A function defined with `def` is available to be invoked from other modules, # A function defined with `def` is available to be invoked from other modules,
# a private function can only be invoked locally. # a private function can only be invoked locally.
defmodule PrivateMath do defmodule PrivateMath do
def sum(a, b) do def sum(a, b) do
do_sum(a, b) do_sum(a, b)
end end
defp do_sum(a, b) do defp do_sum(a, b) do
a + b a + b
end end
end end
PrivateMath.sum(1, 2) #=> 3 PrivateMath.sum(1, 2) #=> 3
@@ -267,27 +267,29 @@ PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
# Function declarations also support guards and multiple clauses: # Function declarations also support guards and multiple clauses:
defmodule Geometry do defmodule Geometry do
def area({:rectangle, w, h}) do def area({:rectangle, w, h}) do
w * h w * h
end end
def area({:circle, r}) when is_number(r) do def area({:circle, r}) when is_number(r) do
3.14 * r * r 3.14 * r * r
end end
end end
Geometry.area({:rectangle, 2, 3}) #=> 6 Geometry.area({:rectangle, 2, 3}) #=> 6
Geometry.area({:circle, 3}) #=> 28.25999999999999801048 Geometry.area({:circle, 3}) #=> 28.25999999999999801048
Geometry.area({:circle, "not_a_number"})
#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
# Due to immutability, recursion is a big part of elixir # Due to immutability, recursion is a big part of elixir
defmodule Recursion do defmodule Recursion do
def sum_list([head | tail], acc) do def sum_list([head | tail], acc) do
sum_list(tail, acc + head) sum_list(tail, acc + head)
end end
def sum_list([], acc) do def sum_list([], acc) do
acc acc
end end
end end
Recursion.sum_list([1,2,3], 0) #=> 6 Recursion.sum_list([1,2,3], 0) #=> 6
@@ -295,12 +297,12 @@ Recursion.sum_list([1,2,3], 0) #=> 6
# Elixir modules support attributes, there are built-in attributes and you # Elixir modules support attributes, there are built-in attributes and you
# may also add custom attributes. # may also add custom attributes.
defmodule MyMod do defmodule MyMod do
@moduledoc """ @moduledoc """
This is a built-in attribute on a example module. This is a built-in attribute on a example module.
""" """
@my_data 100 # This is a custom attribute. @my_data 100 # This is a custom attribute.
IO.inspect(@my_data) #=> 100 IO.inspect(@my_data) #=> 100
end end
## --------------------------- ## ---------------------------
@@ -322,18 +324,18 @@ joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180]
# The `try` block with the `rescue` keyword is used to handle exceptions # The `try` block with the `rescue` keyword is used to handle exceptions
try do try do
raise "some error" raise "some error"
rescue rescue
RuntimeError -> "rescued a runtime error" RuntimeError -> "rescued a runtime error"
_error -> "this will rescue any error" _error -> "this will rescue any error"
end end
# All exceptions have a message # All exceptions have a message
try do try do
raise "some error" raise "some error"
rescue rescue
x in [RuntimeError] -> x in [RuntimeError] ->
x.message x.message
end end
## --------------------------- ## ---------------------------
@@ -354,16 +356,16 @@ spawn(f) #=> #PID<0.40.0>
# For all of this to be useful we need to be able to receive messages. This is # For all of this to be useful we need to be able to receive messages. This is
# achived with the `receive` mechanism: # achived with the `receive` mechanism:
defmodule Geometry do defmodule Geometry do
def area_loop do def area_loop do
receive do receive do
{:rectangle, w, h} -> {:rectangle, w, h} ->
IO.puts("Area = #{w * h}") IO.puts("Area = #{w * h}")
area_loop() area_loop()
{:circle, r} -> {:circle, r} ->
IO.puts("Area = #{3.14 * r * r}") IO.puts("Area = #{3.14 * r * r}")
area_loop() area_loop()
end end
end end
end end
# Compile the module and create a process that evaluates `area_loop` in the shell # Compile the module and create a process that evaluates `area_loop` in the shell