├── README.md └── images ├── atom-naming.png ├── module-naming.png └── variable-naming.png /README.md: -------------------------------------------------------------------------------- 1 | # Elixir Quick Reference 2 | A quick reference for the Elixir programming Language and standard library. 3 | 4 | Elixir Website: http://elixir-lang.org/
5 | Elixir Documentation: http://elixir-lang.org/docs.html
6 | Elixir Source: https://github.com/elixir-lang/elixir
7 | Try Elixir Online: https://glot.io/new/elixir
8 | Elixir Regex editor/testor: http://www.elixre.uk/
9 | This Document: https://github.com/itsgreggreg/elixir_quick_reference
10 | 11 | 12 | 13 | # Table of Contents 14 | 15 | - [Basic Types](#basic-types) 16 | - [Integer](#integer) 17 | - [Float](#float) 18 | - [Atom](#atom) 19 | - [Boolean](#boolean) 20 | - [Nil](#nil) 21 | - [Binary](#binary) 22 | - [String](#string) 23 | - [Escape Sequences](#escape-sequences) 24 | - [Regular Expression](#regular-expression) 25 | - [Collection Types](#collection-types) 26 | - [List](#list) 27 | - [Charlist](#charlist) 28 | - [Tuple](#tuple) 29 | - [Keyword List](#keyword-list) 30 | - [Map](#map) 31 | - [Struct](#struct) 32 | - [Range](#range) 33 | - [Streams](#streams) 34 | - [Syntax](#syntax) 35 | - [Variables](#variables) 36 | - [Operators](#operators) 37 | - [Standard infix](#standard-infix) 38 | - [Standard prefix](#standard-prefix) 39 | - [= (match)](#-match) 40 | - [^ (pin)](#-pin) 41 | - [|> (pipe)](#-pipe) 42 | - [=~ (string match)](#-string-match) 43 | - [? (codepoint)](#-codepoint) 44 | - [& (capture)](#-capture) 45 | - [Ternary](#ternary) 46 | - [in](#in) 47 | - [Comments](#comments) 48 | - [Semicolons](#semicolons) 49 | - [Do, End](#do-end) 50 | - [Pattern Matching](#pattern-matching) 51 | - [Binaries](#binaries) 52 | - [Reserved Words](#reserved-words) 53 | - [Truthiness](#truthiness) 54 | - [Sorting](#sorting) 55 | - [Modules](#modules) 56 | - [Declaration](#declaration) 57 | - [Module Functions](#module-functions) 58 | - [Private Functions](#private-functions) 59 | - [Working with other modules](#working-with-other-modules) 60 | - [Attributes](#attributes) 61 | - [Documentation](#documentation) 62 | - [Introspection](#introspection) 63 | - [Errors](#errors) 64 | - [Raise](#raise) 65 | - [Custom Error](#custom-error) 66 | - [Rescue](#rescue) 67 | - [Control Flow](#control-flow) 68 | - [if/unless](#ifunless) 69 | - [case](#case) 70 | - [cond](#cond) 71 | - [throw/catch](#throwcatch) 72 | - [with](#with) 73 | - [Guards](#guards) 74 | - [Anonymous Functions](#anonymous-functions) 75 | - [Comprehensions](#comprehensions) 76 | - [Sigils](#sigils) 77 | - [Metaprogramming](#metaprogramming) 78 | - [Processes](#processes) 79 | - [Structs](#structs) 80 | - [Working with Files](#working-with-files) 81 | - [Erlang Interoperability](#erlang-interoperability) 82 | - [IEx](#iex) 83 | - [Mix](#mix) 84 | - [Applications](#applications) 85 | - [Tasks](#tasks) 86 | - [Tests](#tests) 87 | - [Style Guide](#style-guide) 88 | 89 | 90 | 91 | 92 | ## Basic Types 93 | 94 | ### Integer 95 | Can be specified in base 10, hex, or binary. All are stored as base 10. 96 | 97 | ```elixir 98 | > 1234567 == 1_234_567 # true 99 | > 0xcafe == 0xCAFE # true 100 | > 0b10101 == 65793 # true 101 | > 0xCafe == 0b1100101011111110 # true 102 | > 0xCafe == 51_966 # true 103 | > Integer.to_string(51_966, 16) == "CAFE" # true 104 | > Integer.to_string(0xcafe) == "51996" # true 105 | ``` 106 | 107 | ### Float 108 | 64bit double precision. Can be specified with an exponent. Cannot begin or end with `.`. 109 | 110 | ```elixir 111 | > 1.2345 112 | > 0.001 == 1.0e-3 # true 113 | > .001 # syntax error! 114 | ``` 115 | 116 | ### Atom 117 | Constants whose name is their value.
118 | Are named in this format: 119 | 120 | ![Atom Naming](https://rawgit.com/itsgreggreg/elixir_quick_reference/80954a5e9bd06d5a009857a97bfad640d3cbd31a/images/atom-naming.png)
121 | To use other characters you must quote the atom.
122 | TODO: Note which characters can be used when quoted.
123 | Stored in a global table once used and never de-allocated so avoid programmatic creation.
124 | 125 | ```elixir 126 | > :something 127 | > :_some_thing 128 | > :allowed? 129 | > :Some@Thing@12345 130 | > :"Üñîçødé and Spaces" 131 | > Atom.to_string(:Yay!) # "Yay!" 132 | > :123 # syntax error! 133 | ``` 134 | 135 | ### Boolean 136 | `true` and `false` are just syntactic sugar for `:true` and `:false` and not a special type. 137 | 138 | ```elixir 139 | > true == :true # true 140 | > false == :false # true 141 | > is_boolean(:true) # true 142 | > is_atom(false) # true 143 | > is_boolean(:True) # false! 144 | ``` 145 | 146 | ### Nil 147 | `nil` is syntactic sugar for `:nil` and is not a special type. 148 | 149 | ```elixir 150 | > nil == :nil # true 151 | > is_atom(nil) # true 152 | ``` 153 | 154 | ### Binary 155 | A binary is a sequence of bytes enclosed in `<< >>` and separated with `,`.
156 | By default each number is 8 bits though size can be specified with:
157 | `::size(n)`, `::n`, `::utf8`, `::utf16`, `::utf32` or `::float`
158 | If the number of bits in a binary is not divisible by 8, it is considered a bitstring.
159 | Binaries are concatenated with `<>`. 160 | ```elixir 161 | > <<0,1,2,3>> 162 | > <<100>> == <<100::size(8)>> # true 163 | > <<4::float>> == <<64, 16, 0, 0, 0, 0, 0, 0>> # true 164 | > <<65::utf32>> == <<0, 0, 0, 65>> # true 165 | > <<0::2, 1::2>> == <<1::4>> # true 166 | > <<1,2>> <> <<3,4>> == <<1,2,3,4>> # true 167 | > is_binary(<<1,2,3,4>>) # true 168 | > is_binary(<<1::size(4)>>) # false!, num of bits not devisible by 8 169 | > is_bitstring(<<1::size(4)>>) # true 170 | ``` 171 | 172 | ### String 173 | Strings are UTF-8 encoded binaries. They are enclosed in double quotes(`"`).
174 | They can span multiple lines and contain interpolations.
175 | Interpolations are enclosed in `#{}` and can contain any expression.
176 | Strings, being binaries, are concatenated with `<>`. 177 | 178 | ```elixir 179 | > "This is a string." 180 | > "☀★☂☻♞☯☭☢€→☎♫♎⇧☮♻⌘⌛☘☊♔♕♖☦♠♣♥♦♂♀" # no problem :) 181 | > "This is an #{ Atom.to_string(:interpolated) } string." 182 | > "Where is " <> "my other half?" 183 | > "multi\nline" == "multi 184 | line" # true 185 | > <<69,108,105,120,105,114>> == "Elixir" # true 186 | > String.length("🎩") # 1 187 | > byte_size("🎩") # 4 188 | > is_binary("any string") # true 189 | > String.valid?("こんにちは") # true 190 | > String.valid?("hello" <> <<255>>) # false! 191 | > String.valid?(<<4>>) # true 192 | > String.printable?(<<4>>) # false! 4 is a valid UTF-8 codepoint, but is not printable. 193 | ``` 194 | #### Escape Sequences 195 | characters | whitespace | control sequences 196 | --------------------------|---------------------|---------------------- 197 | `\"` – double quote | `\b` – backspace | `\a` – bell/alert 198 | `\'` – single quote | `\f` - form feed | `\d` - delete 199 | `\\` – single backslash | `\n` – newline | `\e` - escape 200 | | `\s` – space | `\r` – carriage return 201 | | `\t` - tab | `\0` - null byte 202 | | `\v` – vertical tab | 203 | 204 | `\x...` - character with hexadecimal representation.
205 | `\x{...}` - character with hexadecimal representation with one or more hexadecimal digits.
206 | ```elixir 207 | > "\x3f" == "?" # true 208 | > "\x{266B}" == "♫" # true 209 | > "\x{2660}" == "♠" # true 210 | ``` 211 | 212 | 213 | 214 | ### Regular Expression 215 | Inherited from Erlang's `re` module and are Perl compatible.
216 | Written literally with the `~r` [Sigil](#sigils) and can span multiple lines.
217 | Can have a number of modifiers specified directly after the pattern.
218 | Many functions take a captures option that limits captures. 219 | 220 | **Modifiers**: 221 | - `u` enables unicode specific patterns like \p and changes escapes like \w, \W, \s and friends to also match on unicode. It expects valid unicode strings to be given on match 222 | - `i` ignore case 223 | - `s` dot matches newlines and also set newline to anycrlf. 224 | - `m` ^ and $ match the start and end of each line; use \A and \z to match the end or start of the string 225 | - `x` whitespace characters are ignored except when escaped and `#` delimits comments 226 | - `f` forces the unanchored pattern to match before or at the first newline, though the matched text may continue over the newline 227 | r - inverts the “greediness” of the regexp 228 | 229 | **To override newline treatment start the pattern with**: 230 | - `(*CR)` carriage return 231 | - `(*LF)` line feed 232 | - `(*CRLF)` carriage return, followed by linefeed 233 | - `(*ANYCRLF)` any of the three above 234 | - `(*ANY)` all Unicode newline sequences 235 | 236 | ```elixir 237 | > Regex.compile!("caf[eé]") == ~r/caf[eé]/ # true 238 | > Regex.match?(~r/caf[eé]/, "café") # true 239 | > Regex.regex?(~r"caf[eé]") # true 240 | > Regex.regex?("caf[eé]") # false! string not compiled regex 241 | > Regex.run(~r/hat: (.*)/, "hat: 🎩", [capture: :all_but_first]) == ["🎩"] # true 242 | # Modifiers 243 | > Regex.match?(~r/mr. bojangles/i, "Mr. Bojangles") # true 244 | > Regex.compile!("mr. bojangles", "sxi") # ~r/mr. bojangles/sxi 245 | # Newline overrides 246 | > ~r/(*ANY)some\npattern/ 247 | ``` 248 | 249 | ## Collection Types 250 | 251 | ### List 252 | Simple linked lists that can be of any size and can have elements of any type.
253 | They are enclosed in `[ ]` and elements are comma separated.
254 | Concatenated with `++` and subtracted with `--`.
255 | Can be constructed with the cons operator `|`.
256 | Best for sequential access, fastest when elements are added and subtracted from the head.
257 | Instead of building a list by adding to its tail, add to the head and reverse the list.
258 | List implements the enumerable protocol so we use Enum for many common operations. 259 | 260 | ```elixir 261 | > [1, 2, 3.4, "a", "b", :c, [:d]] 262 | > [ 1 | [2 | [3]]] == [1, 2, 3] # true 263 | > [1, 2, 3.4] ++ ["a", "b", :c] # [1, 2, 3.4, "a", "b", :c] 264 | > [1, 2, 3.4, "a", "b", :c, [:d]] -- [2, "a", "c"] # [1, 3.4, "b", :c, [:d]] 265 | > hd [1, 2, 3] # 1 266 | > tl [1, 2, 3] # [2, 3] 267 | > length [:a, :b, :c, :d] # 4 268 | > Enum.reverse [:a, :b, :c] # [:c, :b, :a] 269 | > Enum.member? [:a, :b], :b # true 270 | > Enum.join [:a, :b], "_" # "a_b" 271 | > Enum.at [:a, :b, :c], 1 # :b 272 | ``` 273 | 274 | ### Charlist 275 | A [List](#list) of UTF-8 codepoints.
276 | Other than syntax they are exactly the same as Lists and are not a unique class.
277 | Can span multiple lines and are delimited with single quotes `'`.
278 | Have the same [Escape Sequences](#escape-sequences) as String.
279 | 280 | ```elixir 281 | > 'char list' 282 | > [108, 105, 115, 116] == 'list' # true 283 | > 'turbo' ++ 'pogo' # 'turbopogo' 284 | > 'char list' -- 'a l' # 'christ' 285 | > hd 'such list' == ?s # true 286 | > String.to_char_list "tacosalad" # 'tacosalad' 287 | > List.to_string 'frijoles' # "frijoles" 288 | > [?Y, ?e, ?a, ?h] == 'Yeah' # true 289 | ``` 290 | 291 | ### Tuple 292 | Can be of any size and have elements of any type.
293 | Elements are stored contiguously in memory.
294 | Enclosed in `{ }` and elements are comma separated.
295 | Fast for index-based access, slow for a large number of elements.
296 | 297 | ```elixir 298 | > { :a, 1, {:b}, [2]} 299 | > put_elem({:a}, 0, :b) # {:b} 300 | > elem({:a, :b, :c}, 1) # b 301 | > Tuple.delete_at({:a, :b, :c}, 1) # {:a, :c} 302 | > Tuple.insert_at({:a, :c}, 1, :b) # {:a, :b, :c} 303 | > Tuple.to_list({:a, :b, :c}) # [:a, :b, :c] 304 | ``` 305 | 306 | ### Keyword List 307 | A List of 2 element Tuples where each Tuple's first element is an Atom.
308 | This atom is refered to as the keyword, or key.
309 | Have a special concice syntax that omits the Tuple's brackets and places the key's colon on the right.
310 | Being Lists they: 311 | - are order as specified 312 | - can have duplicate elements and multiple elements with the same key 313 | - are fastest when accessed at the head. 314 | - are concatenated with `++` and subtracted with `--`.
315 | 316 | Elements can be accessed with `[:key]` notation. The first Element with a matching `:key` will be returned.
317 | 2 Keyword Lists are only equal if all elements are equal and in the same order. 318 | 319 | ```elixir 320 | # Full Syntax 321 | > [{:a, "one"}, {:b, 2}] 322 | # Concice Syntax 323 | > [a: "one", b: 2] 324 | > [a: 1] ++ [a: 2, b: 3] == [a: 1, a: 2, b: 3] # true 325 | > [a: 1, b: 2] == [b: 2, a: 1] # false! elements are in different order 326 | > [a: 1, a: 2][:a] == 1 # true 327 | > Keyword.keys([a: 1, b: 2]) # [:a, :b] 328 | > Keyword.get_values([a: 1, a: 2], :a) # [1, 2] 329 | > Keyword.keyword?([{:a,1}, {:b,2}]) # true 330 | > Keyword.keyword?([{:a,1}, {"b",2}]) # false! "b" is not an Atom 331 | > Keyword.delete([a: 1, b: 2], :a) # [b: 2] 332 | ``` 333 | 334 | ### Map 335 | Key - Value store where Keys and Values are of any type.
336 | Cannot have multiple values for the same key and are unordered.
337 | `Map`s are enclosed in `%{ }`, elements are comma seperated, and elemets have the form: key `=>` value.
338 | If all keys are `Atom`s, the `=>` can be omitted and the `Atom`'s `:` must be on the right.
339 | Values are accessed with `[key]` notation.
340 | Maps can be accessed with `.key` notation if key is an `Atom`.
341 | Maps can be updated by enclosing them in `%{}` and using the cons `|` operator.
342 | Maps can be of any size and are fastest for key based lookup. 343 | 344 | ```elixir 345 | > %{:a => 1, 1 => ["list"], [2,3,4] => {"a", "b"}} 346 | > %{:a => 1, :b => 2} == %{a: 1, b: 2} # true 347 | > %{a: "one", b: "two", a: 1} == %{a: 1, b: "two"} # true 348 | > %{a: "one", b: "two"} == %{b: "two", a: "one"} # true 349 | > %{a: "one", b: "two"}[:b] # "two" 350 | > %{a: "one", b: "two"}.b # "two" 351 | > %{a: "one", a: 1} == %{a: 1} # true 352 | > %{:a => "one", "a" => "two"}."a" == "two" # false! watchout 353 | > Map.keys( %{a: 1, b: 2} ) == [:a, :b] # true 354 | > %{ %{a: 1, b: 2, c: 3} | :a => 4, b: 5 } # %{a: 4, b: 5, c: 3} 355 | > Map.merge( %{a: 1, b: 2}, %{a: 4, c: 3} ) # %{a: 4, b: 2, c: 3} 356 | > Map.put( %{a: 1}, :b, 2 ) == %{a: 1, b: 2} # true 357 | > Kernel.get_in # TODO 358 | > Kernel.put_in # TODO 359 | ``` 360 | 361 | ### Struct 362 | Structs can be thought of as bare Maps with pre-defined keys, default values and where the keys must be atoms.
363 | Structs are defined at the top level of a Module and take the Module's name.
364 | Structs do not implement the Access or Enumerable protocol and can be considered bare Maps.
365 | Structs have a special field called `__struct__` that holds the name of the struct. 366 | 367 | ```elixir 368 | defmodule City do 369 | defstruct name: "New Orleans", founded: 1718 370 | end 371 | nola = %City{} 372 | chi = %City{name: "Chicago", founded: 1833} 373 | nola.name # "New Orleans" 374 | chi.founded # 1833 375 | nola.__struct__ # City 376 | ``` 377 | 378 | ### Range 379 | Used to specify the first and last elements of something.
380 | Just a Struct of type Range with a `first` field and a `last` field.
381 | Have a special `..` creation syntax but can also be created like any other struct. 382 | 383 | ```elixir 384 | > a = 5..10 385 | > b = Range.new(5, 10) 386 | > c = %Range{first: 5, last: 10} 387 | > Range.range?(c) # true 388 | > Enum.each(5..10, fn(n) -> n*n end) # prints all the squares of 5..10 389 | > Map.keys(5..10) # [:__struct__, :first, :last] 390 | > (5..10).first # 5 391 | ``` 392 | 393 | ### Streams 394 | Lazy enumerables.
395 | Are created out of enumerables with functions in the `Stream` module.
396 | Elements are not computed until a method from the `Enum` module is called on them.
397 | ```elixir 398 | > a = Stream.cycle 'abc' 399 | #Function<47.29647706/2 in Stream.unfold/2> # Infinate Stream created 400 | > Enum.take a, 10 # Enum.take computes the 10 elements 401 | 'abcabcabca' 402 | ``` 403 | 404 | With [Stream.unfold/2](http://elixir-lang.org/docs/stable/elixir/Stream.html#unfold/2) you can create an arbitrary stream. 405 | ```elixir 406 | > s = Stream.unfold( 5, 407 | fn 0 -> nil # returning nil halts the stream 408 | n -> {n, n-1} # return format {next-val, rest} 409 | end) 410 | > Enum.to_list(s) 411 | [5, 4, 3, 2, 1] 412 | ``` 413 | 414 | ## Syntax 415 | 416 | ### Variables 417 | Are declared and initialized upon use.
418 | Are named in the following format: 419 | 420 | ![variable naming](https://rawgit.com/itsgreggreg/elixir_quick_reference/50ffe1e533896247fbb6429b72f83cdbb1186a8a/images/variable-naming.png)
421 | Can hold any data structure and can be assigned more than once. 422 | 423 | ```elixir 424 | > something = :anything 425 | > something = ["a", "list", "of", "strings"] 426 | > _yeeHaw1234! = %{:a => :b} 427 | ``` 428 | 429 | ### Operators 430 | #### Standard infix 431 | - Equality `==`, `!=` 432 | - Strict equality `===` and `!==` do not coerce Floats to Integers. `1 === 1.0 #false` 433 | - Comparison `>`, `<`, `>=`, `<=` 434 | - Logic, short-circuiting `&&` and `||` 435 | - Boolean only Logic, short-circuiting `and` and `or`. (Only left side must be boolean) 436 | - Math `+`, `-`, `*`, `/` 437 | 438 | #### Standard prefix 439 | - Negation, any type `!`, `!1 == false` 440 | - Negation, boolean only `not`, `not is_atom(5) == true` 441 | 442 | #### = (match) 443 | left `=` right
444 | Performs a [Pattern Match](#pattern-matching). 445 | 446 | #### ^ (pin) 447 | Used to pin the value of a variable in the left side of a [Pattern Match](#pattern-matching). 448 | ```elixir 449 | a = "thirty hams" 450 | {b, ^a} = {:i_need, "thirty hams"} # `b` is set to `:i_need` 451 | {^a, {^a}} = {"thirty hams", {"thirty hams"}} # nothing is set, but the match succedes 452 | ``` 453 | 454 | #### |> (pipe) 455 | `|>`
456 | Takes the result of a statement on its left and passes as the first argument to the function on its right.
457 | The statement on the left can be on the preceeding line of code. 458 | ```elixir 459 | > [1,2,3] |> hd |> Integer.to_string |> IO.inspect # "1" 460 | # ⇣ doesn't work in iex 461 | hd([1,2,3]) 462 | |> Integer.to_string 463 | |> IO.inspect # "1" 464 | ``` 465 | 466 | #### =~ (string match) 467 | `=~`
468 | Takes a string on the left and on the right either a string or a regular expression.
469 | If the string on the right is a substring of left, `true` is returned.
470 | If the regular expression on the right matches the string on the left, `true` is returned.
471 | Otherwise `false` is returned. 472 | ```elixir 473 | > "abcd" =~ ~r/c(d)/ # true 474 | > "abcd" =~ ~r/e/ # false 475 | > "abcd" =~ "bc" # true 476 | > "abcd" =~ "ad" # false 477 | ``` 478 | 479 | #### ? (codepoint) 480 | `?`
481 | Returns the UTF-8 codepoint of the character immediately to its right.
482 | Can only take one character, accepts [Escape Sequences](#escape-sequences).
483 | **Remember** [Charlists](#charlist) are just lists of UTF-8 codepoints. 484 | ```elixir 485 | > ?a # 97 486 | > ?♫ # 9835 487 | > ?\s # 32 488 | > ?? # 63 489 | > [?♀, ?!] == '♀!' # true 490 | ``` 491 | 492 | #### & (capture) 493 | - TODO 494 | 495 | #### Ternary 496 | Elixir has no ternary operator. The same effect though can be achieved with the `if` macro. 497 | ```elixir 498 | > a = if true, do: "True!", else: "False!" 499 | > a == "True!" # true 500 | ``` 501 | 502 | #### in 503 | left `in` right.
504 | Used to check if the **enumerable** on the right contains the data structure on the left.
505 | Right hand side must implement the Enumerable Protocol. 506 | 507 | ```elixir 508 | > :b in [:a, :b, :c] # true 509 | > [:c] in [1,3,[:c]] # true 510 | > :ok in {:ok} # ERROR: protocol Enumerable not implemented for {:ok} 511 | ``` 512 | 513 | ### Comments 514 | `#` indicates that itself and anything after it until a new line is a comment. That is all. 515 | 516 | ### Semicolons 517 | Semicolons can be used to terminate statements but in practice are rarely if ever used.
518 | The only required usage is to put more than one statement on the same line. `a = 1; b = 2`
519 | This is considered bad style and placing them on seperate lines is much prefered. 520 | 521 | ### Do, End 522 | Blocks of code passed to macros start with `do` and end with `end`. 523 | ```elixir 524 | if true do 525 | "True!" 526 | end 527 | 528 | if true do "True!" end 529 | 530 | # inside a module 531 | def somefunc() do 532 | IO.puts "multi line" 533 | end 534 | 535 | if true do 536 | "True!" 537 | else 538 | "False!" 539 | end 540 | ``` 541 | 542 | You can pass the block as a single line and without `end` with some extra puctuation.
543 | ```elixir 544 | # ⇣ ⇣ ⇣ no end keyword 545 | if true, do: "True!" 546 | # ⇣ ⇣ ⇣ ⇣ ⇣ no end keyword 547 | if true, do: "True", else: "False!" 548 | # inside a module 549 | # ⇣ ⇣ ⇣ no end keyword 550 | def someFunc(), do: IO.puts "look ma, one line!" 551 | ``` 552 | 553 | Syntactic sugar for 554 | ```elixir 555 | if(true, [{:do, "True!"}, {:else, "False!"}]) 556 | def(someFunc(), [{:do, IO.puts "look ma, one line!"}]) 557 | ``` 558 | 559 | ### Pattern Matching 560 | A match has 2 main parts, a **left** side and a **right** side.
561 | ```elixir 562 | # ┌Left ┌Right 563 | # ┌───┴───┐ ┌───┴──────┐ 564 | {:one, x} = {:one, :two} 565 | # ┌Right 566 | # ┌───┴──────┐ 567 | case {:one, :two} do 568 | # ┌Left 569 | # ┌───┴───┐ 570 | {:one, x} -> IO.puts x 571 | # ┌Left 572 | _ -> IO.puts "no other match" 573 | end 574 | ``` 575 | 576 | The **right** side is a **data structure** of any kind.
577 | The **left** side attempts to **match** itself to the **data structure** on the right and **bind** any **variables** to **substructures**. 578 | 579 | The simplest **match** has a lone **variable** on the **left** and will **match** anything: 580 | ```elixir 581 | # in these examples `x` will be set to whatever is on the right 582 | x = 1 583 | x = [1,2,3,4] 584 | x = {:any, "structure", %{:whatso => :ever}} 585 | ``` 586 | 587 | But you can place the **variables** inside a **structure** so you can **capture** a **substructure**: 588 | ```elixir 589 | # `x` gets set to only the `substructure` it matches 590 | {:one, x} = {:one, :two} # `x` is set to `:two` 591 | [1,2,n,4] = [1,2,3,4] # `n` is set to `3` 592 | [:one, p] = [:one, {:apple, :orange}] # `p` is set to `{:apple, :orange}` 593 | ``` 594 | 595 | There is also a special `_` **variable** that works exactly like other **variables** but tells elixir, "Make sure something is here, but I don't care exactly what it is.": 596 | ```elixir 597 | # in all of these examples, `x` gets set to `:two` 598 | {_, x} = {:one, :two} 599 | {_, x} = {:three, :two} 600 | [_,_,x,_] = [1,{2},:two,3] 601 | ``` 602 | 603 | If you place a **variable** on the **right**, its **value** is used: 604 | ```elixir 605 | # ┌Same as writing {"twenty hams"} 606 | a = {"twenty hams"} ⇣ 607 | {:i_have, {b}} = {:i_have, a} # `b` is set to "twenty hams" 608 | ``` 609 | 610 | In the previous example you are telling elixir: I want to **match** a **structure** that is a **tuple**, and this **tuple's** first element is going to be the atom **:i_have**. This **tuple's** second element is going to be a **tuple**. This **second tuple** is going to have one element and whatever it is I want you to bind it to the variable **b**. 611 | 612 | If you want to use the **value** of a **variable** in your structure on the **left** you use the `^` operator: 613 | ```elixir 614 | a = "thirty hams" 615 | {b, ^a} = {:i_need, "thirty hams"} # `b` is set to `:i_need` 616 | {^a, {^a}} = {"thirty hams", {"thirty hams"}} # nothing is set, but the match succedes 617 | ``` 618 | 619 | #### Maps 620 | Individual keys can be matched in Maps like so: 621 | ```elixir 622 | nola = %{ name: "New Orleans", founded: 1718 } 623 | %{name: city_name} = nola # city_name now equals "New Orleans" 624 | %{name: _, founded: city_founded} = nola # Map must have both a name and a founded key 625 | ``` 626 | You can use the pin operator (^) to match on variables: 627 | ```elixir 628 | field = "founded" 629 | %{^field: city_founded} = nola # city_founded now equals 1718 630 | ``` 631 | 632 | #### Binaries 633 | - `<< size::8, rest::binary>> = <<3,0,25,1,1,2,1,6,4,3>>` 634 | - `<< data::size(size)-unit(16)-binary, rest::binary>> = rest` 635 | - TODO 636 | 637 | #### Ranges 638 | Ranges can be pattern matched if both their values are integers. 639 | ```elixir 640 | min..max = 20..5000 641 | min == 20 # true 642 | max == 5000 # true 643 | min..max == 1..10.0 # Thats an Argument Error 644 | ``` 645 | 646 | ### Reserved words 647 | These words are reserved for the language and cannot be used as variables, module or method names. 648 | 649 | `nil`, `true`, `false`, `__MODULE__`,`__FILE__`,`__DIR__`,`__ENV__`,`__CALLER__` 650 | 651 | ## Truthiness 652 | `:nil` and `:false` are falsy.
653 | `nil` and `false` are syntactic sugar for `:nil` and `:false`.
654 | Everything else is truthy. 655 | 656 | ```elixir 657 | > !!nil # false 658 | > !!0 # true 659 | > nil || :nil || false || :false || 1 # 1 660 | ``` 661 | 662 | ## Sorting 663 | Any types can be compared using comparison operators.
664 | `number < atom < reference < functions < port < pid < tuple < maps < list < bitstring` 665 | 666 | ```elixir 667 | 10000 < :five == true 668 | "something" > &div/2 == true 669 | ``` 670 | 671 | ## Modules 672 | Modules organize code under a namespace.
673 | They can be meta-programmed but are defined at compile time and cannot be changed after, only replaced .
674 | Named according to the following format:
675 | 676 | ![Module Naming](https://rawgit.com/itsgreggreg/elixir_quick_reference/75b339df6f6592dd123a8afad0449faae7bd36cc/images/module-naming.png) 677 | 678 | ### Declaration 679 | ```elixir 680 | defmodule MyModule do 681 | end 682 | ``` 683 | 684 | ### Module Functions 685 | Names must begin with `a-z`.
686 | Names can contain `a-Z`, `A-Z`, `0-9` and `_`.
687 | May end with `?` or `!`.
688 | 689 | ```elixir 690 | defmodule MyModule do 691 | def my_function do 692 | IO.puts("Hello from my function") 693 | end 694 | end 695 | ``` 696 | 697 | `def` is actually a macro, and like calling any macro, [do ... end](#do-end) can be written as a one liner: 698 | ```elixir 699 | defmodule MyModule do 700 | def my_function, do: IO.puts("Hello from my function") 701 | end 702 | ``` 703 | 704 | Inside of the defining module, functions may be called by name. Outside they must be called with the defining Module's name and a `.`. Eg: `IO.puts()` 705 | ```elixir 706 | defmodule MyModule do 707 | def function1 do 708 | IO.puts "func 1" 709 | end 710 | def function2 do 711 | function1 712 | IO.puts "funct 2" 713 | end 714 | end 715 | 716 | > MyModule.function2 717 | ``` 718 | 719 | Arguments are passed to functions positionally and can have default arguments.
720 | Arguments can be of any Type. 721 | ```elixir 722 | defmodule MyModule do 723 | # ⇣ indicates "earthlings" to be the default for who 724 | def greet(greeting, who \\ "earthlings") do 725 | IO.puts("#{greeting} #{who}") 726 | end 727 | end 728 | 729 | > MyModule.greet("'sup", "y'all?") # "'sup y'all?" 730 | > MyModule.greet("greetings") # "greetings earthlings" 731 | ``` 732 | 733 | Module functions can be defined multiple times to support different configurations of arguments. 734 | ```elixir 735 | defmodule MyModule do 736 | def greet() do 737 | greet("hello", "you") 738 | end 739 | def greet(greeting, who) do 740 | IO.puts("#{greeting} #{who}") 741 | end 742 | end 743 | 744 | > MyModule.printer("hello") # "hello" 745 | > MyModule.printer([1,2,3]) # [1,2,3] 746 | > MyModule.printer() # "nothing passed" 747 | ``` 748 | 749 | They can also be defined multiple times to Pattern Match on arguments passed. 750 | ```elixir 751 | def is_it_the_number_2?(2) do 752 | true 753 | end 754 | def is_it_the_number_2(value) do 755 | false 756 | end 757 | ``` 758 | 759 | You can ignore arguments with `_` and our previous example is better written as 760 | ```elixir 761 | def is_it_the_number_2?(2) do 762 | true 763 | end 764 | # ⇣ underscore ignores argument 765 | def is_it_the_number_2(_) do 766 | false 767 | end 768 | ``` 769 | 770 | Module function definitions can have [Guards](#guards). 771 | ```elixir 772 | def square(n) when is_number(n), do: n * n 773 | def square(_), do: raise "not a number" 774 | ``` 775 | 776 | ### Private Functions 777 | To make a function private to a module use `defp` instead of `def`. 778 | 779 | ```elixir 780 | defmodule ModA do 781 | defp hi, do: IO.puts "Hello from ModA" 782 | def say_hi, do: hi 783 | end 784 | ModA.say_hi 785 | # Hello from ModA 786 | ModA.hi 787 | # ** (UndefinedFunctionError) undefined function ModA.hi/0 ModA.hi() 788 | ``` 789 | 790 | ### Working with other modules 791 | Inside of a module you can use one of the 4 directives to interact with other modules. 792 | #### import 793 | `import SomeModule` brings all modules and macros of SomeModule into the enclosing module so you can use them un-namespaced
794 | `import` can take either an `only:` or `except:` list in which you specify functions and macros to include.
795 | Alternatively `import SomeModule, only:` can take `:functions` or `:macros` to specify only those. 796 | ```elixir 797 | def ModA do 798 | import ModB # All Functions and Macros in ModB 799 | import ModB, except: [destroy_planet: 1] # All Functions and Macros except destroy_planet/1 800 | import ModB, only: :functions # All functions, no macros 801 | import ModB, only: [say_hi: 0, fibonacci: 1] # Only the specified functions or macros 802 | end 803 | ``` 804 | 805 | #### require 806 | `require SomeModule` allows you to use macros of SomeModule. It also makes sure that SomeModule is compiled before the enclosing module. 807 | 808 | #### use 809 | `use SomeModule` first __requires SomeModule__ and then calls the macro SomeModule.\_\_using\_\_. It is often used to perform setup for metaprogramming. 810 | 811 | #### alias 812 | `alias SomeVery.Long.ModuleName, as: SVLMN` is used simply to shorten a module name to cut down on typing. 813 | 814 | ### Attributes 815 | Pieces of data that can be thought of as metadata or constants for a module.
816 | They are inlined by the compiler and cannot be changed at runtime.
817 | They can be set multiple times and the value used will be the value set when the function is defined. 818 | 819 | ```elixir 820 | defmodule ModA do 821 | @name "April" 822 | def first, do: @name 823 | @name "O'Neal" 824 | def last, do: @name 825 | end 826 | ``` 827 | 828 | TODO: 829 | - @external_resource 830 | - Better explanation of attributes in relation to metaprogramming 831 | 832 | ### Documentation 833 | Elixir has documentation built in and you can document your modules and functions with Attributes.
834 | `@moduledoc` describes your module.
835 | `@doc` describes module functions. 836 | ```elixir 837 | defmodule MathUtils do 838 | @moduledoc """ 839 | Random math related functions 840 | """ 841 | 842 | @doc "Squares the given number." 843 | def square(n), do: n*n 844 | end 845 | ``` 846 | 847 | ### Introspection 848 | - `__info__(:functions)` 849 | 850 | ## Errors 851 | Only to be used in exceptional circumstances, not for control flow.
852 | Built in errors are listed in the docs: http://elixir-lang.org/docs/stable/elixir/ArgumentError.html . They're on the left. 853 | 854 | ### Raise 855 | `raise` a runtime error: 856 | ```elixir 857 | > raise "not fabulous enough" 858 | ** (RuntimeError) not fabulous enough 859 | ``` 860 | 861 | `raise` a different error: 862 | ```elixir 863 | > raise ArgumentError, "I'm done. We're talking in circles." 864 | #** (ArgumentError) I'm done. We're talking in circles. 865 | ``` 866 | 867 | Some errors take specific options, and you must read the source to find them: 868 | ```elixir 869 | > raise KeyError, key: "to car", term: "pocket" 870 | #** (KeyError) key "to car" not found in: "pocket" 871 | ``` 872 | 873 | ### Custom Error 874 | ``` elixir 875 | defmodule LandWarWithRussiaError do 876 | defexception message: "Never." 877 | end 878 | > raise LandWarWithRussiaError 879 | #** (LandWarWithRussiaError) Never. 880 | ``` 881 | 882 | ### Rescue 883 | ```elixir 884 | try do 885 | if false do 886 | raise "are we there yet?" 887 | else 888 | raise ArgumentError, "I'll pull this car around!" 889 | end 890 | rescue 891 | e in RuntimeError -> IO.puts "No!" 892 | e in ArgumentError -> IO.puts "That's it we're going home!" 893 | end 894 | ``` 895 | 896 | **Remember** There are much better ways to control flow in Elixir than raising/rescuing errors.
897 | Errors should be reserved for truly exceptional situations. 898 | 899 | 900 | ## Control Flow 901 | ### if/unless 902 | ```elixir 903 | if :something_truthy do 904 | IO.puts "something truthy happened" 905 | else 906 | IO.puts "false or nil happened" 907 | end 908 | 909 | unless :something_truthy do 910 | IO.puts "nil or false happened" 911 | else 912 | IO.puts "something truthy happened" 913 | end 914 | ``` 915 | 916 | ### case 917 | `case` let's you pattern match on a value.
918 | If no cases match it throws a `MatchError`. 919 | ```elixir 920 | case 137 do 921 | "137" -> IO.puts "I require 137 the number." 922 | 137 -> IO.puts "Ahh much better." 923 | 138 -> 924 | IO.puts "Blocks can start on the next line as well." 925 | end 926 | ``` 927 | 928 | Like all pattern matches, `_` will match anything and can be used as a catchall: 929 | ```elixir 930 | case {:ok, "everything went to plan"} do 931 | {:ok, message} -> IO.puts message 932 | {:error, message} -> IO.puts "ERROR!: #{message}" 933 | # ⇣catchall, otherwise you'll get an error if nothing matches 934 | _ -> IO.puts "I match everything else!" 935 | end 936 | ``` 937 | 938 | You can have [guards](#guards) on your cases: 939 | ```elixir 940 | case 1_349 do 941 | n when is_integer n -> IO.puts "you gave me an integer" 942 | n when is_binary n -> IO.puts "you gave me a binary" 943 | _ -> IO.puts "you gave me neither an integer nor binary" 944 | end 945 | ``` 946 | 947 | ### cond 948 | `cond` takes one or more conditions and runs the first truthy one it finds.
949 | Often used where imperative languages would use elseif.
950 | If no statements evaluate to true it throws a `MatchError`. 951 | ```elixir 952 | cond do 953 | false -> IO.puts "I will never run" 954 | true -> IO.puts "I will always run" 955 | 1235 -> IO.puts "I would run if that dang true wasn't on top of me." 956 | end 957 | ``` 958 | 959 | `true` is often used as a catch all: 960 | ```elixir 961 | guess = 12 962 | cond do 963 | guess == 10 -> IO.puts "You guessed 10!" 964 | guess == 46 -> IO.puts "You guessed 46!" 965 | true -> 966 | IO.puts "I give up." 967 | end 968 | ``` 969 | ### throw/catch 970 | Inside of a `try` block you can `throw` any data type and pattern match on it inside a `catch` block.
971 | `catch` blocks work the same as [case](#case) blocks.
972 | `after` blocks will always run, throw or no throw. 973 | ```elixir 974 | try do 975 | IO.puts "Inside a try block" 976 | throw [:hey, "Reggie"] 977 | IO.puts "if there is a throw before me, I'll never run." 978 | catch 979 | x when is_number(x) -> IO.puts "!!A number was thrown." 980 | [:hey, name] -> IO.puts "!!Hey was thrown to #{name}." 981 | _ -> IO.puts "Something else was thrown." 982 | after 983 | IO.puts "I run regardless of a throw." 984 | end 985 | ``` 986 | 987 | ### with 988 | Takes a series of pattern matches, runs them in order, if all pattern matches succeed it returns its `do` block. If a pattern match doesn't succeed, the non-matching value is returned and `with` is exited.
989 | You can supply an `else` block that essentially functions as a `case` block for an uncussessful match.
990 | Variables assigned in a `with` block do not leak into outer scope.
991 | A comma must come after every match. 992 | 993 | ```elixir 994 | nums = [8,13,44] 995 | # ┌left arrow ┌comma 996 | # match left | match right | 997 | # ┌───┴────┐ ⇣ ┌───────┴─────────┐⇣ 998 | with {:ok, num} <- Enum.fetch(nums, 2), 999 | "44" <- Integer.to_string(num), 1000 | do: "it was 44" 1001 | 1002 | # Paterns can take guards 1003 | with a when is_nil(a) <- nil, 1004 | do: "Accepts guards" 1005 | else 1006 | _ -> "Does not accept guards" 1007 | 1008 | # From the docs 1009 | opts = %{width: 10, height: 15} 1010 | with {:ok, width} <- Map.fetch(opts, :width), 1011 | {:ok, height} <- Map.fetch(opts, :height), 1012 | do: {:ok, width * height} 1013 | # returns {:ok, 150} 1014 | 1015 | opts = %{width: 10} 1016 | with {:ok, width} <- Map.fetch(opts, :width), 1017 | {:ok, height} <- Map.fetch(opts, :height), 1018 | do: {:ok, width * height} 1019 | # returns :error as that's what Map.fetch returns when a key is not present. 1020 | # ┌─ Or you can catch the error in an else block 1021 | else 1022 | :error -> "A key wasn't found!" 1023 | 1024 | ``` 1025 | 1026 | ## Guards 1027 | TODO: how to use guards.
1028 | Errors generated in guards are swallowed and simply cause the guard to fail.
1029 | Functions and operators allowed in guard clauses: 1030 | 1031 | | = | logic | math | type_checking | map | tuple |list |binary | Kernel 1032 | |-----------|-------|-------|---------------|-----------|------------|---------|-----------|-------- 1033 | |== | or | + | is_atom | map_size()|elem() |a `in` b |bit_size() | node() 1034 | |!= | and | - | is_binary | |tuple_size()|hd() |byte_size()| self() 1035 | |=== | not | * | is_bitstring | | |tl() | | 1036 | |!== | | / | is_boolean | | |length() | | 1037 | |\> | |abs() | is_exception ||||| 1038 | |\< | |div() | is_float ||||| 1039 | |\<= | |float()| is_function ||||| 1040 | |\>= | |rem() | is_integer ||||| 1041 | | | |round()| is_nil ||||| 1042 | | | |trunc()| is_list ||||| 1043 | | | | | is_number ||||| 1044 | | | | | is_pid ||||| 1045 | | | | | is_port ||||| 1046 | | | | | is_reference ||||| 1047 | | | | | is_tuple ||||| 1048 | 1049 | **Notice** `!`, `&&` and `||` are not allowed in guard clauses. 1050 | 1051 | ## Anonymous Functions 1052 | Closures in which the captured variables are set at definition.
1053 | Are essentially [case](#case) blocks you can pass around.
1054 | Take the general form: 1055 | ```elixir 1056 | fn (1, 2, 3) -> IO.inspect 1*2*3 1057 | (a, b, c) -> IO.inspect [a,b,c] 1058 | end 1059 | ``` 1060 | Are called with the `.` operator. 1061 | ```elixir 1062 | > add_2 = fn num -> num + 2 end 1063 | # ⇣called with a dot 1064 | > add_2.(127) == 129 1065 | true 1066 | > three = 3 1067 | > add_3 = fn num -> num + three end 1068 | > add_3.(262) == 265 1069 | true 1070 | # ⇣is our function compromised? 1071 | > three = 7 1072 | # ⇣no, `three` is still 3 in the function 1073 | > add_3.(262) == 265 1074 | true 1075 | ``` 1076 | 1077 | Like case blocks, they can have multiple matches, matches can have guards, and do not leak scope: 1078 | ```elixir 1079 | > support_method = fn ("suspenders") -> IO.puts "Hey big spender." 1080 | ("belt") -> IO.puts "Who is the real hero?" 1081 | a when is_list a -> Enum.each(a, support_method) 1082 | _ -> IO.puts "What is this wizzardry?" 1083 | end 1084 | > support_method.(["belt", "suspenders"]) 1085 | "Who is the real hero?" 1086 | "Hey big spender." 1087 | > peanut_butter = "smooth" 1088 | # ⇣immediately call 1089 | > fn () -> peanut_butter = "chunky" end.() 1090 | > peanut_butter == "smooth" 1091 | true # scope was not leaked 1092 | ``` 1093 | 1094 | They **cannot** have multiple arities (which in case statements wouldn't make sense): 1095 | ```elixir 1096 | > fn (a) -> "One" 1097 | (a, b) -> "Two" 1098 | end 1099 | # That's a compile error 1100 | ``` 1101 | 1102 | ## Comprehensions 1103 | Loop over any enumerable or bitstring and build another.
1104 | By default they build lists.
1105 | `generators`, `filters` and `into:` are comma separated. `do` follows [Do, End](#do-end) rules.
1106 | Basic form: 1107 | ```elixir 1108 | # ┌for ┌Generator ┌Block 1109 | # ⇣ ┌────────┴────────┐┌──────┴──────┐ 1110 | > for num <- [1, 2, 3, 4], do: num * num 1111 | [1, 4, 9, 16] 1112 | ``` 1113 | 1114 | They can have filters: 1115 | ```elixir 1116 | # ┌Filter 1117 | # ┌────────┴───────┐ 1118 | > for num <- [1, 2, 3, 4], rem(num, 2) == 0, do: num * num 1119 | [4, 16] 1120 | ``` 1121 | 1122 | Multiple generators: 1123 | ```elixir 1124 | # ┌Generator ┌Generator 1125 | # ┌──────┴─────┐┌─────────┴───────┐ 1126 | > for num <- [1,2,3], str <- ["a", "b"], do: "#{num}#{str}" 1127 | ["1a", "1b", "2a", "2b", "3a", "3b"] 1128 | ``` 1129 | 1130 | Multiple filters: 1131 | ```elixir 1132 | # ┌Filter ┌Filter 1133 | # ┌─────┴───┐┌──────┴────┐ 1134 | > for num <- [1,2,3], str <- ["a", "b"], num !== 3, str !== "a", do: "#{num}#{str}" 1135 | ["1b", "2b"] 1136 | ``` 1137 | 1138 | You can pattern match in generators: 1139 | ```elixir 1140 | > for {_, age} <- %{doug: 4, lucy: 6, ralf: 10}, do: age 1141 | [4, 6, 10] 1142 | ``` 1143 | 1144 | You can build a different data structure with `into`: 1145 | ```elixir 1146 | # ┌Into a map 1147 | # ┌────┴────┐ 1148 | > for num <- [1, 2, 3, 4], into: %{}, do: {num, num*num} 1149 | %{1 => 1, 2 => 4, 3 => 9, 4 => 16} 1150 | # ┌Into a string 1151 | # ┌────┴───┐ 1152 | > for num <- [1, 2, 3, 4], into: "", do: "the square of #{num} is #{num * num}. " 1153 | "the square of 1 is 1. the square of 2 is 4. the square of 3 is 9. the square of 4 is 16. " 1154 | ``` 1155 | 1156 | Enumerating binaries is a breeze though they have a special syntax: 1157 | ```elixir 1158 | # ┌Binary generator 1159 | # ┌────────────┴─────────────────┐ 1160 | > for <> >>, do: byte 1161 | [255, 12, 55, 89] 1162 | # ┌Pattern Match on bit size 1163 | # ┌───┴───┐ 1164 | > for <> >>, do: bit 1165 | [0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0] 1166 | 1167 | > pixels = <<213, 45, 132, 64, 76, 32, 76, 0, 0, 234, 32, 15>> 1168 | # ⇣Short hand for bit-size 1169 | > for <>, do: {r, g, b} 1170 | [{213,45,132},{64,76,32},{76,0,0},{234,32,15}] 1171 | ``` 1172 | 1173 | Work well with streams: 1174 | ```elixir 1175 | # Grabs 5 lines of input and upcases it 1176 | stream = IO.stream(:stdio, :line) 1177 | for line <- Enum.take(stream, 5), into: stream do 1178 | String.upcase(line) 1179 | end 1180 | ``` 1181 | 1182 | ## Sigils 1183 | Sigils create structures out of text passed to them.
1184 | They take the general form `~type| content |m` and can be delimited by `{}`, `[]`, `()`, `//`, `||`, `""`, or `''`.
1185 | Built in sigils: 1186 | 1187 | Creates | With Interpolation | Without Interpolation 1188 | ------------------|:------------------:|:---------------------:| 1189 | String | s | S 1190 | Charlist | c | C 1191 | List of words | w | W 1192 | Regular Expression| r | R 1193 | 1194 | ```elixir 1195 | > a = "Yay!" 1196 | > ~s|Quotes #{a} 'used' "willy nilly.| # "Quotes Yay! 'used' \"willy nilly." 1197 | > ~S{Not "interpolated" #{a}} # "Not \"interpolated\" \#{a}" 1198 | > ~c[charlist "with" 'quotes' #{a}] # 'charlist "with" \'quotes\' Yay!' 1199 | > ~w/a list of words #{a}/ # ["a", "list", "of", "words", "Yay!"] 1200 | > ~W"a list of words #{a}" # ["a", "list", "of", "words", "\#{a}"] 1201 | ``` 1202 | 1203 | The `~w` and `~W` sigils can take modifier to specify which type of value to create, `a`, `c`, or `s` for `atom` `charlist` or `string`. 1204 | 1205 | ```elixir 1206 | > ~w|alpha bravo charlie|a # [:alpha, :bravo, :charlie] 1207 | > ~w|alpha bravo charlie|c # ['alpha', 'bravo', 'charlie'] 1208 | > ~w|alpha bravo charlie|s # ["alpha", "bravo", "charlie"] 1209 | ``` 1210 | 1211 | You can also define custom Sigils: 1212 | ```elixir 1213 | defmodule MySigil do 1214 | def sigil_i(string, 'd') do 1215 | for num <- String.split(string), do: String.to_integer(num) * 2 1216 | end 1217 | def sigil_i(string, _opts) do 1218 | for num <- String.split(string), do: String.to_integer(num) 1219 | end 1220 | end 1221 | > import MySigil 1222 | > ~i|1 2 3 4 5| # [1, 2, 3, 4, 5] 1223 | > ~i|1 2 3 4 5|d # [2, 4, 6, 8, 10] 1224 | ``` 1225 | 1226 | ## Metaprogramming 1227 | - macros 1228 | - quote 1229 | - unquote 1230 | - var! 1231 | 1232 | ## Processes 1233 | 1234 | ## Structs 1235 | - %ModuleName{} 1236 | - implement Map behaviour 1237 | - Pattern matching on structs 1238 | - @derive 1239 | 1240 | ## Working with Files 1241 | 1242 | ## Erlang Interoperability 1243 | Erlang modules can be called by prepnding them with a colon. 1244 | ```elixir 1245 | :crypto.hash(:sha, "Elixir is the beez knees") 1246 | |> :crypto.bytes_to_integer 1247 | |> Integer.to_string(16) # "62A3326DEDE3EE38C9C85ED6EC87FD888A130D24" 1248 | ``` 1249 | 1250 | ## IEx 1251 | Interactive Elixir. An Elixir REPL that comes with your Elixir install
1252 | 1253 | ### Running 1254 | run `iex` from a command prompt to enter iex.
1255 | `iex some_file.ex` will compile ./some_file.ex and load it into iex.
1256 | 1257 | ### Using 1258 | iex has built in tab completion. Press tab at an empty prompt to see all functions available. 1259 | 1260 | #### Some useful functions 1261 | - h/0 : Documentation for IEx helpers 1262 | - h/1 : Documentation for a Module or Function 1263 | - i/1 : Inforamtion about a value 1264 | - c/1 : Compile and load a file 1265 | - r/1 : Reload a module 1266 | 1267 | TODO:
1268 | - `-S mix` 1269 | 1270 | ## Mix 1271 | Task runner, build tool, testing harness.
1272 | Run `mix help` from the command line for more details.
1273 | 1274 | ### Applications 1275 | `mix new PATH` generates the boilerplate for an elixir application.
1276 | Run `mix help new` for more details. 1277 | 1278 | ### Tasks 1279 | Mix tasks are modules under the `Mix.Task` namespace that `use Mix.Task` and implement a `run/1` function.
1280 | If you want your task to show up when `mix help` is run you must include a `@shortdoc`.
1281 | `@moduledoc` gets displayed when `mix help sometask` is run. 1282 | A base mix task file looks like: 1283 | ```elixir 1284 | defmodule Mix.Tasks.MyTask do 1285 | use Mix.Task 1286 | @shortdoc "Boilerplate for a task" 1287 | @moduledoc """ 1288 | This task just echos out the options passed to it. 1289 | """ 1290 | def run(opts) do 1291 | IO.inspect(opts) 1292 | end 1293 | end 1294 | ``` 1295 | 1296 | Elixir has a built in option parser that you should use for such a task:
1297 | http://elixir-lang.org/docs/stable/elixir/OptionParser.html 1298 | 1299 | ## Tests 1300 | Testing is built into the elixir platform via [ExUnit](http://elixir-lang.org/docs/stable/ex_unit/).
1301 | You can define tests in two ways.
1302 | If you are in a Mix Application, you put tests in files under the `test` directory.
1303 | These tests will be run with `mix test`.
1304 | You can also place tests at the end of any elixir file and they will be run on compilation.
1305 | Test boilerplate looks like: 1306 | ```elixir 1307 | # ⇣ not needed if in a mix project, setup for you in test_helper.exs 1308 | ExUnit.start 1309 | 1310 | defmodule MyModuleTest do 1311 | use ExUnit.Case 1312 | 1313 | test "the truth" do 1314 | assert 1 + 1 == 2 1315 | end 1316 | end 1317 | ``` 1318 | 1319 | ### Debugging in the context of a test 1320 | 1321 | 1. First add to the top of your test file (before `defmodule`): 1322 | ```elixir 1323 | require IEx 1324 | ``` 1325 | 1326 | 2. Inside your test, where you want to break into IEx, add: 1327 | ``` 1328 | IEx.pry 1329 | ``` 1330 | 1331 | 3. Run your tests with this invocation: 1332 | ```elixir 1333 | iex -S mix test --trace 1334 | ``` 1335 | The `--trace` prevents iex from timing out after you've broken into pry. 1336 | 1337 | 1338 | ## Style Guide 1339 | - Module, record, protocol and behaviour names start with an initial cap and are BumpyCase. 1340 | - Ex: MyModule 1341 | - All other identifiers start with a lowercase letter or an underscore and are snake_case. 1342 | - Ex: in_the_air_tonight 1343 | - For indentation use 2 spaces. No Tabs. 1344 | 1345 |
1346 | **Notes** 1347 | - Regex images generated here: http://jex.im/regulex/ 1348 | -------------------------------------------------------------------------------- /images/atom-naming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsgreggreg/elixir_quick_reference/167c37fd08bbc91188990981b0569a965e3687eb/images/atom-naming.png -------------------------------------------------------------------------------- /images/module-naming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsgreggreg/elixir_quick_reference/167c37fd08bbc91188990981b0569a965e3687eb/images/module-naming.png -------------------------------------------------------------------------------- /images/variable-naming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsgreggreg/elixir_quick_reference/167c37fd08bbc91188990981b0569a965e3687eb/images/variable-naming.png --------------------------------------------------------------------------------