# elixir v1.18.0-rc.0 > Elixir is a dynamic, functional language for building scalable and maintainable applications. ## Docs ### Kernel (module) `Kernel` is Elixir's default environment. It mainly consists of: * basic language primitives, such as arithmetic operators, spawning of processes, data type handling, and others * macros for control-flow and defining new functionality (modules, functions, and the like) * guard checks for augmenting pattern matching You can invoke `Kernel` functions and macros anywhere in Elixir code without the use of the `Kernel.` prefix since they have all been automatically imported. For example, in IEx, you can call: iex> is_number(13) true If you don't want to import a function or macro from `Kernel`, use the `:except` option and then list the function/macro by arity: import Kernel, except: [if: 2, unless: 2] See `import/2` for more information on importing. Elixir also has special forms that are always imported and cannot be skipped. These are described in `Kernel.SpecialForms`. ### The standard library - Kernel (module) `Kernel` provides the basic capabilities the Elixir standard library is built on top of. It is recommended to explore the standard library for advanced functionality. Here are the main groups of modules in the standard library (this list is not a complete reference, see the documentation sidebar for all entries). ### Built-in types - Kernel (module) The following modules handle Elixir built-in data types: * `Atom` - literal constants with a name (`true`, `false`, and `nil` are atoms) * `Float` - numbers with floating point precision * `Function` - a reference to code chunk, created with the `fn/1` special form * `Integer` - whole numbers (not fractions) * `List` - collections of a variable number of elements (linked lists) * `Map` - collections of key-value pairs * `Process` - light-weight threads of execution * `Port` - mechanisms to interact with the external world * `Tuple` - collections of a fixed number of elements There are two data types without an accompanying module: * Bitstring - a sequence of bits, created with `<<>>/1`. When the number of bits is divisible by 8, they are called binaries and can be manipulated with Erlang's `:binary` module * Reference - a unique value in the runtime system, created with `make_ref/0` ### Data types - Kernel (module) Elixir also provides other data types that are built on top of the types listed above. Some of them are: * `Date` - `year-month-day` structs in a given calendar * `DateTime` - date and time with time zone in a given calendar * `Exception` - data raised from errors and unexpected scenarios * `MapSet` - unordered collections of unique elements * `NaiveDateTime` - date and time without time zone in a given calendar * `Keyword` - lists of two-element tuples, often representing optional values * `Range` - inclusive ranges between two integers * `Regex` - regular expressions * `String` - UTF-8 encoded binaries representing characters * `Time` - `hour:minute:second` structs in a given calendar * `URI` - representation of URIs that identify resources * `Version` - representation of versions and requirements ### System modules - Kernel (module) Modules that interface with the underlying system, such as: * `IO` - handles input and output * `File` - interacts with the underlying file system * `Path` - manipulates file system paths * `System` - reads and writes system information ### Protocols - Kernel (module) Protocols add polymorphic dispatch to Elixir. They are contracts implementable by data types. See `Protocol` for more information on protocols. Elixir provides the following protocols in the standard library: * `Collectable` - collects data into a data type * `Enumerable` - handles collections in Elixir. The `Enum` module provides eager functions for working with collections, the `Stream` module provides lazy functions * `Inspect` - converts data types into their programming language representation * `List.Chars` - converts data types to their outside world representation as charlists (non-programming based) * `String.Chars` - converts data types to their outside world representation as strings (non-programming based) ### Process-based and application-centric functionality - Kernel (module) The following modules build on top of processes to provide concurrency, fault-tolerance, and more. * `Agent` - a process that encapsulates mutable state * `Application` - functions for starting, stopping and configuring applications * `GenServer` - a generic client-server API * `Registry` - a key-value process-based storage * `Supervisor` - a process that is responsible for starting, supervising and shutting down other processes * `Task` - a process that performs computations * `Task.Supervisor` - a supervisor for managing tasks exclusively ### Supporting documents - Kernel (module) Under the "Pages" section in sidebar you will find tutorials, guides, and reference documents that outline Elixir semantics and behaviors in more detail. Those are: * [Compatibility and deprecations](compatibility-and-deprecations.md) - lists compatibility between every Elixir version and Erlang/OTP, release schema; lists all deprecated functions, when they were deprecated and alternatives * [Library guidelines](library-guidelines.md) - general guidelines, anti-patterns, and rules for those writing libraries * [Naming conventions](naming-conventions.md) - naming conventions for Elixir code * [Operators reference](operators.md) - lists all Elixir operators and their precedences * [Patterns and guards](patterns-and-guards.md) - an introduction to patterns, guards, and extensions * [Syntax reference](syntax-reference.md) - the language syntax reference * [Typespecs reference](typespecs.md)- types and function specifications, including list of types * [Unicode syntax](unicode-syntax.md) - outlines Elixir support for Unicode ### Guards - Kernel (module) This module includes the built-in guards used by Elixir developers. They are a predefined set of functions and macros that augment pattern matching, typically invoked after the `when` operator. For example: def drive(%User{age: age}) when age >= 16 do ... end The clause above will only be invoked if the user's age is more than or equal to 16. Guards also support joining multiple conditions with `and` and `or`. The whole guard is true if all guard expressions will evaluate to `true`. A more complete introduction to guards is available in the [Patterns and guards](patterns-and-guards.md) page. ### Truthy and falsy values - Kernel (module) Besides the booleans `true` and `false`, Elixir has the concept of a "truthy" or "falsy" value. * a value is truthy when it is neither `false` nor `nil` * a value is falsy when it is either `false` or `nil` Elixir has functions, like `and/2`, that *only* work with booleans, but also functions that work with these truthy/falsy values, like `&&/2` and `!/1`. ### Structural comparison - Kernel (module) The functions in this module perform structural comparison. This allows different data types to be compared using comparison operators: 1 < :an_atom This is possible so Elixir developers can create collections, such as dictionaries and ordered sets, that store a mixture of data types in them. To understand why this matters, let's discuss the two types of comparisons we find in software: _structural_ and _semantic_. Structural means we are comparing the underlying data structures and we often want those operations to be as fast as possible, because it is used to power several algorithms and data structures in the language. A semantic comparison worries about what each data type represents. For example, semantically speaking, it doesn't make sense to compare `Time` with `Date`. One example that shows the differences between structural and semantic comparisons are strings: "alien" sorts less than "office" (`"alien" < "office"`) but "álien" is greater than "office". This happens because `<` compares the underlying bytes that form the string. If you were doing alphabetical listing, you may want "álien" to also appear before "office". This means **comparisons in Elixir are structural**, as it has the goal of comparing data types as efficiently as possible to create flexible and performant data structures. This distinction is specially important for functions that provide ordering, such as `>/2`, `=/2`, `<=/2`, `min/2`, and `max/2`. For example: ~D[2017-03-31] > ~D[2017-04-01] will return `true` because structural comparison compares the `:day` field before `:month` or `:year`. Luckily, the Elixir compiler will detect whenever comparing structs or whenever comparing code that is either always true or false, and emit a warning accordingly. In order to perform semantic comparisons, the relevant data-types provide a `compare/2` function, such as `Date.compare/2`: iex> Date.compare(~D[2017-03-31], ~D[2017-04-01]) :lt Alternatively, you can use the functions in the `Enum` module to sort or compute a maximum/minimum: iex> Enum.sort([~D[2017-03-31], ~D[2017-04-01]], Date) [~D[2017-03-31], ~D[2017-04-01]] iex> Enum.max([~D[2017-03-31], ~D[2017-04-01]], Date) ~D[2017-04-01] The second argument is precisely the module to be used for semantic comparison. Keeping this distinction is important, because if semantic comparison was used by default for implementing data structures and algorithms, they could become orders of magnitude slower! Finally, note there is an overall structural sorting order, called "Term Ordering", defined below. This order is provided for reference purposes, it is not required by Elixir developers to know it by heart. ### Term ordering - Kernel (module) ``` number < atom < reference < function < port < pid < tuple < map < list < bitstring ``` When comparing two numbers of different types (a number being either an integer or a float), a conversion to the type with greater precision will always occur, unless the comparison operator used is either `===/2` or `!==/2`. A float will be considered more precise than an integer, unless the float is greater/less than +/-9007199254740992.0 respectively, at which point all the significant figures of the float are to the left of the decimal point. This behavior exists so that the comparison of large numbers remains transitive. The collection types are compared using the following rules: * Tuples are compared by size, then element by element. * Maps are compared by size, then by key-value pairs. * Lists are compared element by element. * Bitstrings are compared byte by byte, incomplete bytes are compared bit by bit. * Atoms are compared using their string value, codepoint by codepoint. ### Examples - Kernel (module) We can check the truthiness of a value by using the `!/1` function twice. Truthy values: iex> !!true true iex> !!5 true iex> !![1,2] true iex> !!"foo" true Falsy values (of which there are exactly two): iex> !!false false iex> !!nil false ### Inlining - Kernel (module) Some of the functions described in this module are inlined by the Elixir compiler into their Erlang counterparts in the [`:erlang`](`:erlang`) module. Those functions are called BIFs (built-in internal functions) in Erlang-land and they exhibit interesting properties, as some of them are allowed in guards and others are used for compiler optimizations. Most of the inlined functions can be seen in effect when capturing the function: iex> &Kernel.is_atom/1 &:erlang.is_atom/1 Those functions will be explicitly marked in their docs as "inlined by the compiler". ### Kernel.&&/2 (macro) Boolean "and" operator. Provides a short-circuit operator that evaluates and returns the second expression only if the first one evaluates to a truthy value (neither `false` nor `nil`). Returns the first expression otherwise. Not allowed in guard clauses. ### Examples - Kernel.&&/2 (macro) iex> Enum.empty?([]) && Enum.empty?([]) true iex> List.first([]) && true nil iex> Enum.empty?([]) && List.first([1]) 1 iex> false && throw(:bad) false Note that, unlike `and/2`, this operator accepts any expression as the first argument, not only booleans. ### Kernel.**/2 (function) Power operator. It takes two numbers for input. If both are integers and the right-hand side (the `exponent`) is also greater than or equal to 0, then the result will also be an integer. Otherwise it returns a float. ### Examples - Kernel.**/2 (function) iex> 2 ** 2 4 iex> 2 ** -4 0.0625 iex> 2.0 ** 2 4.0 iex> 2 ** 2.0 4.0 ### Kernel.*/2 (function) Arithmetic multiplication operator. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.*/2 (function) iex> 1 * 2 2 ### Kernel.++/2 (function) List concatenation operator. Concatenates a proper list and a term, returning a list. The complexity of `a ++ b` is proportional to `length(a)`, so avoid repeatedly appending to lists of arbitrary length, for example, `list ++ [element]`. Instead, consider prepending via `[element | rest]` and then reversing. If the `right` operand is not a proper list, it returns an improper list. If the `left` operand is not a proper list, it raises `ArgumentError`. If the `left` operand is an empty list, it returns the `right` operand. Inlined by the compiler. ### Examples - Kernel.++/2 (function) iex> [1] ++ [2, 3] [1, 2, 3] iex> ~c"foo" ++ ~c"bar" ~c"foobar" # a non-list on the right will return an improper list # with said element at the end iex> [1, 2] ++ 3 [1, 2 | 3] iex> [1, 2] ++ {3, 4} [1, 2 | {3, 4}] # improper list on the right will return an improper list iex> [1] ++ [2 | 3] [1, 2 | 3] # empty list on the left will return the right operand iex> [] ++ 1 1 The `++/2` operator is right associative, meaning: iex> [1, 2, 3] -- [1] ++ [2] [3] As it is equivalent to: iex> [1, 2, 3] -- ([1] ++ [2]) [3] ### Kernel.+/1 (function) Arithmetic positive unary operator. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.+/1 (function) iex> +1 1 ### Kernel.+/2 (function) Arithmetic addition operator. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.+/2 (function) iex> 1 + 2 3 ### Kernel.--/2 (function) List subtraction operator. Removes the first occurrence of an element on the left list for each element on the right. This function is optimized so the complexity of `a -- b` is proportional to `length(a) * log(length(b))`. See also the [Erlang efficiency guide](https://www.erlang.org/doc/system/efficiency_guide.html). Inlined by the compiler. ### Examples - Kernel.--/2 (function) iex> [1, 2, 3] -- [1, 2] [3] iex> [1, 2, 3, 2, 1] -- [1, 2, 2] [3, 1] The `--/2` operator is right associative, meaning: iex> [1, 2, 3] -- [2] -- [3] [1, 3] As it is equivalent to: iex> [1, 2, 3] -- ([2] -- [3]) [1, 3] ### Kernel.-/1 (function) Arithmetic negative unary operator. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.-/1 (function) iex> -2 -2 ### Kernel.-/2 (function) Arithmetic subtraction operator. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.-/2 (function) iex> 1 - 2 -1 ### Kernel.../0 (macro) Creates the full-slice range `0..-1//1`. This macro returns a range with the following properties: * When enumerated, it is empty * When used as a `slice`, it returns the sliced element as is See `..///3` and the `Range` module for more information. ### Examples - Kernel.../0 (macro) iex> Enum.to_list(..) [] iex> String.slice("Hello world!", ..) "Hello world!" ### Kernel.../2 (macro) Creates a range from `first` to `last`. If first is less than last, the range will be increasing from first to last. If first is equal to last, the range will contain one element, which is the number itself. If first is more than last, the range will be decreasing from first to last, albeit this behavior is deprecated. Instead prefer to explicitly list the step with `first..last//-1`. See the `Range` module for more information. ### Examples - Kernel.../2 (macro) iex> 0 in 1..3 false iex> 2 in 1..3 true iex> Enum.to_list(1..3) [1, 2, 3] ### Kernel...///3 (macro) Creates a range from `first` to `last` with `step`. See the `Range` module for more information. ### Examples - Kernel...///3 (macro) iex> 0 in 1..3//1 false iex> 2 in 1..3//1 true iex> 2 in 1..3//2 false iex> Enum.to_list(1..3//1) [1, 2, 3] iex> Enum.to_list(1..3//2) [1, 3] iex> Enum.to_list(3..1//-1) [3, 2, 1] iex> Enum.to_list(1..0//1) [] ### Kernel.//2 (function) Arithmetic division operator. The result is always a float. Use `div/2` and `rem/2` if you want an integer division or the remainder. Raises `ArithmeticError` if `right` is 0 or 0.0. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.//2 (function) 1 / 2 #=> 0.5 -3.0 / 2.0 #=> -1.5 5 / 1 #=> 5.0 7 / 0 ** (ArithmeticError) bad argument in arithmetic expression ### Kernel.!/1 (macro) Boolean "not" operator. Receives any value (not just booleans) and returns `true` if `value` is `false` or `nil`; returns `false` otherwise. Not allowed in guard clauses. ### Examples - Kernel.!/1 (macro) iex> !Enum.empty?([]) false iex> !List.first([]) true ### Kernel.!=/2 (function) Not equal to operator. Returns `true` if the two terms are not equal. This operator considers 1 and 1.0 to be equal. For match comparison, use `!==/2` instead. This performs a structural comparison where all Elixir terms can be compared with each other. See the ["Structural comparison"](#module-structural-comparison) section for more information. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.!=/2 (function) iex> 1 != 2 true iex> 1 != 1.0 false ### Kernel.!==/2 (function) Strictly not equal to operator. Returns `true` if the two terms are not exactly equal. See `===/2` for a definition of what is considered "exactly equal". This performs a structural comparison where all Elixir terms can be compared with each other. See the ["Structural comparison"](#module-structural-comparison) section for more information. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.!==/2 (function) iex> 1 !== 2 true iex> 1 !== 1.0 true ### Kernel. 1 < 2 true ### Kernel.<=/2 (function) Less-than or equal to operator. Returns `true` if `left` is less than or equal to `right`. This performs a structural comparison where all Elixir terms can be compared with each other. See the ["Structural comparison"](#module-structural-comparison) section for more information. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.<=/2 (function) iex> 1 <= 2 true ### Kernel.<>/2 (macro) Binary concatenation operator. Concatenates two binaries. Raises an `ArgumentError` if one of the sides aren't binaries. ### Examples - Kernel.<>/2 (macro) iex> "foo" <> "bar" "foobar" The `<>/2` operator can also be used in pattern matching (and guard clauses) as long as the left argument is a literal binary: iex> "foo" <> x = "foobar" iex> x "bar" `x <> "bar" = "foobar"` would result in an `ArgumentError` exception. ### Kernel.==/2 (function) Equal to operator. Returns `true` if the two terms are equal. This operator considers 1 and 1.0 to be equal. For stricter semantics, use `===/2` instead. This performs a structural comparison where all Elixir terms can be compared with each other. See the ["Structural comparison"](#module-structural-comparison) section for more information. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.==/2 (function) iex> 1 == 2 false iex> 1 == 1.0 true ### Kernel.===/2 (function) Strictly equal to operator. Returns `true` if the two terms are exactly equal. The terms are only considered to be exactly equal if they have the same value and are of the same type. For example, `1 == 1.0` returns `true`, but since they are of different types, `1 === 1.0` returns `false`. This performs a structural comparison where all Elixir terms can be compared with each other. See the ["Structural comparison"](#module-structural-comparison) section for more information. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.===/2 (function) iex> 1 === 2 false iex> 1 === 1.0 false ### Kernel.=~/2 (function) Text-based match operator. Matches the term on the `left` against the regular expression or string on the `right`. If `right` is a regular expression, returns `true` if `left` matches right. If `right` is a string, returns `true` if `left` contains `right`. ### Examples - Kernel.=~/2 (function) iex> "abcd" =~ ~r/c(d)/ true iex> "abcd" =~ ~r/e/ false iex> "abcd" =~ ~r// true iex> "abcd" =~ "bc" true iex> "abcd" =~ "ad" false iex> "abcd" =~ "abcd" true iex> "abcd" =~ "" true For more information about regular expressions, please check the `Regex` module. ### Kernel.>/2 (function) Greater-than operator. Returns `true` if `left` is more than `right`. This performs a structural comparison where all Elixir terms can be compared with each other. See the ["Structural comparison"](#module-structural-comparison) section for more information. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.>/2 (function) iex> 1 > 2 false ### Kernel.>=/2 (function) Greater-than or equal to operator. Returns `true` if `left` is more than or equal to `right`. This performs a structural comparison where all Elixir terms can be compared with each other. See the ["Structural comparison"](#module-structural-comparison) section for more information. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.>=/2 (function) iex> 1 >= 2 false ### Kernel.@/1 (macro) Module attribute unary operator. Reads and writes attributes in the current module. The canonical example for attributes is annotating that a module implements an OTP behaviour, such as `GenServer`: defmodule MyServer do @behaviour GenServer # ... callbacks ... end By default Elixir supports all the module attributes supported by Erlang, but custom attributes can be used as well: defmodule MyServer do @my_data 13 IO.inspect(@my_data) #=> 13 end Unlike Erlang, such attributes are not stored in the module by default since it is common in Elixir to use custom attributes to store temporary data that will be available at compile-time. Custom attributes may be configured to behave closer to Erlang by using `Module.register_attribute/3`. > #### Prefixing module attributes {: .tip} > > Libraries and frameworks should consider prefixing any > module attributes that are private by underscore, such as `@_my_data`, > so code completion tools do not show them on suggestions and prompts. Finally, note that attributes can also be read inside functions: defmodule MyServer do @my_data 11 def first_data, do: @my_data @my_data 13 def second_data, do: @my_data end MyServer.first_data() #=> 11 MyServer.second_data() #=> 13 It is important to note that reading an attribute takes a snapshot of its current value. In other words, the value is read at compilation time and not at runtime. Check the `Module` module for other functions to manipulate module attributes. ### Attention! Multiple references of the same attribute - Kernel.@/1 (macro) As mentioned above, every time you read a module attribute, a snapshot of its current value is taken. Therefore, if you are storing large values inside module attributes (for example, embedding external files in module attributes), you should avoid referencing the same attribute multiple times. For example, don't do this: @files %{ example1: File.read!("lib/example1.data"), example2: File.read!("lib/example2.data") } def example1, do: @files[:example1] def example2, do: @files[:example2] In the above, each reference to `@files` may end-up with a complete and individual copy of the whole `@files` module attribute. Instead, reference the module attribute once in a private function: @files %{ example1: File.read!("lib/example1.data"), example2: File.read!("lib/example2.data") } defp files(), do: @files def example1, do: files()[:example1] def example2, do: files()[:example2] ### Kernel.abs/1 (function) Returns an integer or float which is the arithmetical absolute value of `number`. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.abs/1 (function) iex> abs(-3.33) 3.33 iex> abs(-3) 3 ### Kernel.alias!/1 (macro) When used inside quoting, marks that the given alias should not be hygienized. This means the alias will be expanded when the macro is expanded. Check `quote/2` for more information. ### Kernel.and/2 (macro) Strictly boolean "and" operator. If `left` is `false`, returns `false`, otherwise returns `right`. Requires only the `left` operand to be a boolean since it short-circuits. If the `left` operand is not a boolean, a `BadBooleanError` exception is raised. Allowed in guard tests. ### Examples - Kernel.and/2 (macro) iex> true and false false iex> true and "yay!" "yay!" iex> "yay!" and true ** (BadBooleanError) expected a boolean on left-side of "and", got: "yay!" ### Kernel.apply/2 (function) Invokes the given anonymous function `fun` with the list of arguments `args`. If the number of arguments is known at compile time, prefer `fun.(arg_1, arg_2, ..., arg_n)` as it is clearer than `apply(fun, [arg_1, arg_2, ..., arg_n])`. Inlined by the compiler. ### Examples - Kernel.apply/2 (function) iex> apply(fn x -> x * 2 end, [2]) 4 ### Kernel.apply/3 (function) Invokes the given function from `module` with the list of arguments `args`. `apply/3` is used to invoke functions where the module, function name or arguments are defined dynamically at runtime. For this reason, you can't invoke macros using `apply/3`, only functions. If the number of arguments and the function name are known at compile time, prefer `module.function(arg_1, arg_2, ..., arg_n)` as it is clearer than `apply(module, :function, [arg_1, arg_2, ..., arg_n])`. `apply/3` cannot be used to call private functions. Inlined by the compiler. ### Examples - Kernel.apply/3 (function) iex> apply(Enum, :reverse, [[1, 2, 3]]) [3, 2, 1] ### Kernel.binary_part/3 (function) Extracts the part of the binary at `start` with `size`. If `start` or `size` reference in any way outside the binary, an `ArgumentError` exception is raised. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.binary_part/3 (function) iex> binary_part("foo", 1, 2) "oo" A negative `size` can be used to extract bytes that come *before* the byte at `start`: iex> binary_part("Hello", 5, -3) "llo" An `ArgumentError` is raised when the `size` is outside of the binary: binary_part("Hello", 0, 10) ** (ArgumentError) argument error ### Kernel.binary_slice/2 (function) Returns a binary from the offset given by the start of the range to the offset given by the end of the range. If the start or end of the range are negative, they are converted into positive indices based on the binary size. For example, `-1` means the last byte of the binary. This is similar to `binary_part/3` except that it works with ranges and it is not allowed in guards. This function works with bytes. For a slicing operation that considers characters, see `String.slice/2`. ### Examples - Kernel.binary_slice/2 (function) iex> binary_slice("elixir", 0..5) "elixir" iex> binary_slice("elixir", 1..3) "lix" iex> binary_slice("elixir", 1..10) "lixir" iex> binary_slice("elixir", -4..-1) "ixir" iex> binary_slice("elixir", -4..6) "ixir" iex> binary_slice("elixir", -10..10) "elixir" For ranges where `start > stop`, you need to explicitly mark them as increasing: iex> binary_slice("elixir", 2..-1//1) "ixir" iex> binary_slice("elixir", 1..-2//1) "lixi" You can use `../0` as a shortcut for `0..-1//1`, which returns the whole binary as is: iex> binary_slice("elixir", ..) "elixir" The step can be any positive number. For example, to get every 2 characters of the binary: iex> binary_slice("elixir", 0..-1//2) "eii" If the first position is after the string ends or after the last position of the range, it returns an empty string: iex> binary_slice("elixir", 10..3//1) "" iex> binary_slice("elixir", -10..-7) "" iex> binary_slice("a", 1..1500) "" ### Kernel.binary_slice/3 (function) Returns a binary starting at the offset `start` and of the given `size`. This is similar to `binary_part/3` except that if `start + size` is greater than the binary size, it automatically clips it to the binary size instead of raising. Opposite to `binary_part/3`, this function is not allowed in guards. This function works with bytes. For a slicing operation that considers characters, see `String.slice/3`. ### Examples - Kernel.binary_slice/3 (function) iex> binary_slice("elixir", 0, 6) "elixir" iex> binary_slice("elixir", 0, 5) "elixi" iex> binary_slice("elixir", 1, 4) "lixi" iex> binary_slice("elixir", 0, 10) "elixir" If `start` is negative, it is normalized against the binary size and clamped to 0: iex> binary_slice("elixir", -3, 10) "xir" iex> binary_slice("elixir", -10, 10) "elixir" If the `size` is zero, an empty binary is returned: iex> binary_slice("elixir", 1, 0) "" If `start` is greater than or equal to the binary size, an empty binary is returned: iex> binary_slice("elixir", 10, 10) "" ### Kernel.binding/1 (macro) Returns the binding for the given context as a keyword list. In the returned result, keys are variable names and values are the corresponding variable values. If the given `context` is `nil` (by default it is), the binding for the current context is returned. ### Examples - Kernel.binding/1 (macro) iex> x = 1 iex> binding() [x: 1] iex> x = 2 iex> binding() [x: 2] iex> binding(:foo) [] iex> var!(x, :foo) = 1 1 iex> binding(:foo) [x: 1] ### Kernel.bit_size/1 (function) Returns an integer which is the size in bits of `bitstring`. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.bit_size/1 (function) iex> bit_size(<<433::16, 3::3>>) 19 iex> bit_size(<<1, 2, 3>>) 24 ### Kernel.byte_size/1 (function) Returns the number of bytes needed to contain `bitstring`. That is, if the number of bits in `bitstring` is not divisible by 8, the resulting number of bytes will be rounded up (by excess). This operation happens in constant time. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.byte_size/1 (function) iex> byte_size(<<433::16, 3::3>>) 3 iex> byte_size(<<1, 2, 3>>) 3 ### Kernel.ceil/1 (function) Returns the smallest integer greater than or equal to `number`. If you want to perform ceil operation on other decimal places, use `Float.ceil/2` instead. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.ceil/1 (function) iex> ceil(10) 10 iex> ceil(10.1) 11 iex> ceil(-10.1) -10 ### Kernel.dbg/2 (macro) Debugs the given `code`. `dbg/2` can be used to debug the given `code` through a configurable debug function. It returns the result of the given code. ### Examples - Kernel.dbg/2 (macro) Let's take this call to `dbg/2`: dbg(Atom.to_string(:debugging)) #=> "debugging" It returns the string `"debugging"`, which is the result of the `Atom.to_string/1` call. Additionally, the call above prints: [my_file.ex:10: MyMod.my_fun/0] Atom.to_string(:debugging) #=> "debugging" The default debugging function prints additional debugging info when dealing with pipelines. It prints the values at every "step" of the pipeline. "Elixir is cool!" |> String.trim_trailing("!") |> String.split() |> List.first() |> dbg() #=> "Elixir" The code above prints: [my_file.ex:10: MyMod.my_fun/0] "Elixir is cool!" #=> "Elixir is cool!" |> String.trim_trailing("!") #=> "Elixir is cool" |> String.split() #=> ["Elixir", "is", "cool"] |> List.first() #=> "Elixir" With no arguments, `dbg()` debugs information about the current binding. See `binding/1`. ## `dbg` inside IEx You can enable IEx to replace `dbg` with its `IEx.pry/0` backend by calling: $ iex --dbg pry In such cases, `dbg` will start a `pry` session where you can interact with the imports, aliases, and variables of the current environment at the location of the `dbg` call. If you call `dbg` at the end of a pipeline (using `|>`) within IEx, you are able to go through each step of the pipeline one by one by entering "next" (or "n"). Note `dbg` only supports stepping for pipelines (in other words, it can only step through the code it sees). For general stepping, you can set breakpoints using `IEx.break!/4`. For more information, [see IEx documentation](https://hexdocs.pm/iex/IEx.html#module-dbg-and-breakpoints). ### Configuring the debug function - Kernel.dbg/2 (macro) One of the benefits of `dbg/2` is that its debugging logic is configurable, allowing tools to extend `dbg` with enhanced behaviour. This is done, for example, by `IEx` which extends `dbg` with an interactive shell where you can directly inspect and access values. The debug function can be configured at compile time through the `:dbg_callback` key of the `:elixir` application. The debug function must be a `{module, function, args}` tuple. The `function` function in `module` will be invoked with three arguments *prepended* to `args`: 1. The AST of `code` 2. The AST of `options` 3. The `Macro.Env` environment of where `dbg/2` is invoked The debug function is invoked at compile time and it must also return an AST. The AST is expected to ultimately return the result of evaluating the debugged expression. Here's a simple example: defmodule MyMod do def debug_fun(code, options, caller, device) do quote do result = unquote(code) IO.inspect(unquote(device), result, label: unquote(Macro.to_string(code))) end end end To configure the debug function: # In config/config.exs config :elixir, :dbg_callback, {MyMod, :debug_fun, [:stdio]} ### Default debug function - Kernel.dbg/2 (macro) By default, the debug function we use is `Macro.dbg/3`. It just prints information about the code to standard output and returns the value returned by evaluating `code`. `options` are used to control how terms are inspected. They are the same options accepted by `inspect/2`. ### Kernel.def/2 (macro) Defines a public function with the given name and body. ### Examples - Kernel.def/2 (macro) defmodule Foo do def bar, do: :baz end Foo.bar() #=> :baz A function that expects arguments can be defined as follows: defmodule Foo do def sum(a, b) do a + b end end In the example above, a `sum/2` function is defined; this function receives two arguments and returns their sum. ### Default arguments - Kernel.def/2 (macro) `\\` is used to specify a default value for a parameter of a function. For example: defmodule MyMath do def multiply_by(number, factor \\ 2) do number * factor end end MyMath.multiply_by(4, 3) #=> 12 MyMath.multiply_by(4) #=> 8 The compiler translates this into multiple functions with different arities, here `MyMath.multiply_by/1` and `MyMath.multiply_by/2`, that represent cases when arguments for parameters with default values are passed or not passed. When defining a function with default arguments as well as multiple explicitly declared clauses, you must write a function head that declares the defaults. For example: defmodule MyString do def join(string1, string2 \\ nil, separator \\ " ") def join(string1, nil, _separator) do string1 end def join(string1, string2, separator) do string1 <> separator <> string2 end end Note that `\\` can't be used with anonymous functions because they can only have a sole arity. ### Keyword lists with default arguments - Kernel.def/2 (macro) Functions containing many arguments can benefit from using `Keyword` lists to group and pass attributes as a single value. defmodule MyConfiguration do @default_opts [storage: "local"] def configure(resource, opts \\ []) do opts = Keyword.merge(@default_opts, opts) storage = opts[:storage] # ... end end The difference between using `Map` and `Keyword` to store many arguments is `Keyword`'s keys: * must be atoms * can be given more than once * ordered, as specified by the developer ### Function names - Kernel.def/2 (macro) Function and variable names in Elixir must start with an underscore or a Unicode letter that is not in uppercase or titlecase. They may continue using a sequence of Unicode letters, numbers, and underscores. They may end in `?` or `!`. Elixir's [Naming Conventions](naming-conventions.md) suggest for function and variable names to be written in the `snake_case` format. ## `rescue`/`catch`/`after`/`else` Function bodies support `rescue`, `catch`, `after`, and `else` as `try/1` does (known as "implicit try"). For example, the following two functions are equivalent: def convert(number) do try do String.to_integer(number) rescue e in ArgumentError -> {:error, e.message} end end def convert(number) do String.to_integer(number) rescue e in ArgumentError -> {:error, e.message} end ### Kernel.defdelegate/2 (macro) Defines a function that delegates to another module. Functions defined with `defdelegate/2` are public and can be invoked from outside the module they're defined in, as if they were defined using `def/2`. Therefore, `defdelegate/2` is about extending the current module's public API. If what you want is to invoke a function defined in another module without using its full module name, then use `alias/2` to shorten the module name or use `import/2` to be able to invoke the function without the module name altogether. Delegation only works with functions; delegating macros is not supported. Check `def/2` for rules on naming and default arguments. ### Options - Kernel.defdelegate/2 (macro) * `:to` - the module to dispatch to. * `:as` - the function to call on the target given in `:to`. This parameter is optional and defaults to the name being delegated (`funs`). ### Examples - Kernel.defdelegate/2 (macro) defmodule MyList do defdelegate reverse(list), to: Enum defdelegate other_reverse(list), to: Enum, as: :reverse end MyList.reverse([1, 2, 3]) #=> [3, 2, 1] MyList.other_reverse([1, 2, 3]) #=> [3, 2, 1] ### Kernel.defexception/1 (macro) Defines an exception. Exceptions are structs backed by a module that implements the `Exception` behaviour. The `Exception` behaviour requires two functions to be implemented: * [`exception/1`](`c:Exception.exception/1`) - receives the arguments given to `raise/2` and returns the exception struct. The default implementation accepts either a set of keyword arguments that is merged into the struct or a string to be used as the exception's message. * [`message/1`](`c:Exception.message/1`) - receives the exception struct and must return its message. Most commonly exceptions have a message field which by default is accessed by this function. However, if an exception does not have a message field, this function must be explicitly implemented. Since exceptions are structs, the API supported by `defstruct/1` is also available in `defexception/1`. ### Raising exceptions - Kernel.defexception/1 (macro) The most common way to raise an exception is via `raise/2`: defmodule MyAppError do defexception [:message] end value = [:hello] raise MyAppError, message: "did not get what was expected, got: #{inspect(value)}" In many cases it is more convenient to pass the expected value to `raise/2` and generate the message in the `c:Exception.exception/1` callback: defmodule MyAppError do defexception [:message] @impl true def exception(value) do msg = "did not get what was expected, got: #{inspect(value)}" %MyAppError{message: msg} end end raise MyAppError, value The example above shows the preferred strategy for customizing exception messages. ### Kernel.defguard/1 (macro) Defines a macro suitable for use in guard expressions. It raises at compile time if the `guard` uses expressions that aren't allowed in [guard clauses](patterns-and-guards.html#guards), and otherwise creates a macro that can be used both inside or outside guards. When defining your own guards, consider the [naming conventions](naming-conventions.html#is_-prefix-is_foo) around boolean-returning guards. ### Example - Kernel.defguard/1 (macro) defmodule Integer.Guards do defguard is_even(value) when is_integer(value) and rem(value, 2) == 0 end defmodule Collatz do @moduledoc "Tools for working with the Collatz sequence." import Integer.Guards @doc "Determines the number of steps `n` takes to reach `1`." # If this function never converges, please let me know what `n` you used. def converge(n) when n > 0, do: step(n, 0) defp step(1, step_count) do step_count end defp step(n, step_count) when is_even(n) do step(div(n, 2), step_count + 1) end defp step(n, step_count) do step(3 * n + 1, step_count + 1) end end ### Kernel.defguardp/1 (macro) Defines a private macro suitable for use in guard expressions. It raises at compile time if the `guard` uses expressions that aren't allowed in [guard clauses](patterns-and-guards.html#guards), and otherwise creates a private macro that can be used both inside or outside guards in the current module. When defining your own guards, consider the [naming conventions](naming-conventions.html#is_-prefix-is_foo) around boolean-returning guards. Similar to `defmacrop/2`, `defguardp/1` must be defined before its use in the current module. ### Kernel.defimpl/3 (macro) Defines an implementation for the given protocol. See the `Protocol` module for more information. ### Kernel.defmacro/2 (macro) Defines a public macro with the given name and body. Macros must be defined before its usage. Check `def/2` for rules on naming and default arguments. ### Examples - Kernel.defmacro/2 (macro) defmodule MyLogic do defmacro unless(expr, opts) do quote do if !unquote(expr), unquote(opts) end end end require MyLogic MyLogic.unless false do IO.puts("It works") end ### Kernel.defmacrop/2 (macro) Defines a private macro with the given name and body. Private macros are only accessible from the same module in which they are defined. Private macros must be defined before its usage. Check `defmacro/2` for more information, and check `def/2` for rules on naming and default arguments. ### Kernel.defmodule/2 (macro) Defines a module given by name with the given contents. This macro defines a module with the given `alias` as its name and with the given contents. It returns a tuple with four elements: * `:module` * the module name * the binary contents of the module * the result of evaluating the contents block ### Examples - Kernel.defmodule/2 (macro) defmodule Number do def one, do: 1 def two, do: 2 end #=> {:module, Number, <<70, 79, 82, ...>>, {:two, 0}} Number.one() #=> 1 Number.two() #=> 2 ### Module names and aliases - Kernel.defmodule/2 (macro) Module names (and aliases) must start with an ASCII uppercase character which may be followed by any ASCII letter, number, or underscore. Elixir's [Naming Conventions](naming-conventions.md) suggest for module names and aliases to be written in the `CamelCase` format. You can also use atoms as the module name, although they must only contain ASCII characters. ### Nesting - Kernel.defmodule/2 (macro) Nesting a module inside another module affects the name of the nested module: defmodule Foo do defmodule Bar do end end In the example above, two modules - `Foo` and `Foo.Bar` - are created. When nesting, Elixir automatically creates an alias to the inner module, allowing the second module `Foo.Bar` to be accessed as `Bar` in the same lexical scope where it's defined (the `Foo` module). This only happens if the nested module is defined via an alias. If the `Foo.Bar` module is moved somewhere else, the references to `Bar` in the `Foo` module need to be updated to the fully-qualified name (`Foo.Bar`) or an alias has to be explicitly set in the `Foo` module with the help of `alias/2`. defmodule Foo.Bar do # code end defmodule Foo do alias Foo.Bar # code here can refer to "Foo.Bar" as just "Bar" end ### Dynamic names - Kernel.defmodule/2 (macro) Elixir module names can be dynamically generated. This is very useful when working with macros. For instance, one could write: defmodule Module.concat(["Foo", "Bar"]) do # contents ... end Elixir will accept any module name as long as the expression passed as the first argument to `defmodule/2` evaluates to an atom. Note that, when a dynamic name is used, Elixir won't nest the name under the current module nor automatically set up an alias. ### Reserved module names - Kernel.defmodule/2 (macro) If you attempt to define a module that already exists, you will get a warning saying that a module has been redefined. There are some modules that Elixir does not currently implement but it may be implement in the future. Those modules are reserved and defining them will result in a compilation error: defmodule Any do # code end ** (CompileError) iex:1: module Any is reserved and cannot be defined Elixir reserves the following module names: `Elixir`, `Any`, `BitString`, `PID`, and `Reference`. ### Kernel.defoverridable/1 (macro) Makes the given definitions in the current module overridable. If the user defines a new function or macro with the same name and arity, then the overridable ones are discarded. Otherwise, the original definitions are used. It is possible for the overridden definition to have a different visibility than the original: a public function can be overridden by a private function and vice-versa. Macros cannot be overridden as functions and vice-versa. ### Example - Kernel.defoverridable/1 (macro) defmodule DefaultMod do defmacro __using__(_opts) do quote do def test(x, y) do x + y end defoverridable test: 2 end end end defmodule ChildMod do use DefaultMod def test(x, y) do x * y + super(x, y) end end As seen as in the example above, `super` can be used to call the default implementation. > #### Disclaimer {: .tip} > > Use `defoverridable` with care. If you need to define multiple modules > with the same behaviour, it may be best to move the default implementation > to the caller, and check if a callback exists via `Code.ensure_loaded?/1` and > `function_exported?/3`. > > For example, in the example above, imagine there is a module that calls the > `test/2` function. This module could be defined as such: > > defmodule CallsTest do > def receives_module_and_calls_test(module, x, y) do > if Code.ensure_loaded?(module) and function_exported?(module, :test, 2) do > module.test(x, y) > else > x + y > end > end > end ### Example with behaviour - Kernel.defoverridable/1 (macro) You can also pass a behaviour to `defoverridable` and it will mark all of the callbacks in the behaviour as overridable: defmodule Behaviour do @callback test(number(), number()) :: number() end defmodule DefaultMod do defmacro __using__(_opts) do quote do @behaviour Behaviour def test(x, y) do x + y end defoverridable Behaviour end end end defmodule ChildMod do use DefaultMod def test(x, y) do x * y + super(x, y) end end ### Kernel.defp/2 (macro) Defines a private function with the given name and body. Private functions are only accessible from within the module in which they are defined. Trying to access a private function from outside the module it's defined in results in an `UndefinedFunctionError` exception. Check `def/2` for more information. ### Examples - Kernel.defp/2 (macro) defmodule Foo do def bar do sum(1, 2) end defp sum(a, b), do: a + b end Foo.bar() #=> 3 Foo.sum(1, 2) ** (UndefinedFunctionError) undefined function Foo.sum/2 ### Kernel.defprotocol/2 (macro) Defines a protocol. See the `Protocol` module for more information. ### Kernel.defstruct/1 (macro) Defines a struct. A struct is a tagged map that allows developers to provide default values for keys, tags to be used in polymorphic dispatches and compile time assertions. It is only possible to define a struct per module, as the struct is tied to the module itself. ### Examples - Kernel.defstruct/1 (macro) defmodule User do defstruct name: nil, age: nil end Struct fields are evaluated at compile-time, which allows them to be dynamic. In the example below, `10 + 11` is evaluated at compile-time and the age field is stored with value `21`: defmodule User do defstruct name: nil, age: 10 + 11 end The `fields` argument is usually a keyword list with field names as atom keys and default values as corresponding values. `defstruct/1` also supports a list of atoms as its argument: in that case, the atoms in the list will be used as the struct's field names and they will all default to `nil`. defmodule Post do defstruct [:title, :content, :author] end Add documentation to a struct with the `@doc` attribute, like a function. defmodule Post do @doc "A post. The content should be valid Markdown." defstruct [:title, :content, :author] end Once a struct is defined, it is possible to create them as follows: %Post{title: "Hello world!"} For more information on creating, updating, and pattern matching on structs, please check `%/2`. ### Deriving - Kernel.defstruct/1 (macro) Although structs are maps, by default structs do not implement any of the protocols implemented for maps. For example, attempting to use a protocol with the `User` struct leads to an error: john = %User{name: "John"} MyProtocol.call(john) ** (Protocol.UndefinedError) protocol MyProtocol not implemented for %User{...} `defstruct/1`, however, allows protocol implementations to be *derived*. This can be done by defining a `@derive` attribute as a list before invoking `defstruct/1`: defmodule User do @derive MyProtocol defstruct name: nil, age: nil end MyProtocol.call(john) # it works! A common example is to `@derive` the `Inspect` protocol to hide certain fields when the struct is printed: defmodule User do @derive {Inspect, only: :name} defstruct name: nil, age: nil end For each protocol in `@derive`, Elixir will verify if the protocol has implemented the `c:Protocol.__deriving__/2` callback. If so, the callback will be invoked and it should define the implementation module. Otherwise an implementation that simply points to the `Any` implementation is automatically derived. For more information, see `Protocol.derive/3`. ### Enforcing keys - Kernel.defstruct/1 (macro) When building a struct, Elixir will automatically guarantee all keys belong to the struct: %User{name: "john", unknown: :key} ** (KeyError) key :unknown not found in: %User{age: 21, name: nil} Elixir also allows developers to enforce that certain keys must always be given when building the struct: defmodule User do @enforce_keys [:name] defstruct name: nil, age: 10 + 11 end Now trying to build a struct without the name key will fail: %User{age: 21} ** (ArgumentError) the following keys must also be given when building struct User: [:name] Keep in mind `@enforce_keys` is a simple compile-time guarantee to aid developers when building structs. It is not enforced on updates and it does not provide any sort of value-validation. ### Types - Kernel.defstruct/1 (macro) It is recommended to define types for structs. By convention, such a type is called `t`. To define a struct inside a type, the struct literal syntax is used: defmodule User do defstruct name: "John", age: 25 @type t :: %__MODULE__{name: String.t(), age: non_neg_integer} end It is recommended to only use the struct syntax when defining the struct's type. When referring to another struct, it's better to use `User.t()` instead of `%User{}`. The types of the struct fields that are not included in `%User{}` default to `term()` (see `t:term/0`). Structs whose internal structure is private to the local module (pattern matching them or directly accessing their fields should not be allowed) should use the `@opaque` attribute. Structs whose internal structure is public should use `@type`. ### Kernel.destructure/2 (macro) Destructures two lists, assigning each term in the right one to the matching term in the left one. Unlike pattern matching via `=`, if the sizes of the left and right lists don't match, destructuring simply stops instead of raising an error. ### Examples - Kernel.destructure/2 (macro) iex> destructure([x, y, z], [1, 2, 3, 4, 5]) iex> {x, y, z} {1, 2, 3} In the example above, even though the right list has more entries than the left one, destructuring works fine. If the right list is smaller, the remaining elements are simply set to `nil`: iex> destructure([x, y, z], [1]) iex> {x, y, z} {1, nil, nil} The left-hand side supports any expression you would use on the left-hand side of a match: x = 1 destructure([^x, y, z], [1, 2, 3]) The example above will only work if `x` matches the first value in the right list. Otherwise, it will raise a `MatchError` (like the `=` operator would do). ### Kernel.div/2 (function) Performs an integer division. Raises an `ArithmeticError` exception if one of the arguments is not an integer, or when the `divisor` is `0`. `div/2` performs *truncated* integer division. This means that the result is always rounded towards zero. If you want to perform floored integer division (rounding towards negative infinity), use `Integer.floor_div/2` instead. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.div/2 (function) div(5, 2) #=> 2 div(6, -4) #=> -1 div(-99, 2) #=> -49 div(100, 0) ** (ArithmeticError) bad argument in arithmetic expression ### Kernel.elem/2 (function) Gets the element at the zero-based `index` in `tuple`. It raises `ArgumentError` when index is negative or it is out of range of the tuple elements. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.elem/2 (function) tuple = {:foo, :bar, 3} elem(tuple, 1) #=> :bar elem({}, 0) ** (ArgumentError) argument error elem({:foo, :bar}, 2) ** (ArgumentError) argument error ### Kernel.exit/1 (function) Stops the execution of the calling process with the given reason. Since evaluating this function causes the process to terminate, it has no return value. Inlined by the compiler. ### Examples - Kernel.exit/1 (function) When a process reaches its end, by default it exits with reason `:normal`. You can also call `exit/1` explicitly if you want to terminate a process but not signal any failure: exit(:normal) In case something goes wrong, you can also use `exit/1` with a different reason: exit(:seems_bad) If the exit reason is not `:normal`, all the processes linked to the process that exited will crash (unless they are trapping exits). ### OTP exits - Kernel.exit/1 (function) Exits are used by the OTP to determine if a process exited abnormally or not. The following exits are considered "normal": * `exit(:normal)` * `exit(:shutdown)` * `exit({:shutdown, term})` Exiting with any other reason is considered abnormal and treated as a crash. This means the default supervisor behavior kicks in, error reports are emitted, and so forth. This behavior is relied on in many different places. For example, `ExUnit` uses `exit(:shutdown)` when exiting the test process to signal linked processes, supervision trees and so on to politely shut down too. ### CLI exits - Kernel.exit/1 (function) Building on top of the exit signals mentioned above, if the process started by the command line exits with any of the three reasons above, its exit is considered normal and the Operating System process will exit with status 0. It is, however, possible to customize the operating system exit signal by invoking: exit({:shutdown, integer}) This will cause the operating system process to exit with the status given by `integer` while signaling all linked Erlang processes to politely shut down. Any other exit reason will cause the operating system process to exit with status `1` and linked Erlang processes to crash. ### Kernel.floor/1 (function) Returns the largest integer smaller than or equal to `number`. If you want to perform floor operation on other decimal places, use `Float.floor/2` instead. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.floor/1 (function) iex> floor(10) 10 iex> floor(9.7) 9 iex> floor(-9.7) -10 ### Kernel.function_exported?/3 (function) Returns `true` if `module` is loaded and contains a public `function` with the given `arity`, otherwise `false`. Note that this function does not load the module in case it is not loaded. Check `Code.ensure_loaded/1` for more information. Inlined by the compiler. ### Examples - Kernel.function_exported?/3 (function) iex> function_exported?(Enum, :map, 2) true iex> function_exported?(Enum, :map, 10) false iex> function_exported?(List, :to_string, 1) true ### Kernel.get_and_update_in/2 (macro) Gets a value and updates a nested data structure via the given `path`. This is similar to `get_and_update_in/3`, except the path is extracted via a macro rather than passing a list. For example: get_and_update_in(opts[:foo][:bar], &{&1, &1 + 1}) Is equivalent to: get_and_update_in(opts, [:foo, :bar], &{&1, &1 + 1}) This also works with nested structs and the `struct.path.to.value` way to specify paths: get_and_update_in(struct.foo.bar, &{&1, &1 + 1}) Note that in order for this macro to work, the complete path must always be visible by this macro. See the "Paths" section below. ### Examples - Kernel.get_and_update_in/2 (macro) iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_and_update_in(users["john"].age, &{&1, &1 + 1}) {27, %{"john" => %{age: 28}, "meg" => %{age: 23}}} ### Paths - Kernel.get_and_update_in/2 (macro) A path may start with a variable, local or remote call, and must be followed by one or more: * `foo[bar]` - accesses the key `bar` in `foo`; in case `foo` is nil, `nil` is returned * `foo.bar` - accesses a map/struct field; in case the field is not present, an error is raised Here are some valid paths: users["john"][:age] users["john"].age User.all()["john"].age all_users()["john"].age Here are some invalid ones: # Does a remote call after the initial value users["john"].do_something(arg1, arg2) # Does not access any key or field users ### Kernel.get_and_update_in/3 (function) Gets a value and updates a nested structure. `data` is a nested structure (that is, a map, keyword list, or struct that implements the `Access` behaviour). The `fun` argument receives the value of `key` (or `nil` if `key` is not present) and must return one of the following values: * a two-element tuple `{current_value, new_value}`. In this case, `current_value` is the retrieved value which can possibly be operated on before being returned. `new_value` is the new value to be stored under `key`. * `:pop`, which implies that the current value under `key` should be removed from the structure and returned. This function uses the `Access` module to traverse the structures according to the given `keys`, unless the `key` is a function, which is detailed in a later section. ### Examples - Kernel.get_and_update_in/3 (function) This function is useful when there is a need to retrieve the current value (or something calculated in function of the current value) and update it at the same time. For example, it could be used to read the current age of a user while increasing it by one in one pass: iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_and_update_in(users, ["john", :age], &{&1, &1 + 1}) {27, %{"john" => %{age: 28}, "meg" => %{age: 23}}} Note the current value given to the anonymous function may be `nil`. If any of the intermediate values are nil, it will raise: iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_and_update_in(users, ["jane", :age], &{&1, &1 + 1}) ** (ArgumentError) could not put/update key :age on a nil value ### Functions as keys - Kernel.get_and_update_in/3 (function) If a key is a function, the function will be invoked passing three arguments: * the operation (`:get_and_update`) * the data to be accessed * a function to be invoked next This means `get_and_update_in/3` can be extended to provide custom lookups. The downside is that functions cannot be stored as keys in the accessed data structures. When one of the keys is a function, the function is invoked. In the example below, we use a function to get and increment all ages inside a list: iex> users = [%{name: "john", age: 27}, %{name: "meg", age: 23}] iex> all = fn :get_and_update, data, next -> ...> data |> Enum.map(next) |> Enum.unzip() ...> end iex> get_and_update_in(users, [all, :age], &{&1, &1 + 1}) {[27, 23], [%{name: "john", age: 28}, %{name: "meg", age: 24}]} If the previous value before invoking the function is `nil`, the function *will* receive `nil` as a value and must handle it accordingly (be it by failing or providing a sane default). The `Access` module ships with many convenience accessor functions, like the `all` anonymous function defined above. See `Access.all/0`, `Access.key/2`, and others as examples. ### Kernel.get_in/1 (macro) Gets a key from the nested structure via the given `path`, with nil-safe handling. This is similar to `get_in/2`, except the path is extracted via a macro rather than passing a list. For example: get_in(opts[:foo][:bar]) Is equivalent to: get_in(opts, [:foo, :bar]) Additionally, this macro can traverse structs: get_in(struct.foo.bar) In case any of the keys returns `nil`, then `nil` will be returned and `get_in/1` won't traverse any further. Note that in order for this macro to work, the complete path must always be visible by this macro. For more information about the supported path expressions, please check `get_and_update_in/2` docs. ### Examples - Kernel.get_in/1 (macro) iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_in(users["john"].age) 27 iex> get_in(users["unknown"].age) nil ### Kernel.get_in/2 (function) Gets a value from a nested structure with nil-safe handling. Uses the `Access` module to traverse the structures according to the given `keys`, unless the `key` is a function, which is detailed in a later section. ### Examples - Kernel.get_in/2 (function) iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_in(users, ["john", :age]) 27 iex> # Equivalent to: iex> users["john"][:age] 27 `get_in/2` can also use the accessors in the `Access` module to traverse more complex data structures. For example, here we use `Access.all/0` to traverse a list: iex> users = [%{name: "john", age: 27}, %{name: "meg", age: 23}] iex> get_in(users, [Access.all(), :age]) [27, 23] In case any of the components returns `nil`, `nil` will be returned and `get_in/2` won't traverse any further: iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_in(users, ["unknown", :age]) nil iex> # Equivalent to: iex> users["unknown"][:age] nil ### Functions as keys - Kernel.get_in/2 (function) If a key given to `get_in/2` is a function, the function will be invoked passing three arguments: * the operation (`:get`) * the data to be accessed * a function to be invoked next This means `get_in/2` can be extended to provide custom lookups. That's precisely how the `Access.all/0` key in the previous section behaves. For example, we can manually implement such traversal as follows: iex> users = [%{name: "john", age: 27}, %{name: "meg", age: 23}] iex> all = fn :get, data, next -> Enum.map(data, next) end iex> get_in(users, [all, :age]) [27, 23] The `Access` module ships with many convenience accessor functions. See `Access.all/0`, `Access.key/2`, and others as examples. ### Working with structs - Kernel.get_in/2 (function) By default, structs do not implement the `Access` behaviour required by this function. Therefore, you can't do this: get_in(some_struct, [:some_key, :nested_key]) There are two alternatives. Given structs have predefined keys, we can use the `struct.field` notation: some_struct.some_key.nested_key However, the code above will fail if any of the values return `nil`. If you also want to handle nil values, you can use `get_in/1`: get_in(some_struct.some_key.nested_key) Pattern-matching is another option for handling such cases, which can be especially useful if you want to match on several fields at once or provide custom return values: case some_struct do %{some_key: %{nested_key: value}} -> value %{} -> nil end ### Kernel.hd/1 (function) Returns the head of a list. Raises `ArgumentError` if the list is empty. The head of a list is its first element. It works with improper lists. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.hd/1 (function) hd([1, 2, 3, 4]) #=> 1 hd([1 | 2]) #=> 1 Giving it an empty list raises: hd([]) ** (ArgumentError) argument error ### Kernel.if/2 (macro) Provides an `if/2` macro. This macro expects the first argument to be a condition and the second argument to be a keyword list. Generally speaking, Elixir developers prefer to use pattern matching and guards in function definitions and `case/2`, as they are succinct and precise. However, not all conditions can be expressed through patterns and guards, which makes `if/2` a viable alternative. Similar to `case/2`, any assignment in the condition will be available on both clauses, as well as after the `if` expression. ### One-liner examples - Kernel.if/2 (macro) if(foo, do: bar) In the example above, `bar` will be returned if `foo` evaluates to a truthy value (neither `false` nor `nil`). Otherwise, `nil` will be returned. An `else` option can be given to specify the opposite: if(foo, do: bar, else: baz) ### Blocks examples - Kernel.if/2 (macro) It's also possible to pass a block to the `if/2` macro. The first example above would be translated to: if foo do bar end Note that `do`-`end` become delimiters. The second example would translate to: if foo do bar else baz end If you find yourself nesting conditionals inside conditionals, consider using `cond/1`. ### Kernel.in/2 (macro) Membership operator. Checks if the element on the left-hand side is a member of the collection on the right-hand side. ### Examples - Kernel.in/2 (macro) iex> x = 1 iex> x in [1, 2, 3] true This operator (which is a macro) simply translates to a call to `Enum.member?/2`. The example above would translate to: Enum.member?([1, 2, 3], x) Elixir also supports `left not in right`, which evaluates to `not(left in right)`: iex> x = 1 iex> x not in [1, 2, 3] false ### Guards - Kernel.in/2 (macro) The `in/2` operator (as well as `not in`) can be used in guard clauses as long as the right-hand side is a range or a list. If the right-hand side is a list, Elixir will expand the operator to a valid guard expression which needs to check each value. For example: when x in [1, 2, 3] translates to: when x === 1 or x === 2 or x === 3 However, this construct will be inefficient for large lists. In such cases, it is best to stop using guards and use a more appropriate data structure, such as `MapSet`. If the right-hand side is a range, a more efficient comparison check will be done. For example: when x in 1..1000 translates roughly to: when x >= 1 and x <= 1000 ### AST considerations - Kernel.in/2 (macro) `left not in right` is parsed by the compiler into the AST: {:not, _, [{:in, _, [left, right]}]} This is the same AST as `not(left in right)`. Additionally, `Macro.to_string/2` and `Code.format_string!/2` will translate all occurrences of this AST to `left not in right`. ### Kernel.inspect/2 (function) Inspects the given argument according to the `Inspect` protocol. The second argument is a keyword list with options to control inspection. ### Options - Kernel.inspect/2 (function) `inspect/2` accepts a list of options that are internally translated to an `Inspect.Opts` struct. Check the docs for `Inspect.Opts` to see the supported options. ### Examples - Kernel.inspect/2 (function) iex> inspect(:foo) ":foo" iex> inspect([1, 2, 3, 4, 5], limit: 3) "[1, 2, 3, ...]" iex> inspect([1, 2, 3], pretty: true, width: 0) "[1,\n 2,\n 3]" iex> inspect("olá" <> <<0>>) "<<111, 108, 195, 161, 0>>" iex> inspect("olá" <> <<0>>, binaries: :as_strings) "\"olá\\0\"" iex> inspect("olá", binaries: :as_binaries) "<<111, 108, 195, 161>>" iex> inspect(~c"bar") "~c\"bar\"" iex> inspect([0 | ~c"bar"]) "[0, 98, 97, 114]" iex> inspect(100, base: :octal) "0o144" iex> inspect(100, base: :hex) "0x64" Note that the `Inspect` protocol does not necessarily return a valid representation of an Elixir term. In such cases, the inspected result must start with `#`. For example, inspecting a function will return: inspect(fn a, b -> a + b end) #=> #Function<...> The `Inspect` protocol can be derived to hide certain fields from structs, so they don't show up in logs, inspects and similar. See the "Deriving" section of the documentation of the `Inspect` protocol for more information. ### Kernel.is_atom/1 (function) Returns `true` if `term` is an atom, otherwise returns `false`. Note `true`, `false`, and `nil` are atoms in Elixir, as well as module names. Therefore this function will return `true` to all of those values. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.is_atom/1 (function) iex> is_atom(:name) true iex> is_atom(false) true iex> is_atom(AnAtom) true iex> is_atom("string") false ### Kernel.is_binary/1 (function) Returns `true` if `term` is a binary, otherwise returns `false`. A binary always contains a complete number of bytes. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.is_binary/1 (function) iex> is_binary("foo") true iex> is_binary(<<1::3>>) false ### Kernel.is_bitstring/1 (function) Returns `true` if `term` is a bitstring (including a binary), otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.is_bitstring/1 (function) iex> is_bitstring("foo") true iex> is_bitstring(<<1::3>>) true ### Kernel.is_boolean/1 (function) Returns `true` if `term` is either the atom `true` or the atom `false` (i.e., a boolean), otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.is_boolean/1 (function) iex> is_boolean(false) true iex> is_boolean(true) true iex> is_boolean(:test) false ### Kernel.is_exception/1 (macro) Returns `true` if `term` is an exception, otherwise returns `false`. Allowed in guard tests. ### Examples - Kernel.is_exception/1 (macro) iex> is_exception(%RuntimeError{}) true iex> is_exception(%{}) false ### Kernel.is_exception/2 (macro) Returns `true` if `term` is an exception of `name`, otherwise returns `false`. Allowed in guard tests. ### Examples - Kernel.is_exception/2 (macro) iex> is_exception(%RuntimeError{}, RuntimeError) true iex> is_exception(%RuntimeError{}, Macro.Env) false ### Kernel.is_float/1 (function) Returns `true` if `term` is a floating-point number, otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Kernel.is_function/1 (function) Returns `true` if `term` is a function, otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.is_function/1 (function) iex> is_function(fn x -> x + x end) true iex> is_function("not a function") false ### Kernel.is_function/2 (function) Returns `true` if `term` is a function that can be applied with `arity` number of arguments; otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.is_function/2 (function) iex> is_function(fn x -> x * 2 end, 1) true iex> is_function(fn x -> x * 2 end, 2) false ### Kernel.is_integer/1 (function) Returns `true` if `term` is an integer, otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Kernel.is_list/1 (function) Returns `true` if `term` is a list with zero or more elements, otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Kernel.is_map/1 (function) Returns `true` if `term` is a map, otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. > #### Structs are maps {: .info} > > Structs are also maps, and many of Elixir data structures are implemented > using structs: `Range`s, `Regex`es, `Date`s... > > iex> is_map(1..10) > true > iex> is_map(~D[2024-04-18]) > true > > If you mean to specifically check for non-struct maps, use > `is_non_struct_map/1` instead. > > iex> is_non_struct_map(1..10) > false ### Kernel.is_map_key/2 (function) Returns `true` if `key` is a key in `map`, otherwise returns `false`. It raises `BadMapError` if the first element is not a map. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.is_map_key/2 (function) iex> is_map_key(%{a: "foo", b: "bar"}, :a) true iex> is_map_key(%{a: "foo", b: "bar"}, :c) false ### Kernel.is_nil/1 (macro) Returns `true` if `term` is `nil`, `false` otherwise. Allowed in guard clauses. ### Examples - Kernel.is_nil/1 (macro) iex> is_nil(1 + 2) false iex> is_nil(nil) true ### Kernel.is_non_struct_map/1 (macro) Returns `true` if `term` is a map that is not a struct, otherwise returns `false`. Allowed in guard tests. ### Examples - Kernel.is_non_struct_map/1 (macro) iex> is_non_struct_map(%{}) true iex> is_non_struct_map(URI.parse("/")) false iex> is_non_struct_map(nil) false ### Kernel.is_number/1 (function) Returns `true` if `term` is either an integer or a floating-point number; otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Kernel.is_pid/1 (function) Returns `true` if `term` is a PID (process identifier), otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Kernel.is_port/1 (function) Returns `true` if `term` is a port identifier, otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Kernel.is_reference/1 (function) Returns `true` if `term` is a reference, otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Kernel.is_struct/1 (macro) Returns `true` if `term` is a struct, otherwise returns `false`. Allowed in guard tests. ### Examples - Kernel.is_struct/1 (macro) iex> is_struct(URI.parse("/")) true iex> is_struct(%{}) false ### Kernel.is_struct/2 (macro) Returns `true` if `term` is a struct of `name`, otherwise returns `false`. `is_struct/2` does not check that `name` exists and is a valid struct. If you want such validations, you must pattern match on the struct instead, such as `match?(%URI{}, arg)`. Allowed in guard tests. ### Examples - Kernel.is_struct/2 (macro) iex> is_struct(URI.parse("/"), URI) true iex> is_struct(URI.parse("/"), Macro.Env) false ### Kernel.is_tuple/1 (function) Returns `true` if `term` is a tuple, otherwise returns `false`. Allowed in guard tests. Inlined by the compiler. ### Kernel.length/1 (function) Returns the length of `list`. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.length/1 (function) iex> length([1, 2, 3, 4, 5, 6, 7, 8, 9]) 9 ### Kernel.macro_exported?/3 (function) Returns `true` if `module` is loaded and contains a public `macro` with the given `arity`, otherwise `false`. Note that this function does not load the module in case it is not loaded. Check `Code.ensure_loaded/1` for more information. If `module` is an Erlang module (as opposed to an Elixir module), this function always returns `false`. ### Examples - Kernel.macro_exported?/3 (function) iex> macro_exported?(Kernel, :use, 2) true iex> macro_exported?(:erlang, :abs, 1) false ### Kernel.make_ref/0 (function) Returns an almost unique reference. The returned reference will re-occur after approximately 2^82 calls; therefore it is unique enough for practical purposes. Inlined by the compiler. ### Examples - Kernel.make_ref/0 (function) make_ref() #=> #Reference<0.0.0.135> ### Kernel.map_size/1 (function) Returns the size of a map. The size of a map is the number of key-value pairs that the map contains. This operation happens in constant time. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.map_size/1 (function) iex> map_size(%{a: "foo", b: "bar"}) 2 ### Kernel.match?/2 (macro) A convenience macro that checks if the right side (an expression) matches the left side (a pattern). ### Examples - Kernel.match?/2 (macro) iex> match?(1, 1) true iex> match?({1, _}, {1, 2}) true iex> map = %{a: 1, b: 2} iex> match?(%{a: _}, map) true iex> a = 1 iex> match?(^a, 1) true `match?/2` is very useful when filtering or finding a value in an enumerable: iex> list = [a: 1, b: 2, a: 3] iex> Enum.filter(list, &match?({:a, _}, &1)) [a: 1, a: 3] Guard clauses can also be given to the match: iex> list = [a: 1, b: 2, a: 3] iex> Enum.filter(list, &match?({:a, x} when x < 2, &1)) [a: 1] Variables assigned in the match will not be available outside of the function call (unlike regular pattern matching with the `=` operator): iex> match?(_x, 1) true iex> binding() [] ### Values vs patterns - Kernel.match?/2 (macro) Remember the pin operator matches _values_, not _patterns_. Passing a variable as the pattern will always return `true` and will result in a warning that the variable is unused: # don't do this pattern = %{a: :a} match?(pattern, %{b: :b}) Similarly, moving an expression out the pattern may no longer preserve its semantics. For example: match?([_ | _], [1, 2, 3]) #=> true pattern = [_ | _] match?(pattern, [1, 2, 3]) ** (CompileError) invalid use of _. _ can only be used inside patterns to ignore values and cannot be used in expressions. Make sure you are inside a pattern or change it accordingly Another example is that a map as a pattern performs a subset match, but not once assigned to a variable: match?(%{x: 1}, %{x: 1, y: 2}) #=> true attrs = %{x: 1} match?(^attrs, %{x: 1, y: 2}) #=> false The pin operator will check if the values are equal, using `===/2`, while patterns have their own rules when matching maps, lists, and so forth. Such behavior is not specific to `match?/2`. The following code also throws an exception: attrs = %{x: 1} ^attrs = %{x: 1, y: 2} #=> (MatchError) no match of right hand side value: %{x: 1, y: 2} ### Kernel.max/2 (function) Returns the biggest of the two given terms according to their structural comparison. If the terms compare equal, the first one is returned. This performs a structural comparison where all Elixir terms can be compared with each other. See the ["Structural comparison"](#module-structural-comparison) section for more information. Inlined by the compiler. ### Examples - Kernel.max/2 (function) iex> max(1, 2) 2 iex> max("a", "b") "b" ### Kernel.min/2 (function) Returns the smallest of the two given terms according to their structural comparison. If the terms compare equal, the first one is returned. This performs a structural comparison where all Elixir terms can be compared with each other. See the ["Structural comparison"](#module-structural-comparison) section for more information. Inlined by the compiler. ### Examples - Kernel.min/2 (function) iex> min(1, 2) 1 iex> min("foo", "bar") "bar" ### Kernel.node/0 (function) Returns an atom representing the name of the local node. If the node is not alive, `:nonode@nohost` is returned instead. Allowed in guard tests. Inlined by the compiler. ### Kernel.node/1 (function) Returns the node where the given argument is located. The argument can be a PID, a reference, or a port. If the local node is not alive, `:nonode@nohost` is returned. Allowed in guard tests. Inlined by the compiler. ### Kernel.not/1 (function) Strictly boolean "not" operator. `value` must be a boolean; if it's not, an `ArgumentError` exception is raised. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.not/1 (function) iex> not false true ### Kernel.or/2 (macro) Strictly boolean "or" operator. If `left` is `true`, returns `true`, otherwise returns `right`. Requires only the `left` operand to be a boolean since it short-circuits. If the `left` operand is not a boolean, a `BadBooleanError` exception is raised. Allowed in guard tests. ### Examples - Kernel.or/2 (macro) iex> true or false true iex> false or 42 42 iex> 42 or false ** (BadBooleanError) expected a boolean on left-side of "or", got: 42 ### Kernel.pop_in/1 (macro) Pops a key from the nested structure via the given `path`. This is similar to `pop_in/2`, except the path is extracted via a macro rather than passing a list. For example: pop_in(opts[:foo][:bar]) Is equivalent to: pop_in(opts, [:foo, :bar]) Note that in order for this macro to work, the complete path must always be visible by this macro. For more information about the supported path expressions, please check `get_and_update_in/2` docs. ### Examples - Kernel.pop_in/1 (macro) iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> pop_in(users["john"][:age]) {27, %{"john" => %{}, "meg" => %{age: 23}}} iex> users = %{john: %{age: 27}, meg: %{age: 23}} iex> pop_in(users.john[:age]) {27, %{john: %{}, meg: %{age: 23}}} In case any entry returns `nil`, its key will be removed and the deletion will be considered a success. ### Kernel.pop_in/2 (function) Pops a key from the given nested structure. Uses the `Access` protocol to traverse the structures according to the given `keys`, unless the `key` is a function. If the key is a function, it will be invoked as specified in `get_and_update_in/3`. ### Examples - Kernel.pop_in/2 (function) iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> pop_in(users, ["john", :age]) {27, %{"john" => %{}, "meg" => %{age: 23}}} In case any entry returns `nil`, its key will be removed and the deletion will be considered a success. iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> pop_in(users, ["jane", :age]) {nil, %{"john" => %{age: 27}, "meg" => %{age: 23}}} ### Kernel.put_elem/3 (function) Puts `value` at the given zero-based `index` in `tuple`. Inlined by the compiler. ### Examples - Kernel.put_elem/3 (function) iex> tuple = {:foo, :bar, 3} iex> put_elem(tuple, 0, :baz) {:baz, :bar, 3} ### Kernel.put_in/2 (macro) Puts a value in a nested structure via the given `path`. This is similar to `put_in/3`, except the path is extracted via a macro rather than passing a list. For example: put_in(opts[:foo][:bar], :baz) Is equivalent to: put_in(opts, [:foo, :bar], :baz) This also works with nested structs and the `struct.path.to.value` way to specify paths: put_in(struct.foo.bar, :baz) Note that in order for this macro to work, the complete path must always be visible by this macro. For more information about the supported path expressions, please check `get_and_update_in/2` docs. ### Examples - Kernel.put_in/2 (macro) iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> put_in(users["john"][:age], 28) %{"john" => %{age: 28}, "meg" => %{age: 23}} iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> put_in(users["john"].age, 28) %{"john" => %{age: 28}, "meg" => %{age: 23}} ### Kernel.put_in/3 (function) Puts a value in a nested structure. Uses the `Access` module to traverse the structures according to the given `keys`, unless the `key` is a function. If the key is a function, it will be invoked as specified in `get_and_update_in/3`. ### Examples - Kernel.put_in/3 (function) iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> put_in(users, ["john", :age], 28) %{"john" => %{age: 28}, "meg" => %{age: 23}} If any of the intermediate values are nil, it will raise: iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> put_in(users, ["jane", :age], "oops") ** (ArgumentError) could not put/update key :age on a nil value ### Kernel.raise/1 (macro) Raises an exception. If `message` is a string, it raises a `RuntimeError` exception with it. If `message` is an atom, it just calls `raise/2` with the atom as the first argument and `[]` as the second one. If `message` is an exception struct, it is raised as is. If `message` is anything else, `raise` will fail with an `ArgumentError` exception. ### Examples - Kernel.raise/1 (macro) iex> raise "oops" ** (RuntimeError) oops try do 1 + :foo rescue x in [ArithmeticError] -> IO.puts("that was expected") raise x end ### Kernel.raise/2 (macro) Raises an exception. Calls the `exception/1` function on the given argument (which has to be a module name like `ArgumentError` or `RuntimeError`) passing `attributes` in order to retrieve the exception struct. Any module that contains a call to the `defexception/1` macro automatically implements the `c:Exception.exception/1` callback expected by `raise/2`. For more information, see `defexception/1`. ### Examples - Kernel.raise/2 (macro) iex> raise(ArgumentError, "Sample") ** (ArgumentError) Sample ### Kernel.rem/2 (function) Computes the remainder of an integer division. `rem/2` uses truncated division, which means that the result will always have the sign of the `dividend`. Raises an `ArithmeticError` exception if one of the arguments is not an integer, or when the `divisor` is `0`. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.rem/2 (function) iex> rem(5, 2) 1 iex> rem(6, -4) 2 ### Kernel.reraise/2 (macro) Raises an exception preserving a previous stacktrace. Works like `raise/1` but does not generate a new stacktrace. Note that `__STACKTRACE__` can be used inside catch/rescue to retrieve the current stacktrace. ### Examples - Kernel.reraise/2 (macro) try do raise "oops" rescue exception -> reraise exception, __STACKTRACE__ end ### Kernel.reraise/3 (macro) Raises an exception preserving a previous stacktrace. `reraise/3` works like `reraise/2`, except it passes arguments to the `exception/1` function as explained in `raise/2`. ### Examples - Kernel.reraise/3 (macro) try do raise "oops" rescue exception -> reraise WrapperError, [exception: exception], __STACKTRACE__ end ### Kernel.round/1 (function) Rounds a number to the nearest integer. If the number is equidistant to the two nearest integers, rounds away from zero. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.round/1 (function) iex> round(5.6) 6 iex> round(5.2) 5 iex> round(-9.9) -10 iex> round(-9) -9 iex> round(2.5) 3 iex> round(-2.5) -3 ### Kernel.self/0 (function) Returns the PID (process identifier) of the calling process. Allowed in guard clauses. Inlined by the compiler. ### Kernel.send/2 (function) Sends a message to the given `dest` and returns the message. `dest` may be a remote or local PID, a local port, a locally registered name, or a tuple in the form of `{registered_name, node}` for a registered name at another node. For additional documentation, see the [`!` operator Erlang documentation](https://www.erlang.org/doc/reference_manual/expressions#send). Inlined by the compiler. ### Examples - Kernel.send/2 (function) iex> send(self(), :hello) :hello ### Kernel.sigil_C/2 (macro) Handles the sigil `~C` for charlists. It returns a charlist without interpolations and without escape characters. A charlist is a list of integers where all the integers are valid code points. The three expressions below are equivalent: ~C"foo\n" [?f, ?o, ?o, ?\\, ?n] [102, 111, 111, 92, 110] In practice, charlists are mostly used in specific scenarios such as interfacing with older Erlang libraries that do not accept binaries as arguments. ### Examples - Kernel.sigil_C/2 (macro) iex> ~C(foo) ~c"foo" iex> ~C(f#{o}o) ~c"f\#{o}o" iex> ~C(foo\n) ~c"foo\\n" ### Kernel.sigil_c/2 (macro) Handles the sigil `~c` for charlists. It returns a charlist, unescaping characters and replacing interpolations. A charlist is a list of integers where all the integers are valid code points. The three expressions below are equivalent: ~c"foo" [?f, ?o, ?o] [102, 111, 111] In practice, charlists are mostly used in specific scenarios such as interfacing with older Erlang libraries that do not accept binaries as arguments. ### Examples - Kernel.sigil_c/2 (macro) iex> ~c(foo) ~c"foo" iex> ~c(f#{:o}o) ~c"foo" iex> ~c(f\#{:o}o) ~c"f\#{:o}o" The list is only printed as a `~c` sigil if all code points are within the ASCII range: iex> ~c"hełło" [104, 101, 322, 322, 111] iex> [104, 101, 108, 108, 111] ~c"hello" See `Inspect.Opts` for more information. ### Kernel.sigil_D/2 (macro) Handles the sigil `~D` for dates. By default, this sigil uses the built-in `Calendar.ISO`, which requires dates to be written in the ISO8601 format: ~D[yyyy-mm-dd] such as: ~D[2015-01-13] If you are using alternative calendars, any representation can be used as long as you follow the representation by a single space and the calendar name: ~D[SOME-REPRESENTATION My.Alternative.Calendar] The lower case `~d` variant does not exist as interpolation and escape characters are not useful for date sigils. More information on dates can be found in the `Date` module. ### Examples - Kernel.sigil_D/2 (macro) iex> ~D[2015-01-13] ~D[2015-01-13] ### Kernel.sigil_N/2 (macro) Handles the sigil `~N` for naive date times. By default, this sigil uses the built-in `Calendar.ISO`, which requires naive date times to be written in the ISO8601 format: ~N[yyyy-mm-dd hh:mm:ss] ~N[yyyy-mm-dd hh:mm:ss.ssssss] ~N[yyyy-mm-ddThh:mm:ss.ssssss] such as: ~N[2015-01-13 13:00:07] ~N[2015-01-13T13:00:07.123] If you are using alternative calendars, any representation can be used as long as you follow the representation by a single space and the calendar name: ~N[SOME-REPRESENTATION My.Alternative.Calendar] The lower case `~n` variant does not exist as interpolation and escape characters are not useful for date time sigils. More information on naive date times can be found in the `NaiveDateTime` module. ### Examples - Kernel.sigil_N/2 (macro) iex> ~N[2015-01-13 13:00:07] ~N[2015-01-13 13:00:07] iex> ~N[2015-01-13T13:00:07.001] ~N[2015-01-13 13:00:07.001] ### Kernel.sigil_r/2 (macro) Handles the sigil `~r` for regular expressions. It returns a regular expression pattern, unescaping characters and replacing interpolations. More information on regular expressions can be found in the `Regex` module. ### Examples - Kernel.sigil_r/2 (macro) iex> Regex.match?(~r/foo/, "foo") true iex> Regex.match?(~r/a#{:b}c/, "abc") true While the `~r` sigil allows parens and brackets to be used as delimiters, it is preferred to use `"` or `/` to avoid escaping conflicts with reserved regex characters. ### Kernel.sigil_S/2 (macro) Handles the sigil `~S` for strings. It returns a string without interpolations and without escape characters. ### Examples - Kernel.sigil_S/2 (macro) iex> ~S(foo) "foo" iex> ~S(f#{o}o) "f\#{o}o" iex> ~S(\o/) "\\o/" ### Kernel.sigil_s/2 (macro) Handles the sigil `~s` for strings. It returns a string as if it was a double quoted string, unescaping characters and replacing interpolations. ### Examples - Kernel.sigil_s/2 (macro) iex> ~s(foo) "foo" iex> ~s(f#{:o}o) "foo" iex> ~s(f\#{:o}o) "f\#{:o}o" ### Kernel.sigil_T/2 (macro) Handles the sigil `~T` for times. By default, this sigil uses the built-in `Calendar.ISO`, which requires times to be written in the ISO8601 format: ~T[hh:mm:ss] ~T[hh:mm:ss.ssssss] such as: ~T[13:00:07] ~T[13:00:07.123] If you are using alternative calendars, any representation can be used as long as you follow the representation by a single space and the calendar name: ~T[SOME-REPRESENTATION My.Alternative.Calendar] The lower case `~t` variant does not exist as interpolation and escape characters are not useful for time sigils. More information on times can be found in the `Time` module. ### Examples - Kernel.sigil_T/2 (macro) iex> ~T[13:00:07] ~T[13:00:07] iex> ~T[13:00:07.001] ~T[13:00:07.001] ### Kernel.sigil_U/2 (macro) Handles the sigil `~U` to create a UTC `DateTime`. By default, this sigil uses the built-in `Calendar.ISO`, which requires UTC date times to be written in the ISO8601 format: ~U[yyyy-mm-dd hh:mm:ssZ] ~U[yyyy-mm-dd hh:mm:ss.ssssssZ] ~U[yyyy-mm-ddThh:mm:ss.ssssss+00:00] such as: ~U[2015-01-13 13:00:07Z] ~U[2015-01-13T13:00:07.123+00:00] If you are using alternative calendars, any representation can be used as long as you follow the representation by a single space and the calendar name: ~U[SOME-REPRESENTATION My.Alternative.Calendar] The given `datetime_string` must include "Z" or "00:00" offset which marks it as UTC, otherwise an error is raised. The lower case `~u` variant does not exist as interpolation and escape characters are not useful for date time sigils. More information on date times can be found in the `DateTime` module. ### Examples - Kernel.sigil_U/2 (macro) iex> ~U[2015-01-13 13:00:07Z] ~U[2015-01-13 13:00:07Z] iex> ~U[2015-01-13T13:00:07.001+00:00] ~U[2015-01-13 13:00:07.001Z] ### Kernel.sigil_W/2 (macro) Handles the sigil `~W` for list of words. It returns a list of "words" split by whitespace without interpolations and without escape characters. ### Modifiers - Kernel.sigil_W/2 (macro) * `s`: words in the list are strings (default) * `a`: words in the list are atoms * `c`: words in the list are charlists ### Examples - Kernel.sigil_W/2 (macro) iex> ~W(foo #{bar} baz) ["foo", "\#{bar}", "baz"] ### Kernel.sigil_w/2 (macro) Handles the sigil `~w` for list of words. It returns a list of "words" split by whitespace. Character unescaping and interpolation happens for each word. ### Modifiers - Kernel.sigil_w/2 (macro) * `s`: words in the list are strings (default) * `a`: words in the list are atoms * `c`: words in the list are charlists ### Examples - Kernel.sigil_w/2 (macro) iex> ~w(foo #{:bar} baz) ["foo", "bar", "baz"] iex> ~w(foo #{" bar baz "}) ["foo", "bar", "baz"] iex> ~w(--source test/enum_test.exs) ["--source", "test/enum_test.exs"] iex> ~w(foo bar baz)a [:foo, :bar, :baz] iex> ~w(foo bar baz)c [~c"foo", ~c"bar", ~c"baz"] ### Kernel.spawn/1 (function) Spawns the given function and returns its PID. Typically developers do not use the `spawn` functions, instead they use abstractions such as `Task`, `GenServer` and `Agent`, built on top of `spawn`, that spawns processes with more conveniences in terms of introspection and debugging. Check the `Process` module for more process-related functions. The anonymous function receives 0 arguments, and may return any value. Inlined by the compiler. ### Examples - Kernel.spawn/1 (function) current = self() child = spawn(fn -> send(current, {self(), 1 + 2}) end) receive do {^child, 3} -> IO.puts("Received 3 back") end ### Kernel.spawn/3 (function) Spawns the given function `fun` from the given `module` passing it the given `args` and returns its PID. Typically developers do not use the `spawn` functions, instead they use abstractions such as `Task`, `GenServer` and `Agent`, built on top of `spawn`, that spawns processes with more conveniences in terms of introspection and debugging. Check the `Process` module for more process-related functions. Inlined by the compiler. ### Examples - Kernel.spawn/3 (function) spawn(SomeModule, :function, [1, 2, 3]) ### Kernel.spawn_link/1 (function) Spawns the given function, links it to the current process, and returns its PID. Typically developers do not use the `spawn` functions, instead they use abstractions such as `Task`, `GenServer` and `Agent`, built on top of `spawn`, that spawns processes with more conveniences in terms of introspection and debugging. Check the `Process` module for more process-related functions. For more information on linking, check `Process.link/1`. The anonymous function receives 0 arguments, and may return any value. Inlined by the compiler. ### Examples - Kernel.spawn_link/1 (function) current = self() child = spawn_link(fn -> send(current, {self(), 1 + 2}) end) receive do {^child, 3} -> IO.puts("Received 3 back") end ### Kernel.spawn_link/3 (function) Spawns the given function `fun` from the given `module` passing it the given `args`, links it to the current process, and returns its PID. Typically developers do not use the `spawn` functions, instead they use abstractions such as `Task`, `GenServer` and `Agent`, built on top of `spawn`, that spawns processes with more conveniences in terms of introspection and debugging. Check the `Process` module for more process-related functions. For more information on linking, check `Process.link/1`. Inlined by the compiler. ### Examples - Kernel.spawn_link/3 (function) spawn_link(SomeModule, :function, [1, 2, 3]) ### Kernel.spawn_monitor/1 (function) Spawns the given function, monitors it and returns its PID and monitoring reference. Typically developers do not use the `spawn` functions, instead they use abstractions such as `Task`, `GenServer` and `Agent`, built on top of `spawn`, that spawns processes with more conveniences in terms of introspection and debugging. Check the `Process` module for more process-related functions. The anonymous function receives 0 arguments, and may return any value. Inlined by the compiler. ### Examples - Kernel.spawn_monitor/1 (function) current = self() spawn_monitor(fn -> send(current, {self(), 1 + 2}) end) ### Kernel.spawn_monitor/3 (function) Spawns the given module and function passing the given args, monitors it and returns its PID and monitoring reference. Typically developers do not use the `spawn` functions, instead they use abstractions such as `Task`, `GenServer` and `Agent`, built on top of `spawn`, that spawns processes with more conveniences in terms of introspection and debugging. Check the `Process` module for more process-related functions. Inlined by the compiler. ### Examples - Kernel.spawn_monitor/3 (function) spawn_monitor(SomeModule, :function, [1, 2, 3]) ### Kernel.struct/2 (function) Creates and updates a struct. The `struct` argument may be an atom (which defines `defstruct`) or a `struct` itself. The second argument is any `Enumerable` that emits two-element tuples (key-value pairs) during enumeration. Keys in the `Enumerable` that don't exist in the struct are automatically discarded. Note that keys must be atoms, as only atoms are allowed when defining a struct. If there are duplicate keys in the `Enumerable`, the last entry will be taken (same behavior as `Map.new/1`). This function is useful for dynamically creating and updating structs, as well as for converting maps to structs; in the latter case, just inserting the appropriate `:__struct__` field into the map may not be enough and `struct/2` should be used instead. ### Examples - Kernel.struct/2 (function) defmodule User do defstruct name: "john" end struct(User) #=> %User{name: "john"} opts = [name: "meg"] user = struct(User, opts) #=> %User{name: "meg"} struct(user, unknown: "value") #=> %User{name: "meg"} struct(User, %{name: "meg"}) #=> %User{name: "meg"} # String keys are ignored struct(User, %{"name" => "meg"}) #=> %User{name: "john"} ### Kernel.struct!/2 (function) Similar to `struct/2` but checks for key validity. The function `struct!/2` emulates the compile time behavior of structs. This means that: * when building a struct, as in `struct!(SomeStruct, key: :value)`, it is equivalent to `%SomeStruct{key: :value}` and therefore this function will check if every given key-value belongs to the struct. If the struct is enforcing any key via `@enforce_keys`, those will be enforced as well; * when updating a struct, as in `struct!(%SomeStruct{}, key: :value)`, it is equivalent to `%SomeStruct{struct | key: :value}` and therefore this function will check if every given key-value belongs to the struct. ### Kernel.tap/2 (macro) Pipes the first argument, `value`, into the second argument, a function `fun`, and returns `value` itself. Useful for running synchronous side effects in a pipeline, using the `|>/2` operator. ### Examples - Kernel.tap/2 (macro) iex> tap(1, fn x -> x + 1 end) 1 Most commonly, this is used in pipelines, using the `|>/2` operator. For example, let's suppose you want to inspect part of a data structure. You could write: %{a: 1} |> Map.update!(:a, & &1 + 2) |> tap(&IO.inspect(&1.a)) |> Map.update!(:a, & &1 * 2) ### Kernel.then/2 (macro) Pipes the first argument, `value`, into the second argument, a function `fun`, and returns the result of calling `fun`. In other words, it invokes the function `fun` with `value` as argument, and returns its result. This is most commonly used in pipelines, using the `|>/2` operator, allowing you to pipe a value to a function outside of its first argument. ### Examples - Kernel.then/2 (macro) iex> 1 |> then(fn x -> x * 2 end) 2 iex> 1 |> then(fn x -> Enum.drop(["a", "b", "c"], x) end) ["b", "c"] ### Kernel.throw/1 (function) A non-local return from a function. Using `throw/1` is generally discouraged, as it allows a function to escape from its regular execution flow, which can make the code harder to read. Furthermore, all thrown values must be caught by `try/catch`. See `try/1` for more information. Inlined by the compiler. ### Kernel.tl/1 (function) Returns the tail of a list. Raises `ArgumentError` if the list is empty. The tail of a list is the list without its first element. It works with improper lists. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.tl/1 (function) tl([1, 2, 3, :go]) #=> [2, 3, :go] tl([:one]) #=> [] tl([:a, :b | :improper_end]) #=> [:b | :improper_end] tl([:a | %{b: 1}]) #=> %{b: 1} Giving it an empty list raises: tl([]) ** (ArgumentError) argument error ### Kernel.to_charlist/1 (macro) Converts the given term to a charlist according to the `List.Chars` protocol. ### Examples - Kernel.to_charlist/1 (macro) iex> to_charlist(:foo) ~c"foo" ### Kernel.to_string/1 (macro) Converts the argument to a string according to the `String.Chars` protocol. This is the function invoked when there is string interpolation. ### Examples - Kernel.to_string/1 (macro) iex> to_string(:foo) "foo" ### Kernel.to_timeout/1 (function) Constructs a millisecond timeout from the given components, duration, or timeout. This function is useful for constructing timeouts to use in functions that expect `t:timeout/0` values (such as `Process.send_after/4` and many others). ### Argument - Kernel.to_timeout/1 (function) The `duration` argument can be one of a `Duration`, a `t:timeout/0`, or a list of components. Each of these is described below. ### Passing `Duration`s - Kernel.to_timeout/1 (function) `t:Duration.t/0` structs can be converted to timeouts. The given duration must have `year` and `month` fields set to `0`, since those cannot be reliably converted to milliseconds (due to the varying number of days in a month and year). Microseconds in durations are converted to milliseconds (through `System.convert_time_unit/3`). ### Passing components - Kernel.to_timeout/1 (function) The `duration` argument can also be keyword list which can contain the following keys, each appearing at most once with a non-negative integer value: * `:week` - the number of weeks (a week is always 7 days) * `:day` - the number of days (a day is always 24 hours) * `:hour` - the number of hours * `:minute` - the number of minutes * `:second` - the number of seconds * `:millisecond` - the number of milliseconds The timeout is calculated as the sum of the components, each multiplied by the corresponding factor. ### Passing timeouts - Kernel.to_timeout/1 (function) You can also pass timeouts directly to this functions, that is, milliseconds or the atom `:infinity`. In this case, this function just returns the given argument. ### Examples - Kernel.to_timeout/1 (function) With a keyword list: iex> to_timeout(hour: 1, minute: 30) 5400000 With a duration: iex> to_timeout(%Duration{hour: 1, minute: 30}) 5400000 With a timeout: iex> to_timeout(5400000) 5400000 iex> to_timeout(:infinity) :infinity ### Kernel.trunc/1 (function) Returns the integer part of `number`. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.trunc/1 (function) iex> trunc(5.4) 5 iex> trunc(-5.99) -5 iex> trunc(-5) -5 ### Kernel.tuple_size/1 (function) Returns the size of a tuple. This operation happens in constant time. Allowed in guard tests. Inlined by the compiler. ### Examples - Kernel.tuple_size/1 (function) iex> tuple_size({:a, :b, :c}) 3 ### Kernel.unless/2 (macro) Provides an `unless` macro. This macro evaluates and returns the `do` block passed in as the second argument if `condition` evaluates to a falsy value (`false` or `nil`). Otherwise, it returns the value of the `else` block if present or `nil` if not. See also `if/2`. ### Examples - Kernel.unless/2 (macro) iex> unless(Enum.empty?([]), do: "Hello") nil iex> unless(Enum.empty?([1, 2, 3]), do: "Hello") "Hello" iex> unless Enum.sum([2, 2]) == 5 do ...> "Math still works" ...> else ...> "Math is broken" ...> end "Math still works" ### Kernel.update_in/2 (macro) Updates a nested structure via the given `path`. This is similar to `update_in/3`, except the path is extracted via a macro rather than passing a list. For example: update_in(opts[:foo][:bar], &(&1 + 1)) Is equivalent to: update_in(opts, [:foo, :bar], &(&1 + 1)) This also works with nested structs and the `struct.path.to.value` way to specify paths: update_in(struct.foo.bar, &(&1 + 1)) Note that in order for this macro to work, the complete path must always be visible by this macro. For more information about the supported path expressions, please check `get_and_update_in/2` docs. ### Examples - Kernel.update_in/2 (macro) iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> update_in(users["john"][:age], &(&1 + 1)) %{"john" => %{age: 28}, "meg" => %{age: 23}} iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> update_in(users["john"].age, &(&1 + 1)) %{"john" => %{age: 28}, "meg" => %{age: 23}} ### Kernel.update_in/3 (function) Updates a key in a nested structure. Uses the `Access` module to traverse the structures according to the given `keys`, unless the `key` is a function. If the key is a function, it will be invoked as specified in `get_and_update_in/3`. `data` is a nested structure (that is, a map, keyword list, or struct that implements the `Access` behaviour). The `fun` argument receives the value of `key` (or `nil` if `key` is not present) and the result replaces the value in the structure. ### Examples - Kernel.update_in/3 (function) iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> update_in(users, ["john", :age], &(&1 + 1)) %{"john" => %{age: 28}, "meg" => %{age: 23}} Note the current value given to the anonymous function may be `nil`. If any of the intermediate values are nil, it will raise: iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> update_in(users, ["jane", :age], & &1 + 1) ** (ArgumentError) could not put/update key :age on a nil value ### Kernel.use/2 (macro) Uses the given module in the current context. When calling: use MyModule, some: :options Elixir will invoke `MyModule.__using__/1` passing the second argument of `use` as its argument. Since `__using__/1` is typically a macro, all the usual macro rules apply, and its return value should be quoted code that is then inserted where `use/2` is called. > #### Code injection {: .warning} > > `use MyModule` works as a **code-injection point** in the caller. > Given the caller of `use MyModule` has little control over how the > code is injected, `use/2` should be used with care. If you can, > avoid use in favor of `import/2` or `alias/2` whenever possible. ### Examples - Kernel.use/2 (macro) For example, to write test cases using the `ExUnit` framework provided with Elixir, a developer should `use` the `ExUnit.Case` module: defmodule AssertionTest do use ExUnit.Case, async: true test "always pass" do assert true end end In this example, Elixir will call the `__using__/1` macro in the `ExUnit.Case` module with the keyword list `[async: true]` as its argument. In other words, `use/2` translates to: defmodule AssertionTest do require ExUnit.Case ExUnit.Case.__using__(async: true) test "always pass" do assert true end end where `ExUnit.Case` defines the `__using__/1` macro: defmodule ExUnit.Case do defmacro __using__(opts) do # do something with opts quote do # return some code to inject in the caller end end end ### Best practices - Kernel.use/2 (macro) `__using__/1` is typically used when there is a need to set some state (via module attributes) or callbacks (like `@before_compile`, see the documentation for `Module` for more information) into the caller. `__using__/1` may also be used to alias, require, or import functionality from different modules: defmodule MyModule do defmacro __using__(_opts) do quote do import MyModule.Foo import MyModule.Bar import MyModule.Baz alias MyModule.Repo end end end However, do not provide `__using__/1` if all it does is to import, alias or require the module itself. For example, avoid this: defmodule MyModule do defmacro __using__(_opts) do quote do import MyModule end end end In such cases, developers should instead import or alias the module directly, so that they can customize those as they wish, without the indirection behind `use/2`. Developers must also avoid defining functions inside `__using__/1`. Given `use MyModule` can generate any code, it may not be easy for developers to understand the impact of `use MyModule`. For this reason, to provide guidance and clarity, we recommend developers to include an admonition block in their `@moduledoc` that explains how `use MyModule` impacts their code. As an example, the `GenServer` documentation outlines: > #### `use GenServer` {: .info} > > When you `use GenServer`, the `GenServer` module will > set `@behaviour GenServer` and define a `child_spec/1` > function, so your module can be used as a child > in a supervision tree. This provides a quick summary of how using a module impacts the user code. Keep in mind to only list changes made to the public API of the module. For example, if `use MyModule` sets an internal attribute called `@_my_module_info` and this attribute is never meant to be public, it must not be listed. For convenience, the markup notation to generate the admonition block above is: ``` > #### `use GenServer` {: .info} > > When you `use GenServer`, the GenServer module will > set `@behaviour GenServer` and define a `child_spec/1` > function, so your module can be used as a child > in a supervision tree. ``` ### Kernel.var!/2 (macro) Marks that the given variable should not be hygienized. This macro expects a variable and it is typically invoked inside `quote/2` to mark that a variable should not be hygienized. See `quote/2` for more information. ### Examples - Kernel.var!/2 (macro) iex> Kernel.var!(example) = 1 1 iex> Kernel.var!(example) 1 ### Kernel.|>/2 (macro) Pipe operator. This operator introduces the expression on the left-hand side as the first argument to the function call on the right-hand side. ### Examples - Kernel.|>/2 (macro) iex> [1, [2], 3] |> List.flatten() [1, 2, 3] The example above is the same as calling `List.flatten([1, [2], 3])`. The `|>/2` operator is mostly useful when there is a desire to execute a series of operations resembling a pipeline: iex> [1, [2], 3] |> List.flatten() |> Enum.map(fn x -> x * 2 end) [2, 4, 6] In the example above, the list `[1, [2], 3]` is passed as the first argument to the `List.flatten/1` function, then the flattened list is passed as the first argument to the `Enum.map/2` function which doubles each element of the list. In other words, the expression above simply translates to: Enum.map(List.flatten([1, [2], 3]), fn x -> x * 2 end) ### Pitfalls - Kernel.|>/2 (macro) There are two common pitfalls when using the pipe operator. The first one is related to operator precedence. For example, the following expression: String.graphemes "Hello" |> Enum.reverse Translates to: String.graphemes("Hello" |> Enum.reverse()) which results in an error as the `Enumerable` protocol is not defined for binaries. Adding explicit parentheses resolves the ambiguity: String.graphemes("Hello") |> Enum.reverse() Or, even better: "Hello" |> String.graphemes() |> Enum.reverse() The second limitation is that Elixir always pipes to a function call. Therefore, to pipe into an anonymous function, you need to invoke it: some_fun = &Regex.replace(~r/l/, &1, "L") "Hello" |> some_fun.() Alternatively, you can use `then/2` for the same effect: some_fun = &Regex.replace(~r/l/, &1, "L") "Hello" |> then(some_fun) `then/2` is most commonly used when you want to pipe to a function but the value is expected outside of the first argument, such as above. By replacing `some_fun` by its value, we get: "Hello" |> then(&Regex.replace(~r/l/, &1, "L")) ### Kernel.||/2 (macro) Boolean "or" operator. Provides a short-circuit operator that evaluates and returns the second expression only if the first one does not evaluate to a truthy value (that is, it is either `nil` or `false`). Returns the first expression otherwise. Not allowed in guard clauses. ### Examples - Kernel.||/2 (macro) iex> Enum.empty?([1]) || Enum.empty?([1]) false iex> List.first([]) || true true iex> Enum.empty?([1]) || 1 1 iex> Enum.empty?([]) || throw(:bad) true Note that, unlike `or/2`, this operator accepts any expression as the first argument, not only booleans. ### Kernel.SpecialForms (module) Special forms are the basic building blocks of Elixir, and therefore cannot be overridden by the developer. The `Kernel.SpecialForms` module consists solely of macros that can be invoked anywhere in Elixir code without the use of the `Kernel.SpecialForms.` prefix. This is possible because they all have been automatically imported, in the same fashion as the functions and macros from the `Kernel` module. These building blocks are defined in this module. Some of these special forms are lexical (such as `alias/2` and `case/2`). The macros `{}/1` and `<<>>/1` are also special forms used to define tuple and binary data structures respectively. This module also documents macros that return information about Elixir's compilation environment, such as (`__ENV__/0`, `__MODULE__/0`, `__DIR__/0`, `__STACKTRACE__/0`, and `__CALLER__/0`). Additionally, it documents two special forms, `__block__/1` and `__aliases__/1`, which are not intended to be called directly by the developer but they appear in quoted contents since they are essential in Elixir's constructs. ### Kernel.SpecialForms.%/2 (macro) Matches on or builds a struct. A struct is a tagged map that allows developers to provide default values for keys, tags to be used in polymorphic dispatches and compile time assertions. Structs are usually defined with the `Kernel.defstruct/1` macro: defmodule User do defstruct name: "john", age: 27 end Now a struct can be created as follows: %User{} Underneath a struct is just a map with a `:__struct__` key pointing to the `User` module: %User{} == %{__struct__: User, name: "john", age: 27} The struct fields can be given when building the struct: %User{age: 31} #=> %{__struct__: User, name: "john", age: 31} Or also on pattern matching to extract values out: %User{age: age} = user The advantage of structs is that they validate that the given keys are part of the defined struct. The example below will fail because there is no key `:full_name` in the `User` struct: %User{full_name: "john doe"} An update operation specific for structs is also available: %User{user | age: 28} Once again, the syntax above will guarantee the given keys are valid at compilation time and it will guarantee at runtime the given argument is a struct, failing with `BadStructError` otherwise. The map update syntax can also be used for updating structs, and it is useful when you want to update any struct, regardless of their name, as long as they have matching fields: %{user | age: 28} ### Pattern matching on struct names - Kernel.SpecialForms.%/2 (macro) Besides allowing pattern matching on struct fields, such as: %User{age: age} = user Structs also allow pattern matching on the struct name: %struct_name{} = user struct_name #=> User You can also assign the struct name to `_` when you want to check if something is a struct but you are not interested in its name: %_{} = user ### Kernel.SpecialForms.%{}/1 (macro) Creates a map. See the `Map` module for more information about maps, their syntax, and ways to access and manipulate them. ### AST representation - Kernel.SpecialForms.%{}/1 (macro) Regardless of whether `=>` or the keyword syntax is used, key-value pairs in maps are always represented internally as a list of two-element tuples for simplicity: iex> quote do ...> %{"a" => :b, c: :d} ...> end {:%{}, [], [{"a", :b}, {:c, :d}]} ### Kernel.SpecialForms.&/1 (macro) Capture operator. Captures or creates an anonymous function. ### Capture - Kernel.SpecialForms.&/1 (macro) The capture operator is most commonly used to capture a function with given name and arity from a module: iex> fun = &Kernel.is_atom/1 iex> fun.(:atom) true iex> fun.("string") false In the example above, we captured `Kernel.is_atom/1` as an anonymous function and then invoked it. The capture operator can also be used to capture local functions, including private ones, and imported functions by omitting the module name: &local_function/1 Note that `&local_function/1` creates a local capture, but `&__MODULE__.local_function/1` or `&imported_function/1` create a remote capture. For more information, refer to the ["Functions" section in the Erlang Reference Manual](https://www.erlang.org/doc/system/eff_guide_functions.html#function-calls). Whether a capture is local or remote has implications when using hot code reloading: local captures dispatch to the version of the module that existed at the time they were created, while remote captures dispatch to the current version of the module. See also `Function.capture/3`. ### Anonymous functions - Kernel.SpecialForms.&/1 (macro) The capture operator can also be used to partially apply functions, where `&1`, `&2` and so on can be used as value placeholders. For example: iex> double = &(&1 * 2) iex> double.(2) 4 In other words, `&(&1 * 2)` is equivalent to `fn x -> x * 2 end`. We can partially apply a remote function with placeholder: iex> take_five = &Enum.take(&1, 5) iex> take_five.(1..10) [1, 2, 3, 4, 5] Another example while using an imported or local function: iex> first_elem = &elem(&1, 0) iex> first_elem.({0, 1}) 0 The `&` operator can be used with more complex expressions: iex> fun = &(&1 + &2 + &3) iex> fun.(1, 2, 3) 6 As well as with lists and tuples: iex> fun = &{&1, &2} iex> fun.(1, 2) {1, 2} iex> fun = &[&1 | &2] iex> fun.(1, [2, 3]) [1, 2, 3] The only restrictions when creating anonymous functions is that at least one placeholder must be present, i.e. it must contain at least `&1`, and that block expressions are not supported: # No placeholder, fails to compile. &(:foo) # Block expression, fails to compile. &(&1; &2) ### Kernel.SpecialForms../2 (macro) Dot operator. Defines a remote call, a call to an anonymous function, or an alias. The dot (`.`) in Elixir can be used for remote calls: iex> String.downcase("FOO") "foo" In this example above, we have used `.` to invoke `downcase` in the `String` module, passing `"FOO"` as argument. The dot may be used to invoke anonymous functions too: iex> (fn n -> n end).(7) 7 in which case there is a function on the left hand side. We can also use the dot for creating aliases: iex> Hello.World Hello.World This time, we have joined two aliases, defining the final alias `Hello.World`. ### Syntax - Kernel.SpecialForms../2 (macro) The right side of `.` may be a word starting with an uppercase letter, which represents an alias, a word starting with lowercase or underscore, any valid language operator or any name wrapped in single- or double-quotes. Those are all valid examples: iex> Kernel.Sample Kernel.Sample iex> Kernel.length([1, 2, 3]) 3 iex> Kernel.+(1, 2) 3 iex> Kernel."+"(1, 2) 3 Wrapping the function name in single- or double-quotes is always a remote call. Therefore `Kernel."Foo"` will attempt to call the function "Foo" and not return the alias `Kernel.Foo`. This is done by design as module names are more strict than function names. When the dot is used to invoke an anonymous function there is only one operand, but it is still written using a postfix notation: iex> negate = fn n -> -n end iex> negate.(7) -7 ### Quoted expression - Kernel.SpecialForms../2 (macro) When `.` is used, the quoted expression may take two distinct forms. When the right side starts with a lowercase letter (or underscore): iex> quote do ...> String.downcase("FOO") ...> end {{:., [], [{:__aliases__, [alias: false], [:String]}, :downcase]}, [], ["FOO"]} Note that we have an inner tuple, containing the atom `:.` representing the dot as first element: {:., [], [{:__aliases__, [alias: false], [:String]}, :downcase]} This tuple follows the general quoted expression structure in Elixir, with the name as first argument, some keyword list as metadata as second, and the list of arguments as third. In this case, the arguments are the alias `String` and the atom `:downcase`. The second argument in a remote call is **always** an atom. In the case of calls to anonymous functions, the inner tuple with the dot special form has only one argument, reflecting the fact that the operator is unary: iex> quote do ...> negate.(0) ...> end {{:., [], [{:negate, [], __MODULE__}]}, [], [0]} When the right side is an alias (i.e. starts with uppercase), we get instead: iex> quote do ...> Hello.World ...> end {:__aliases__, [alias: false], [:Hello, :World]} We go into more details about aliases in the `__aliases__/1` special form documentation. ### Unquoting - Kernel.SpecialForms../2 (macro) We can also use unquote to generate a remote call in a quoted expression: iex> x = :downcase iex> quote do ...> String.unquote(x)("FOO") ...> end {{:., [], [{:__aliases__, [alias: false], [:String]}, :downcase]}, [], ["FOO"]} Similar to `Kernel."FUNCTION_NAME"`, `unquote(x)` will always generate a remote call, independent of the value of `x`. To generate an alias via the quoted expression, one needs to rely on `Module.concat/2`: iex> x = Sample iex> quote do ...> Module.concat(String, unquote(x)) ...> end {{:., [], [{:__aliases__, [alias: false], [:Module]}, :concat]}, [], [{:__aliases__, [alias: false], [:String]}, Sample]} ### Kernel.SpecialForms.__aliases__/1 (macro) Internal special form to hold aliases information. It is usually compiled to an atom: iex> quote do ...> Foo.Bar ...> end {:__aliases__, [alias: false], [:Foo, :Bar]} Elixir represents `Foo.Bar` as `__aliases__` so calls can be unambiguously identified by the operator `:.`. For example: iex> quote do ...> Foo.bar() ...> end {{:., [], [{:__aliases__, [alias: false], [:Foo]}, :bar]}, [], []} Whenever an expression iterator sees a `:.` as the tuple key, it can be sure that it represents a call and the second argument in the list is an atom. On the other hand, aliases hold some properties: 1. The head element of aliases can be any term that must expand to an atom at compilation time. 2. The tail elements of aliases are guaranteed to always be atoms. 3. When the head element of aliases is the atom `:Elixir`, no expansion happens. ### Kernel.SpecialForms.__block__/1 (macro) Internal special form for block expressions. This is the special form used whenever we have a block of expressions in Elixir. This special form is private and should not be invoked directly: iex> quote do ...> 1 ...> 2 ...> 3 ...> end {:__block__, [], [1, 2, 3]} ### Kernel.SpecialForms.__CALLER__/0 (macro) Returns the current calling environment as a `Macro.Env` struct. In the environment you can access the filename, line numbers, set up aliases, the function and others. ### Kernel.SpecialForms.__cursor__/1 (macro) Internal special form for cursor position. This is the special form used whenever we need to represent the cursor position in Elixir's AST. See `Code.Fragment` for more information. ### Kernel.SpecialForms.__DIR__/0 (macro) Returns the absolute path of the directory of the current file as a binary. Although the directory can be accessed as `Path.dirname(__ENV__.file)`, this macro is a convenient shortcut. ### Kernel.SpecialForms.__ENV__/0 (macro) Returns the current environment information as a `Macro.Env` struct. In the environment you can access the current filename, line numbers, set up aliases, the current function and others. ### Kernel.SpecialForms.__MODULE__/0 (macro) Returns the current module name as an atom or `nil` otherwise. Although the module can be accessed in the `__ENV__/0`, this macro is a convenient shortcut. ### Kernel.SpecialForms.__STACKTRACE__/0 (macro) Returns the stacktrace for the currently handled exception. It is available only in the `catch` and `rescue` clauses of `try/1` expressions. To retrieve the stacktrace of the current process, use `Process.info(self(), :current_stacktrace)` instead. ### Kernel.SpecialForms.::/2 (macro) Type operator. Used by types and bitstrings to specify types. This operator is used in two distinct occasions in Elixir. It is used in typespecs to specify the type of a variable, function or of a type itself: @type number :: integer | float @spec add(number, number) :: number It may also be used in bit strings to specify the type of a given bit segment: < > = bits Read the documentation on the [Typespecs page](typespecs.md) and `<<>>/1` for more information on typespecs and bitstrings respectively. ### Kernel.SpecialForms.<<>>/1 (macro) Defines a new bitstring. ### Examples - Kernel.SpecialForms.<<>>/1 (macro) iex> <<1, 2, 3>> <<1, 2, 3>> ### Types - Kernel.SpecialForms.<<>>/1 (macro) A bitstring is made of many segments and each segment has a type. There are 9 types used in bitstrings: - `integer` - `float` - `bits` (alias for `bitstring`) - `bitstring` - `binary` - `bytes` (alias for `binary`) - `utf8` - `utf16` - `utf32` When no type is specified, the default is `integer`: iex> <<1, 2, 3>> <<1, 2, 3>> Elixir also accepts by default the segment to be a literal string which expands to integers: iex> <<0, "foo">> <<0, 102, 111, 111>> You can use one of `utf8` (the default), `utf16`, and `utf32` to control how the string is encoded: iex> <<"foo"::utf16>> <<0, 102, 0, 111, 0, 111>> Which is equivalent to writing: iex> <> <<0, 102, 0, 111, 0, 111>> At runtime, binaries need to be explicitly tagged as `binary`: iex> rest = "oo" iex> <<102, rest::binary>> "foo" Otherwise we get an `ArgumentError` when constructing the binary: rest = "oo" <<102, rest>> ** (ArgumentError) argument error ### Options - Kernel.SpecialForms.<<>>/1 (macro) Many options can be given by using `-` as separator. Order is arbitrary, so the following are all equivalent: <<102::integer-native, rest::binary>> <<102::native-integer, rest::binary>> <<102::unsigned-big-integer, rest::binary>> <<102::unsigned-big-integer-size(8), rest::binary>> <<102::unsigned-big-integer-8, rest::binary>> <<102::8-integer-big-unsigned, rest::binary>> <<102, rest::binary>> ### Unit and Size - Kernel.SpecialForms.<<>>/1 (macro) The length of the match is equal to the `unit` (a number of bits) times the `size` (the number of repeated segments of length `unit`). Type | Default Unit --------- | ------------ `integer` | 1 bit `float` | 1 bit `binary` | 8 bits Sizes for types are a bit more nuanced. The default size for integers is 8. For floats, it is 64. For floats, `size * unit` must result in 16, 32, or 64, corresponding to [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point) binary16, binary32, and binary64, respectively. For binaries, the default is the size of the binary. Only the last binary in a match can use the default size. All others must have their size specified explicitly, even if the match is unambiguous. For example: iex> < > = <<"Frank the Walrus">> "Frank the Walrus" iex> {name, species} {"Frank", "Walrus"} The size can be a variable or any valid guard expression: iex> name_size = 5 iex> < > = <<"Frank the Walrus">> iex> {name, species} {"Frank", "Walrus"} The size can access prior variables defined in the binary itself: iex> < > = <<5, "Frank the Walrus">> iex> {name, species} {"Frank", "Walrus"} However, it cannot access variables defined in the match outside of the binary/bitstring: {name_size, < >} = {5, <<"Frank the Walrus">>} ** (CompileError): undefined variable "name_size" in bitstring segment Failing to specify the size for the non-last causes compilation to fail: < > = <<"Frank the Walrus">> ** (CompileError): a binary field without size is only allowed at the end of a binary pattern #### Shortcut Syntax Size and unit can also be specified using a syntax shortcut when passing integer values: iex> x = 1 iex> < > == < > true iex> < > == < > true This syntax reflects the fact the effective size is given by multiplying the size by the unit. ### Modifiers - Kernel.SpecialForms.<<>>/1 (macro) Some types have associated modifiers to clear up ambiguity in byte representation. Modifier | Relevant Type(s) -------------------- | ---------------- `signed` | `integer` `unsigned` (default) | `integer` `little` | `integer`, `float`, `utf16`, `utf32` `big` (default) | `integer`, `float`, `utf16`, `utf32` `native` | `integer`, `float`, `utf16`, `utf32` ### Sign - Kernel.SpecialForms.<<>>/1 (macro) Integers can be `signed` or `unsigned`, defaulting to `unsigned`. iex> < > = <<-100>> <<156>> iex> int 156 iex> < > = <<-100>> <<156>> iex> int -100 `signed` and `unsigned` are only used for matching binaries (see below) and are only used for integers. iex> <<-100::signed, _rest::binary>> = <<-100, "foo">> <<156, 102, 111, 111>> ### Endianness - Kernel.SpecialForms.<<>>/1 (macro) Elixir has three options for endianness: `big`, `little`, and `native`. The default is `big`: iex> < > = <<0, 1>> <<0, 1>> iex> number 256 iex> < > = <<0, 1>> <<0, 1>> iex> number 1 `native` is determined by the VM at startup and will depend on the host operating system. ### Binary/Bitstring Matching - Kernel.SpecialForms.<<>>/1 (macro) Binary matching is a powerful feature in Elixir that is useful for extracting information from binaries as well as pattern matching. Binary matching can be used by itself to extract information from binaries: iex> <<"Hello, ", place::binary>> = "Hello, World" "Hello, World" iex> place "World" Or as a part of function definitions to pattern match: defmodule ImageType do @png_signature <<137::size(8), 80::size(8), 78::size(8), 71::size(8), 13::size(8), 10::size(8), 26::size(8), 10::size(8)>> @jpg_signature <<255::size(8), 216::size(8)>> def type(<<@png_signature, _rest::binary>>), do: :png def type(<<@jpg_signature, _rest::binary>>), do: :jpg def type(_), do: :unknown end ### Performance & Optimizations - Kernel.SpecialForms.<<>>/1 (macro) The Erlang compiler can provide a number of optimizations on binary creation and matching. To see optimization output, set the `bin_opt_info` compiler option: ERL_COMPILER_OPTIONS=bin_opt_info mix compile To learn more about specific optimizations and performance considerations, check out the ["Constructing and matching binaries" chapter of the Erlang's Efficiency Guide](https://www.erlang.org/doc/efficiency_guide/binaryhandling.html). ### Kernel.SpecialForms.=/2 (macro) Match operator. Matches the value on the right against the pattern on the left. ### Kernel.SpecialForms.alias/2 (macro) `alias/2` is used to set up aliases, often useful with modules' names. ### Examples - Kernel.SpecialForms.alias/2 (macro) `alias/2` can be used to set up an alias for any module: defmodule Math do alias MyKeyword, as: Keyword end In the example above, we have set up `MyKeyword` to be aliased as `Keyword`. So now, any reference to `Keyword` will be automatically replaced by `MyKeyword`. In case one wants to access the original `Keyword`, it can be done by accessing `Elixir`: Keyword.values #=> uses MyKeyword.values Elixir.Keyword.values #=> uses Keyword.values Note that calling `alias` without the `:as` option automatically sets an alias based on the last part of the module. For example: alias Foo.Bar.Baz Is the same as: alias Foo.Bar.Baz, as: Baz We can also alias multiple modules in one line: alias Foo.{Bar, Baz, Biz} Is the same as: alias Foo.Bar alias Foo.Baz alias Foo.Biz ### Lexical scope - Kernel.SpecialForms.alias/2 (macro) `import/2`, `require/2` and `alias/2` are called directives and all have lexical scope. This means you can set up aliases inside specific functions and it won't affect the overall scope. ### Warnings - Kernel.SpecialForms.alias/2 (macro) If you alias a module and you don't use the alias, Elixir is going to issue a warning implying the alias is not being used. In case the alias is generated automatically by a macro, Elixir won't emit any warnings though, since the alias was not explicitly defined. Both warning behaviors could be changed by explicitly setting the `:warn` option to `true` or `false`. ### Kernel.SpecialForms.case/2 (macro) Matches the given expression against the given clauses. `case/2` relies on pattern matching and guards to choose which clause to execute. If your logic cannot be expressed within patterns and guards, consider using `if/2` or `cond/1` instead. ### Examples - Kernel.SpecialForms.case/2 (macro) case File.read(file) do {:ok, contents} when is_binary(contents) -> String.split(contents, "\n") {:error, _reason} -> Logger.warning "could not find #{file}, assuming empty..." [] end In the example above, we match the result of `File.read/1` against each clause "head" and execute the clause "body" corresponding to the first clause that matches. If no clause matches, an error is raised. For this reason, it may be necessary to add a final catch-all clause (like `_`) which will always match. x = 10 case x do 0 -> "This clause won't match" _ -> "This clause would match any value (x = #{x})" end #=> "This clause would match any value (x = 10)" If you find yourself nesting `case` expressions inside `case` expressions, consider using `with/1`. ### Variable handling - Kernel.SpecialForms.case/2 (macro) Note that variables bound in a clause do not leak to the outer context: case data do {:ok, value} -> value :error -> nil end value #=> unbound variable value Variables in the outer context cannot be overridden either: value = 7 case lucky? do false -> value = 13 true -> true end value #=> 7 In the example above, `value` is going to be `7` regardless of the value of `lucky?`. The variable `value` bound in the clause and the variable `value` bound in the outer context are two entirely separate variables. If you want to pattern match against an existing variable, you need to use the `^/1` operator: x = 1 case 10 do ^x -> "Won't match" _ -> "Will match" end #=> "Will match" ### Using guards to match against multiple values - Kernel.SpecialForms.case/2 (macro) While it is not possible to match against multiple patterns in a single clause, it's possible to match against multiple values by using guards: case data do value when value in [:one, :two] -> "#{value} has been matched" :three -> "three has been matched" end ### Kernel.SpecialForms.cond/1 (macro) Evaluates the expression corresponding to the first clause that evaluates to a truthy value. ### Examples - Kernel.SpecialForms.cond/1 (macro) The following example has a single clause that always evaluates to true: cond do hd([1, 2, 3]) -> "1 is considered as true" end #=> "1 is considered as true" If all clauses evaluate to `nil` or `false`, `cond` raises an error. For this reason, it may be necessary to add a final always-truthy condition (anything non-`false` and non-`nil`), which will always match: cond do 1 + 1 == 1 -> "This will never match" 2 * 2 != 4 -> "Nor this" true -> "This will" end #=> "This will" If your `cond` has two clauses, and the last one falls back to `true`, you may consider using `if/2` instead. ### Kernel.SpecialForms.fn/1 (macro) Defines an anonymous function. See `Function` for more information. ### Examples - Kernel.SpecialForms.fn/1 (macro) iex> add = fn a, b -> a + b end iex> add.(1, 2) 3 Anonymous functions can also have multiple clauses. All clauses should expect the same number of arguments: iex> negate = fn ...> true -> false ...> false -> true ...> end iex> negate.(false) true ### Kernel.SpecialForms.for/1 (macro) Comprehensions allow you to quickly build a data structure from an enumerable or a bitstring. Let's start with an example: iex> for n <- [1, 2, 3, 4], do: n * 2 [2, 4, 6, 8] A comprehension accepts many generators and filters. `for` uses the `<-` operator to extract values from the enumerable on its right side and match them against the pattern on the left. We call them generators: # A list generator: iex> for n <- [1, 2, 3, 4], do: n * 2 [2, 4, 6, 8] # A comprehension with two generators iex> for x <- [1, 2], y <- [2, 3], do: x * y [2, 3, 4, 6] Filters can also be given: # A comprehension with a generator and a filter iex> for n <- [1, 2, 3, 4, 5, 6], rem(n, 2) == 0, do: n [2, 4, 6] Filters must evaluate to truthy values (everything but `nil` and `false`). If a filter is falsy, then the current value is discarded. Generators can also be used to filter as it removes any value that doesn't match the pattern on the left side of `<-`: iex> users = [user: "john", admin: "meg", guest: "barbara"] iex> for {type, name} when type != :guest <- users do ...> String.upcase(name) ...> end ["JOHN", "MEG"] Bitstring generators are also supported and are very useful when you need to organize bitstring streams: iex> pixels = <<213, 45, 132, 64, 76, 32, 76, 0, 0, 234, 32, 15>> iex> for < >, do: {r, g, b} [{213, 45, 132}, {64, 76, 32}, {76, 0, 0}, {234, 32, 15}] Variable assignments inside the comprehension, be it in generators, filters or inside the block, are not reflected outside of the comprehension. Variable assignments inside filters must still return a truthy value, otherwise values are discarded. Let's see an example. Imagine you have a keyword list where the key is a programming language and the value is its direct parent. Then let's try to compute the grandparent of each language. You could try this: iex> languages = [elixir: :erlang, erlang: :prolog, prolog: nil] iex> for {language, parent} <- languages, grandparent = languages[parent], do: {language, grandparent} [elixir: :prolog] Given the grandparents of Erlang and Prolog were nil, those values were filtered out. If you don't want this behavior, a simple option is to move the filter inside the do-block: iex> languages = [elixir: :erlang, erlang: :prolog, prolog: nil] iex> for {language, parent} <- languages do ...> grandparent = languages[parent] ...> {language, grandparent} ...> end [elixir: :prolog, erlang: nil, prolog: nil] However, such option is not always available, as you may have further filters. An alternative is to convert the filter into a generator by wrapping the right side of `=` in a list: iex> languages = [elixir: :erlang, erlang: :prolog, prolog: nil] iex> for {language, parent} <- languages, grandparent <- [languages[parent]], do: {language, grandparent} [elixir: :prolog, erlang: nil, prolog: nil] ### The `:into` and `:uniq` options - Kernel.SpecialForms.for/1 (macro) In the examples above, the result returned by the comprehension was always a list. The returned result can be configured by passing an `:into` option, that accepts any structure as long as it implements the `Collectable` protocol. For example, we can use bitstring generators with the `:into` option to easily remove all spaces in a string: iex> for < >, c != ?\s, into: "", do: < > "helloworld" The `IO` module provides streams, that are both `Enumerable` and `Collectable`, here is an upcase echo server using comprehensions: for line <- IO.stream(), into: IO.stream() do String.upcase(line) end Similarly, `uniq: true` can also be given to comprehensions to guarantee the results are only added to the collection if they were not returned before. For example: iex> for x <- [1, 1, 2, 3], uniq: true, do: x * 2 [2, 4, 6] iex> for < >, uniq: true, into: "", do: < > "ABC" ### The `:reduce` option - Kernel.SpecialForms.for/1 (macro) *Available since Elixir v1.8*. While the `:into` option allows us to customize the comprehension behavior to a given data type, such as putting all of the values inside a map or inside a binary, it is not always enough. For example, imagine that you have a binary with letters where you want to count how many times each lowercase letter happens, ignoring all uppercase ones. For instance, for the string `"AbCabCABc"`, we want to return the map `%{"a" => 1, "b" => 2, "c" => 1}`. If we were to use `:into`, we would need a data type that computes the frequency of each element it holds. While there is no such data type in Elixir, you could implement one yourself. A simpler option would be to use comprehensions for the mapping and filtering of letters, and then we invoke `Enum.reduce/3` to build a map, for example: iex> letters = for < >, x in ?a..?z, do: < > iex> Enum.reduce(letters, %{}, fn x, acc -> Map.update(acc, x, 1, & &1 + 1) end) %{"a" => 1, "b" => 2, "c" => 1} While the above is straight-forward, it has the downside of traversing the data at least twice. If you are expecting long strings as inputs, this can be quite expensive. Luckily, comprehensions also support the `:reduce` option, which would allow us to fuse both steps above into a single step: iex> for < >, x in ?a..?z, reduce: %{} do ...> acc -> Map.update(acc, < >, 1, & &1 + 1) ...> end %{"a" => 1, "b" => 2, "c" => 1} When the `:reduce` key is given, its value is used as the initial accumulator and the `do` block must be changed to use `->` clauses, where the left side of `->` receives the accumulated value of the previous iteration and the expression on the right side must return the new accumulator value. Once there are no more elements, the final accumulated value is returned. If there are no elements at all, then the initial accumulator value is returned. ### Kernel.SpecialForms.import/2 (macro) Imports functions and macros from other modules. `import/2` allows one to easily access functions or macros from other modules without using the qualified name. ### Examples - Kernel.SpecialForms.import/2 (macro) If you are using several functions from a given module, you can import those functions and reference them as local functions, for example: iex> import List iex> flatten([1, [2], 3]) [1, 2, 3] ### Selector - Kernel.SpecialForms.import/2 (macro) By default, Elixir imports functions and macros from the given module, except the ones starting with an underscore (which are usually callbacks): import List A developer can filter to import only functions, macros, or sigils (which can be functions or macros) via the `:only` option: import List, only: :functions import List, only: :macros import Kernel, only: :sigils Alternatively, Elixir allows a developer to pass pairs of name/arities to `:only` or `:except` as a fine grained control on what to import (or not): import List, only: [flatten: 1] import String, except: [split: 2] Importing the same module again will erase the previous imports, except when the `except` option is used, which is always exclusive on a previously declared `import/2`. If there is no previous import, then it applies to all functions and macros in the module. For example: import List, only: [flatten: 1, keyfind: 4] import List, except: [flatten: 1] After the two import calls above, only `List.keyfind/4` will be imported. ### Underscore functions - Kernel.SpecialForms.import/2 (macro) By default functions starting with `_` are not imported. If you really want to import a function starting with `_` you must explicitly include it in the `:only` selector. import File.Stream, only: [__build__: 3] ### Lexical scope - Kernel.SpecialForms.import/2 (macro) It is important to note that `import/2` is lexical. This means you can import specific macros inside specific functions: defmodule Math do def some_function do # 1) Disable "if/2" from Kernel import Kernel, except: [if: 2] # 2) Require the new "if/2" macro from MyMacros import MyMacros # 3) Use the new macro if do_something, it_works end end In the example above, we imported macros from `MyMacros`, replacing the original `if/2` implementation by our own within that specific function. All other functions in that module will still be able to use the original one. ### Warnings - Kernel.SpecialForms.import/2 (macro) If you import a module and you don't use any of the imported functions or macros from this module, Elixir is going to issue a warning implying the import is not being used. In case the import is generated automatically by a macro, Elixir won't emit any warnings though, since the import was not explicitly defined. Both warning behaviors could be changed by explicitly setting the `:warn` option to `true` or `false`. ### Ambiguous function/macro names - Kernel.SpecialForms.import/2 (macro) If two modules `A` and `B` are imported and they both contain a `foo` function with an arity of `1`, an error is only emitted if an ambiguous call to `foo/1` is actually made; that is, the errors are emitted lazily, not eagerly. ### Kernel.SpecialForms.quote/2 (macro) Gets the representation of any expression. ### Examples - Kernel.SpecialForms.quote/2 (macro) iex> quote do ...> sum(1, 2, 3) ...> end {:sum, [], [1, 2, 3]} ### Elixir's AST (Abstract Syntax Tree) - Kernel.SpecialForms.quote/2 (macro) Any Elixir code can be represented using Elixir data structures. The building block of Elixir macros is a tuple with three elements, for example: {:sum, [], [1, 2, 3]} The tuple above represents a function call to `sum` passing 1, 2 and 3 as arguments. The tuple elements are: * The first element of the tuple is always an atom or another tuple in the same representation. * The second element of the tuple represents [metadata](`t:Macro.metadata/0`). * The third element of the tuple are the arguments for the function call. The third argument may be an atom, which is usually a variable (or a local call). Besides the tuple described above, Elixir has a few literals that are also part of its AST. Those literals return themselves when quoted. They are: :sum #=> Atoms 1 #=> Integers 2.0 #=> Floats [1, 2] #=> Lists "strings" #=> Strings {key, value} #=> Tuples with two elements Any other value, such as a map or a four-element tuple, must be escaped (`Macro.escape/1`) before being introduced into an AST. ### Options - Kernel.SpecialForms.quote/2 (macro) * `:bind_quoted` - passes a binding to the macro. Whenever a binding is given, `unquote/1` is automatically disabled. * `:context` - sets the resolution context. * `:generated` - marks the given chunk as generated so it does not emit warnings. It is also useful to avoid dialyzer reporting errors when macros generate unused clauses. * `:file` - sets the quoted expressions to have the given file. * `:line` - sets the quoted expressions to have the given line. * `:location` - when set to `:keep`, keeps the current line and file from quote. Read the "Stacktrace information" section below for more information. * `:unquote` - when `false`, disables unquoting. This means any `unquote` call will be kept as is in the AST, instead of replaced by the `unquote` arguments. For example: iex> quote do ...> unquote("hello") ...> end "hello" iex> quote unquote: false do ...> unquote("hello") ...> end {:unquote, [], ["hello"]} ### Quote and macros - Kernel.SpecialForms.quote/2 (macro) `quote/2` is commonly used with macros for code generation. As an exercise, let's define a macro that multiplies a number by itself (squared). In practice, there is no reason to define such a macro (and it would actually be seen as a bad practice), but it is simple enough that it allows us to focus on the important aspects of quotes and macros: defmodule Math do defmacro squared(x) do quote do unquote(x) * unquote(x) end end end We can invoke it as: import Math IO.puts("Got #{squared(5)}") At first, there is nothing in this example that actually reveals it is a macro. But what is happening is that, at compilation time, `squared(5)` becomes `5 * 5`. The argument `5` is duplicated in the produced code, we can see this behavior in practice though because our macro actually has a bug: import Math my_number = fn -> IO.puts("Returning 5") 5 end IO.puts("Got #{squared(my_number.())}") The example above will print: Returning 5 Returning 5 Got 25 Notice how "Returning 5" was printed twice, instead of just once. This is because a macro receives an expression and not a value (which is what we would expect in a regular function). This means that: squared(my_number.()) Actually expands to: my_number.() * my_number.() Which invokes the function twice, explaining why we get the printed value twice! In the majority of the cases, this is actually unexpected behavior, and that's why one of the first things you need to keep in mind when it comes to macros is to **not unquote the same value more than once**. Let's fix our macro: defmodule Math do defmacro squared(x) do quote do x = unquote(x) x * x end end end Now invoking `squared(my_number.())` as before will print the value just once. In fact, this pattern is so common that most of the times you will want to use the `bind_quoted` option with `quote/2`: defmodule Math do defmacro squared(x) do quote bind_quoted: [x: x] do x * x end end end `:bind_quoted` will translate to the same code as the example above. `:bind_quoted` can be used in many cases and is seen as good practice, not only because it helps prevent us from running into common mistakes, but also because it allows us to leverage other tools exposed by macros, such as unquote fragments discussed in some sections below. Before we finish this brief introduction, you will notice that, even though we defined a variable `x` inside our quote: quote do x = unquote(x) x * x end When we call: import Math squared(5) x ** (CompileError) undefined variable "x" We can see that `x` did not leak to the user context. This happens because Elixir macros are hygienic, a topic we will discuss at length in the next sections as well. ### Hygiene in variables - Kernel.SpecialForms.quote/2 (macro) Consider the following example: defmodule Hygiene do defmacro no_interference do quote do a = 1 end end end require Hygiene a = 10 Hygiene.no_interference() a #=> 10 In the example above, `a` returns 10 even if the macro is apparently setting it to 1 because variables defined in the macro do not affect the context the macro is executed in. If you want to set or get a variable in the caller's context, you can do it with the help of the `var!` macro: defmodule NoHygiene do defmacro interference do quote do var!(a) = 1 end end end require NoHygiene a = 10 NoHygiene.interference() a #=> 1 You cannot even access variables defined in the same module unless you explicitly give it a context: defmodule Hygiene do defmacro write do quote do a = 1 end end defmacro read do quote do a end end end require Hygiene Hygiene.write() Hygiene.read() ** (CompileError) undefined variable "a" (context Hygiene) For such, you can explicitly pass the current module scope as argument: defmodule ContextHygiene do defmacro write do quote do var!(a, ContextHygiene) = 1 end end defmacro read do quote do var!(a, ContextHygiene) end end end require ContextHygiene ContextHygiene.write() ContextHygiene.read() #=> 1 The contexts of a variable is identified by the third element of the tuple. The default context is `nil` and `quote` assigns another context to all variables within: quote(do: var) #=> {:var, [], Elixir} In case of variables returned by macros, there may also be a `:counter` key in the metadata, which is used to further refine its contexts and guarantee isolation between macro invocations as seen in the previous example. ### Hygiene in aliases - Kernel.SpecialForms.quote/2 (macro) Aliases inside quote are hygienic by default. Consider the following example: defmodule Hygiene do alias Map, as: M defmacro no_interference do quote do M.new() end end end require Hygiene Hygiene.no_interference() #=> %{} Note that, even though the alias `M` is not available in the context the macro is expanded, the code above works because `M` still expands to `Map`. Similarly, even if we defined an alias with the same name before invoking a macro, it won't affect the macro's result: defmodule Hygiene do alias Map, as: M defmacro no_interference do quote do M.new() end end end require Hygiene alias SomethingElse, as: M Hygiene.no_interference() #=> %{} In some cases, you want to access an alias or a module defined in the caller. For such, you can use the `alias!` macro: defmodule Hygiene do # This will expand to Elixir.Nested.hello() defmacro no_interference do quote do Nested.hello() end end # This will expand to Nested.hello() for # whatever is Nested in the caller defmacro interference do quote do alias!(Nested).hello() end end end defmodule Parent do defmodule Nested do def hello, do: "world" end require Hygiene Hygiene.no_interference() ** (UndefinedFunctionError) ... Hygiene.interference() #=> "world" end ### Hygiene in imports - Kernel.SpecialForms.quote/2 (macro) Similar to aliases, imports in Elixir are hygienic. Consider the following code: defmodule Hygiene do defmacrop get_length do quote do length([1, 2, 3]) end end def return_length do import Kernel, except: [length: 1] get_length end end Hygiene.return_length() #=> 3 Notice how `Hygiene.return_length/0` returns `3` even though the `Kernel.length/1` function is not imported. In fact, even if `return_length/0` imported a function with the same name and arity from another module, it wouldn't affect the function result: def return_length do import String, only: [length: 1] get_length end Calling this new `return_length/0` will still return `3` as result. Elixir is smart enough to delay the resolution to the latest possible moment. So, if you call `length([1, 2, 3])` inside quote, but no `length/1` function is available, it is then expanded in the caller: defmodule Lazy do defmacrop get_length do import Kernel, except: [length: 1] quote do length("hello") end end def return_length do import Kernel, except: [length: 1] import String, only: [length: 1] get_length end end Lazy.return_length() #=> 5 ### Stacktrace information - Kernel.SpecialForms.quote/2 (macro) When defining functions via macros, developers have the option of choosing if runtime errors will be reported from the caller or from inside the quote. Let's see an example: # adder.ex defmodule Adder do @doc "Defines a function that adds two numbers" defmacro defadd do quote location: :keep do def add(a, b), do: a + b end end end # sample.ex defmodule Sample do import Adder defadd end require Sample Sample.add(:one, :two) ** (ArithmeticError) bad argument in arithmetic expression adder.ex:5: Sample.add/2 When using `location: :keep` and invalid arguments are given to `Sample.add/2`, the stacktrace information will point to the file and line inside the quote. Without `location: :keep`, the error is reported to where `defadd` was invoked. `location: :keep` affects only definitions inside the quote. > #### `location: :keep` and unquote {: .warning} > > Do not use `location: :keep` if the function definition > also `unquote`s some of the macro arguments. If you do so, Elixir > will store the file definition of the current location but the > unquoted arguments may contain line information of the macro caller, > leading to erroneous stacktraces. ### Binding and unquote fragments - Kernel.SpecialForms.quote/2 (macro) Elixir quote/unquote mechanisms provide a functionality called unquote fragments. Unquote fragments provide an easy way to generate functions on the fly. Consider this example: kv = [foo: 1, bar: 2] Enum.each(kv, fn {k, v} -> def unquote(k)(), do: unquote(v) end) In the example above, we have generated the functions `foo/0` and `bar/0` dynamically. Now, imagine that we want to convert this functionality into a macro: defmacro defkv(kv) do Enum.map(kv, fn {k, v} -> quote do def unquote(k)(), do: unquote(v) end end) end We can invoke this macro as: defkv [foo: 1, bar: 2] However, we can't invoke it as follows: kv = [foo: 1, bar: 2] defkv kv This is because the macro is expecting its arguments to be a keyword list at **compilation** time. Since in the example above we are passing the representation of the variable `kv`, our code fails. This is actually a common pitfall when developing macros. We are assuming a particular shape in the macro. We can work around it by unquoting the variable inside the quoted expression: defmacro defkv(kv) do quote do Enum.each(unquote(kv), fn {k, v} -> def unquote(k)(), do: unquote(v) end) end end If you try to run our new macro, you will notice it won't even compile, complaining that the variables `k` and `v` do not exist. This is because of the ambiguity: `unquote(k)` can either be an unquote fragment, as previously, or a regular unquote as in `unquote(kv)`. One solution to this problem is to disable unquoting in the macro, however, doing that would make it impossible to inject the `kv` representation into the tree. That's when the `:bind_quoted` option comes to the rescue (again!). By using `:bind_quoted`, we can automatically disable unquoting while still injecting the desired variables into the tree: defmacro defkv(kv) do quote bind_quoted: [kv: kv] do Enum.each(kv, fn {k, v} -> def unquote(k)(), do: unquote(v) end) end end In fact, the `:bind_quoted` option is recommended every time one desires to inject a value into the quote. ### Kernel.SpecialForms.receive/1 (macro) Checks if there is a message matching any of the given clauses in the current process mailbox. If there is no matching message, the current process waits until a matching message arrives or until after a given timeout value. Any new and existing messages that do not match will remain in the mailbox. ### Examples - Kernel.SpecialForms.receive/1 (macro) receive do {:selector, number, name} when is_integer(number) -> name name when is_atom(name) -> name _ -> IO.puts(:stderr, "Unexpected message received") end An optional `after` clause can be given in case no matching message is received during the given timeout period, specified in milliseconds: receive do {:selector, number, name} when is_integer(number) -> name name when is_atom(name) -> name _ -> IO.puts(:stderr, "Unexpected message received") after 5000 -> IO.puts(:stderr, "No message in 5 seconds") end The `after` clause can be specified even if there are no match clauses. The timeout value given to `after` can be any expression evaluating to one of the allowed values: * `:infinity` - the process should wait indefinitely for a matching message, this is the same as not using the after clause * `0` - if there is no matching message in the mailbox, the timeout will occur immediately * positive integer smaller than or equal to `4_294_967_295` (`0xFFFFFFFF` in hexadecimal notation) - it should be possible to represent the timeout value as an unsigned 32-bit integer. ### Variable handling - Kernel.SpecialForms.receive/1 (macro) The `receive/1` special form handles variables exactly as the `case/2` special macro. For more information, check the docs for `case/2`. ### Kernel.SpecialForms.require/2 (macro) Requires a module in order to use its macros. ### Examples - Kernel.SpecialForms.require/2 (macro) Public functions in modules are globally available, but in order to use macros, you need to opt-in by requiring the module they are defined in. Let's suppose you created your own `if/2` implementation in the module `MyMacros`. If you want to invoke it, you need to first explicitly require the `MyMacros`: defmodule Math do require MyMacros MyMacros.if do_something, it_works end An attempt to call a macro that was not loaded will raise an error. ### Alias shortcut - Kernel.SpecialForms.require/2 (macro) `require/2` also accepts `:as` as an option so it automatically sets up an alias. Please check `alias/2` for more information. ### Kernel.SpecialForms.super/1 (macro) Calls the overridden function when overriding it with `Kernel.defoverridable/1`. See `Kernel.defoverridable/1` for more information and documentation. ### Kernel.SpecialForms.try/1 (macro) Evaluates the given expressions and handles any error, exit, or throw that may have happened. ### Examples - Kernel.SpecialForms.try/1 (macro) try do do_something_that_may_fail(some_arg) rescue ArgumentError -> IO.puts("Invalid argument given") catch value -> IO.puts("Caught #{inspect(value)}") else value -> IO.puts("Success! The result was #{inspect(value)}") after IO.puts("This is printed regardless if it failed or succeeded") end The `rescue` clause is used to handle exceptions while the `catch` clause can be used to catch thrown values and exits. The `else` clause can be used to control flow based on the result of the expression. `catch`, `rescue`, and `else` clauses work based on pattern matching (similar to the `case` special form). Calls inside `try/1` are not tail recursive since the VM needs to keep the stacktrace in case an exception happens. To retrieve the stacktrace, access `__STACKTRACE__/0` inside the `rescue` or `catch` clause. ## `rescue` clauses Besides relying on pattern matching, `rescue` clauses provide some conveniences around exceptions that allow one to rescue an exception by its name. All the following formats are valid patterns in `rescue` clauses: # Rescue a single exception without binding the exception # to a variable try do UndefinedModule.undefined_function rescue UndefinedFunctionError -> nil end # Rescue any of the given exception without binding try do UndefinedModule.undefined_function rescue [UndefinedFunctionError, ArgumentError] -> nil end # Rescue and bind the exception to the variable "x" try do UndefinedModule.undefined_function rescue x in [UndefinedFunctionError] -> nil end # Rescue all kinds of exceptions and bind the rescued exception # to the variable "x" try do UndefinedModule.undefined_function rescue x -> nil end ### Erlang errors - Kernel.SpecialForms.try/1 (macro) Erlang errors are transformed into Elixir ones when rescuing: try do :erlang.error(:badarg) rescue ArgumentError -> :ok end #=> :ok The most common Erlang errors will be transformed into their Elixir counterpart. Those which are not will be transformed into the more generic `ErlangError`: try do :erlang.error(:unknown) rescue ErlangError -> :ok end #=> :ok In fact, `ErlangError` can be used to rescue any error that is not a proper Elixir error. For example, it can be used to rescue the earlier `:badarg` error too, prior to transformation: try do :erlang.error(:badarg) rescue ErlangError -> :ok end #=> :ok ## `catch` clauses The `catch` clause can be used to catch thrown values, exits, and errors. ### Catching thrown values - Kernel.SpecialForms.try/1 (macro) `catch` can be used to catch values thrown by `Kernel.throw/1`: try do throw(:some_value) catch thrown_value -> IO.puts("A value was thrown: #{inspect(thrown_value)}") end ### Catching values of any kind - Kernel.SpecialForms.try/1 (macro) The `catch` clause also supports catching exits and errors. To do that, it allows matching on both the *kind* of the caught value as well as the value itself: try do exit(:shutdown) catch :exit, value -> IO.puts("Exited with value #{inspect(value)}") end try do exit(:shutdown) catch kind, value when kind in [:exit, :throw] -> IO.puts("Caught exit or throw with value #{inspect(value)}") end The `catch` clause also supports `:error` alongside `:exit` and `:throw` as in Erlang, although this is commonly avoided in favor of `raise`/`rescue` control mechanisms. One reason for this is that when catching `:error`, the error is not automatically transformed into an Elixir error: try do :erlang.error(:badarg) catch :error, :badarg -> :ok end #=> :ok ## `after` clauses An `after` clause allows you to define cleanup logic that will be invoked both when the block of code passed to `try/1` succeeds and also when an error is raised. Note that the process will exit as usual when receiving an exit signal that causes it to exit abruptly and so the `after` clause is not guaranteed to be executed. Luckily, most resources in Elixir (such as open files, ETS tables, ports, sockets, and so on) are linked to or monitor the owning process and will automatically clean themselves up if that process exits. File.write!("tmp/story.txt", "Hello, World") try do do_something_with("tmp/story.txt") after File.rm("tmp/story.txt") end Although `after` clauses are invoked whether or not there was an error, they do not modify the return value. All of the following examples return `:return_me`: try do :return_me after IO.puts("I will be printed") :not_returned end try do raise "boom" rescue _ -> :return_me after IO.puts("I will be printed") :not_returned end ## `else` clauses `else` clauses allow the result of the body passed to `try/1` to be pattern matched on: x = 2 try do 1 / x rescue ArithmeticError -> :infinity else y when y < 1 and y > -1 -> :small _ -> :large end If an `else` clause is not present and no exceptions are raised, the result of the expression will be returned: x = 1 ^x = try do 1 / x rescue ArithmeticError -> :infinity end However, when an `else` clause is present but the result of the expression does not match any of the patterns then an exception will be raised. This exception will not be caught by a `catch` or `rescue` in the same `try`: x = 1 try do try do 1 / x rescue # The TryClauseError cannot be rescued here: TryClauseError -> :error_a else 0 -> :small end rescue # The TryClauseError is rescued here: TryClauseError -> :error_b end Similarly, an exception inside an `else` clause is not caught or rescued inside the same `try`: try do try do nil catch # The exit(1) call below can not be caught here: :exit, _ -> :exit_a else _ -> exit(1) end catch # The exit is caught here: :exit, _ -> :exit_b end This means the VM no longer needs to keep the stacktrace once inside an `else` clause and so tail recursion is possible when using a `try` with a tail call as the final call inside an `else` clause. The same is true for `rescue` and `catch` clauses. Only the result of the tried expression falls down to the `else` clause. If the `try` ends up in the `rescue` or `catch` clauses, their result will not fall down to `else`: try do throw(:catch_this) catch :throw, :catch_this -> :it_was_caught else # :it_was_caught will not fall down to this "else" clause. other -> {:else, other} end ### Variable handling - Kernel.SpecialForms.try/1 (macro) Since an expression inside `try` may not have been evaluated due to an exception, any variable created inside `try` cannot be accessed externally. For instance: try do x = 1 do_something_that_may_fail(same_arg) :ok catch _, _ -> :failed end x #=> unbound variable "x" In the example above, `x` cannot be accessed since it was defined inside the `try` clause. A common practice to address this issue is to return the variables defined inside `try`: x = try do x = 1 do_something_that_may_fail(same_arg) x catch _, _ -> :failed end ### Kernel.SpecialForms.unquote/1 (macro) Unquotes the given expression inside a quoted expression. This function expects a valid Elixir AST, also known as quoted expression, as argument. If you would like to `unquote` any value, such as a map or a four-element tuple, you should call `Macro.escape/1` before unquoting. ### Examples - Kernel.SpecialForms.unquote/1 (macro) Imagine the situation you have a quoted expression and you want to inject it inside some quote. The first attempt would be: value = quote do 13 end quote do sum(1, value, 3) end Which the argument for the `:sum` function call is not the expected result: {:sum, [], [1, {:value, [], Elixir}, 3]} For this, we use `unquote`: iex> value = ...> quote do ...> 13 ...> end iex> quote do ...> sum(1, unquote(value), 3) ...> end {:sum, [], [1, 13, 3]} If you want to unquote a value that is not a quoted expression, such as a map, you need to call `Macro.escape/1` before: iex> value = %{foo: :bar} iex> quote do ...> process_map(unquote(Macro.escape(value))) ...> end {:process_map, [], [{:%{}, [], [foo: :bar]}]} If you forget to escape it, Elixir will raise an error when compiling the code. ### Kernel.SpecialForms.unquote_splicing/1 (macro) Unquotes the given list expanding its arguments. Similar to `unquote/1`. ### Examples - Kernel.SpecialForms.unquote_splicing/1 (macro) iex> values = [2, 3, 4] iex> quote do ...> sum(1, unquote_splicing(values), 5) ...> end {:sum, [], [1, 2, 3, 4, 5]} ### Kernel.SpecialForms.with/1 (macro) Combine matching clauses. One of the ways to understand `with` is to show which code patterns it improves. Imagine you have a map where the fields `width` and `height` are optional and you want to compute its area, as `{:ok, area}` or return `:error`. We could implement this function as: def area(opts) do case Map.fetch(opts, :width) do {:ok, width} -> case Map.fetch(opts, :height) do {:ok, height} -> {:ok, width * height} :error -> :error end :error -> :error end end when called as `area(%{width: 10, height: 15})`, it should return `{:ok, 150}`. If any of the fields are missing, it returns `:error`. While the code above works, it is quite verbose. Using `with`, we could rewrite it as: def area(opts) do with {:ok, width} <- Map.fetch(opts, :width), {:ok, height} <- Map.fetch(opts, :height) do {:ok, width * height} end end Instead of defining nested `case`s with clauses, we use `with` alongside the `PATTERN <- EXPRESSION` operator to match expressions on its right side against the pattern on the left. Consider `<-` as a sibling to `=`, except that, while `=` raises in case of not matches, `<-` will simply abort the `with` chain and return the non-matched value. Let's give it a try on IEx: iex> opts = %{width: 10, height: 15} iex> with {:ok, width} <- Map.fetch(opts, :width), ...> {:ok, height} <- Map.fetch(opts, :height) do ...> {:ok, width * height} ...> end {:ok, 150} If all clauses match, the `do` block is executed, returning its result. Otherwise the chain is aborted and the non-matched value is returned: iex> opts = %{width: 10} iex> with {:ok, width} <- Map.fetch(opts, :width), ...> {:ok, height} <- Map.fetch(opts, :height) do ...> {:ok, width * height} ...> end :error Guards can be used in patterns as well: iex> users = %{"melany" => "guest", "bob" => :admin} iex> with {:ok, role} when not is_binary(role) <- Map.fetch(users, "bob") do ...> {:ok, to_string(role)} ...> end {:ok, "admin"} As in `for/1`, variables bound inside `with/1` won't be accessible outside of `with/1`. Expressions without `<-` may also be used in clauses. For instance, you can perform regular matches with the `=` operator: iex> width = nil iex> opts = %{width: 10, height: 15} iex> with {:ok, width} <- Map.fetch(opts, :width), ...> double_width = width * 2, ...> {:ok, height} <- Map.fetch(opts, :height) do ...> {:ok, double_width * height} ...> end {:ok, 300} iex> width nil The behavior of any expression in a clause is the same as if it was written outside of `with`. For example, `=` will raise a `MatchError` instead of returning the non-matched value: with :foo = :bar, do: :ok ** (MatchError) no match of right hand side value: :bar As with any other function or macro call in Elixir, explicit parens can also be used around the arguments before the `do`-`end` block: iex> opts = %{width: 10, height: 15} iex> with( ...> {:ok, width} <- Map.fetch(opts, :width), ...> {:ok, height} <- Map.fetch(opts, :height) ...> ) do ...> {:ok, width * height} ...> end {:ok, 150} The choice between parens and no parens is a matter of preference. ### Else clauses - Kernel.SpecialForms.with/1 (macro) An `else` option can be given to modify what is being returned from `with` in the case of a failed match: iex> opts = %{width: 10} iex> with {:ok, width} <- Map.fetch(opts, :width), ...> {:ok, height} <- Map.fetch(opts, :height) do ...> {:ok, width * height} ...> else ...> :error -> ...> {:error, :wrong_data} ...> ...> _other_error -> ...> :unexpected_error ...> end {:error, :wrong_data} The `else` block works like a `case`: it can have multiple clauses, and the first match will be used. Variables bound inside `with` (such as `width` in this example) are not available in the `else` block. If an `else` block is used and there are no matching clauses, a `WithClauseError` exception is raised. ### Beware! - Kernel.SpecialForms.with/1 (macro) Keep in mind that, one of potential drawback of `with` is that all failure clauses are flattened into a single `else` block. For example, take this code that checks if a given path points to an Elixir file and that it exists before creating a backup copy: with ".ex" <- Path.extname(path), true <- File.exists?(path) do backup_path = path <> ".backup" File.cp!(path, backup_path) {:ok, backup_path} else binary when is_binary(binary) -> {:error, :invalid_extension} false -> {:error, :missing_file} end Note how we are having to reconstruct the result types of `Path.extname/1` and `File.exists?/1` to build error messages. In this case, it is better to refactor the code so each `<-` already return the desired format in case of errors, like this: with :ok <- validate_extension(path), :ok <- validate_exists(path) do backup_path = path <> ".backup" File.cp!(path, backup_path) {:ok, backup_path} end defp validate_extension(path) do if Path.extname(path) == ".ex", do: :ok, else: {:error, :invalid_extension} end defp validate_exists(path) do if File.exists?(path), do: :ok, else: {:error, :missing_file} end Note how the code above is better organized and clearer once we make sure each `<-` in `with` returns a normalized format. ### Kernel.SpecialForms.^/1 (macro) Pin operator. Accesses an already bound variable in match clauses. ### Examples - Kernel.SpecialForms.^/1 (macro) Elixir allows variables to be rebound via static single assignment: iex> x = 1 iex> x = x + 1 iex> x 2 However, in some situations, it is useful to match against an existing value, instead of rebinding. This can be done with the `^` special form, colloquially known as the pin operator: iex> x = 1 iex> ^x = List.first([1]) iex> ^x = List.first([2]) ** (MatchError) no match of right hand side value: 2 Note that `^x` always refers to the value of `x` prior to the match. The following example will match: iex> x = 0 iex> {x, ^x} = {1, 0} iex> x 1 ### Kernel.SpecialForms.{}/1 (macro) Creates a tuple. More information about the tuple data type and about functions to manipulate tuples can be found in the `Tuple` module; some functions for working with tuples are also available in `Kernel` (such as `Kernel.elem/2` or `Kernel.tuple_size/1`). ### AST representation - Kernel.SpecialForms.{}/1 (macro) Only two-element tuples are considered literals in Elixir and return themselves when quoted. Therefore, all other tuples are represented in the AST as calls to the `:{}` special form. iex> quote do ...> {1, 2} ...> end {1, 2} iex> quote do ...> {1, 2, 3} ...> end {:{}, [], [1, 2, 3]} ### Atom (module) Atoms are constants whose values are their own name. They are often useful to enumerate over distinct values, such as: iex> :apple :apple iex> :orange :orange iex> :watermelon :watermelon Atoms are equal if their names are equal. iex> :apple == :apple true iex> :apple == :orange false Often they are used to express the state of an operation, by using values such as `:ok` and `:error`. The booleans `true` and `false` are also atoms: iex> true == :true true iex> is_atom(false) true iex> is_boolean(:false) true Elixir allows you to skip the leading `:` for the atoms `false`, `true`, and `nil`. Atoms must be composed of Unicode characters such as letters, numbers, underscore, and `@`. If the keyword has a character that does not belong to the category above, such as spaces, you can wrap it in quotes: iex> :"this is an atom with spaces" :"this is an atom with spaces" ### Atom.to_charlist/1 (function) Converts an atom to a charlist. Inlined by the compiler. ### Examples - Atom.to_charlist/1 (function) iex> Atom.to_charlist(:"An atom") ~c"An atom" ### Atom.to_string/1 (function) Converts an atom to a string. Inlined by the compiler. ### Examples - Atom.to_string/1 (function) iex> Atom.to_string(:foo) "foo" ### Base (module) This module provides data encoding and decoding functions according to [RFC 4648](https://tools.ietf.org/html/rfc4648). This document defines the commonly used base 16, base 32, and base 64 encoding schemes. ### Base 16 alphabet - Base (module) | Value | Encoding | Value | Encoding | Value | Encoding | Value | Encoding | |------:|:---------|------:|:---------|------:|:---------|------:|:---------| | 0 | 0 | 4 | 4 | 8 | 8 | 12 | C | | 1 | 1 | 5 | 5 | 9 | 9 | 13 | D | | 2 | 2 | 6 | 6 | 10 | A | 14 | E | | 3 | 3 | 7 | 7 | 11 | B | 15 | F | ### Base 32 alphabet - Base (module) | Value | Encoding | Value | Encoding | Value | Encoding | Value | Encoding | |------:|:---------|------:|:---------|------:|:---------|------:|:---------| | 0 | A | 9 | J | 18 | S | 27 | 3 | | 1 | B | 10 | K | 19 | T | 28 | 4 | | 2 | C | 11 | L | 20 | U | 29 | 5 | | 3 | D | 12 | M | 21 | V | 30 | 6 | | 4 | E | 13 | N | 22 | W | 31 | 7 | | 5 | F | 14 | O | 23 | X | | | | 6 | G | 15 | P | 24 | Y | (pad) | = | | 7 | H | 16 | Q | 25 | Z | | | | 8 | I | 17 | R | 26 | 2 | | | ### Base 32 (extended hex) alphabet - Base (module) | Value | Encoding | Value | Encoding | Value | Encoding | Value | Encoding | |------:|:---------|------:|:---------|------:|:---------|------:|:---------| | 0 | 0 | 9 | 9 | 18 | I | 27 | R | | 1 | 1 | 10 | A | 19 | J | 28 | S | | 2 | 2 | 11 | B | 20 | K | 29 | T | | 3 | 3 | 12 | C | 21 | L | 30 | U | | 4 | 4 | 13 | D | 22 | M | 31 | V | | 5 | 5 | 14 | E | 23 | N | | | | 6 | 6 | 15 | F | 24 | O | (pad) | = | | 7 | 7 | 16 | G | 25 | P | | | | 8 | 8 | 17 | H | 26 | Q | | | ### Base 64 alphabet - Base (module) | Value | Encoding | Value | Encoding | Value | Encoding | Value | Encoding | |------:|:----------|------:|:---------|------:|:---------|------:|:---------| | 0 | A | 17 | R | 34 | i | 51 | z | | 1 | B | 18 | S | 35 | j | 52 | 0 | | 2 | C | 19 | T | 36 | k | 53 | 1 | | 3 | D | 20 | U | 37 | l | 54 | 2 | | 4 | E | 21 | V | 38 | m | 55 | 3 | | 5 | F | 22 | W | 39 | n | 56 | 4 | | 6 | G | 23 | X | 40 | o | 57 | 5 | | 7 | H | 24 | Y | 41 | p | 58 | 6 | | 8 | I | 25 | Z | 42 | q | 59 | 7 | | 9 | J | 26 | a | 43 | r | 60 | 8 | | 10 | K | 27 | b | 44 | s | 61 | 9 | | 11 | L | 28 | c | 45 | t | 62 | + | | 12 | M | 29 | d | 46 | u | 63 | / | | 13 | N | 30 | e | 47 | v | | | | 14 | O | 31 | f | 48 | w | (pad) | = | | 15 | P | 32 | g | 49 | x | | | | 16 | Q | 33 | h | 50 | y | | | ### Base 64 (URL and filename safe) alphabet - Base (module) | Value | Encoding | Value | Encoding | Value | Encoding | Value | Encoding | |------:|:---------|------:|:---------|------:|:---------|------:|:---------| | 0 | A | 17 | R | 34 | i | 51 | z | | 1 | B | 18 | S | 35 | j | 52 | 0 | | 2 | C | 19 | T | 36 | k | 53 | 1 | | 3 | D | 20 | U | 37 | l | 54 | 2 | | 4 | E | 21 | V | 38 | m | 55 | 3 | | 5 | F | 22 | W | 39 | n | 56 | 4 | | 6 | G | 23 | X | 40 | o | 57 | 5 | | 7 | H | 24 | Y | 41 | p | 58 | 6 | | 8 | I | 25 | Z | 42 | q | 59 | 7 | | 9 | J | 26 | a | 43 | r | 60 | 8 | | 10 | K | 27 | b | 44 | s | 61 | 9 | | 11 | L | 28 | c | 45 | t | 62 | - | | 12 | M | 29 | d | 46 | u | 63 | _ | | 13 | N | 30 | e | 47 | v | | | | 14 | O | 31 | f | 48 | w | (pad) | = | | 15 | P | 32 | g | 49 | x | | | | 16 | Q | 33 | h | 50 | y | | | ### Base.decode16/2 (function) Decodes a base 16 encoded string into a binary string. ### Options - Base.decode16/2 (function) The accepted options are: * `:case` - specifies the character case to accept when decoding The values for `:case` can be: * `:upper` - only allows upper case characters (default) * `:lower` - only allows lower case characters * `:mixed` - allows mixed case characters ### Examples - Base.decode16/2 (function) iex> Base.decode16("666F6F626172") {:ok, "foobar"} iex> Base.decode16("666f6f626172", case: :lower) {:ok, "foobar"} iex> Base.decode16("666f6F626172", case: :mixed) {:ok, "foobar"} ### Base.decode16!/2 (function) Decodes a base 16 encoded string into a binary string. ### Options - Base.decode16!/2 (function) The accepted options are: * `:case` - specifies the character case to accept when decoding The values for `:case` can be: * `:upper` - only allows upper case characters (default) * `:lower` - only allows lower case characters * `:mixed` - allows mixed case characters An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. ### Examples - Base.decode16!/2 (function) iex> Base.decode16!("666F6F626172") "foobar" iex> Base.decode16!("666f6f626172", case: :lower) "foobar" iex> Base.decode16!("666f6F626172", case: :mixed) "foobar" ### Base.decode32/2 (function) Decodes a base 32 encoded string into a binary string. ### Options - Base.decode32/2 (function) The accepted options are: * `:case` - specifies the character case to accept when decoding * `:padding` - specifies whether to require padding The values for `:case` can be: * `:upper` - only allows upper case characters (default) * `:lower` - only allows lower case characters * `:mixed` - allows mixed case characters The values for `:padding` can be: * `true` - requires the input string to be padded to the nearest multiple of 8 (default) * `false` - ignores padding from the input string ### Examples - Base.decode32/2 (function) iex> Base.decode32("MZXW6YTBOI======") {:ok, "foobar"} iex> Base.decode32("mzxw6ytboi======", case: :lower) {:ok, "foobar"} iex> Base.decode32("mzXW6ytBOi======", case: :mixed) {:ok, "foobar"} iex> Base.decode32("MZXW6YTBOI", padding: false) {:ok, "foobar"} ### Base.decode32!/2 (function) Decodes a base 32 encoded string into a binary string. An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. ### Options - Base.decode32!/2 (function) The accepted options are: * `:case` - specifies the character case to accept when decoding * `:padding` - specifies whether to require padding The values for `:case` can be: * `:upper` - only allows upper case characters (default) * `:lower` - only allows lower case characters * `:mixed` - allows mixed case characters The values for `:padding` can be: * `true` - requires the input string to be padded to the nearest multiple of 8 (default) * `false` - ignores padding from the input string ### Examples - Base.decode32!/2 (function) iex> Base.decode32!("MZXW6YTBOI======") "foobar" iex> Base.decode32!("mzxw6ytboi======", case: :lower) "foobar" iex> Base.decode32!("mzXW6ytBOi======", case: :mixed) "foobar" iex> Base.decode32!("MZXW6YTBOI", padding: false) "foobar" ### Base.decode64/2 (function) Decodes a base 64 encoded string into a binary string. Accepts `ignore: :whitespace` option which will ignore all the whitespace characters in the input string. Accepts `padding: false` option which will ignore padding from the input string. ### Examples - Base.decode64/2 (function) iex> Base.decode64("Zm9vYmFy") {:ok, "foobar"} iex> Base.decode64("Zm9vYmFy\n", ignore: :whitespace) {:ok, "foobar"} iex> Base.decode64("Zm9vYg==") {:ok, "foob"} iex> Base.decode64("Zm9vYg", padding: false) {:ok, "foob"} ### Base.decode64!/2 (function) Decodes a base 64 encoded string into a binary string. Accepts `ignore: :whitespace` option which will ignore all the whitespace characters in the input string. Accepts `padding: false` option which will ignore padding from the input string. An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. ### Examples - Base.decode64!/2 (function) iex> Base.decode64!("Zm9vYmFy") "foobar" iex> Base.decode64!("Zm9vYmFy\n", ignore: :whitespace) "foobar" iex> Base.decode64!("Zm9vYg==") "foob" iex> Base.decode64!("Zm9vYg", padding: false) "foob" ### Base.encode16/2 (function) Encodes a binary string into a base 16 encoded string. ### Options - Base.encode16/2 (function) The accepted options are: * `:case` - specifies the character case to use when encoding The values for `:case` can be: * `:upper` - uses upper case characters (default) * `:lower` - uses lower case characters ### Examples - Base.encode16/2 (function) iex> Base.encode16("foobar") "666F6F626172" iex> Base.encode16("foobar", case: :lower) "666f6f626172" ### Base.encode32/2 (function) Encodes a binary string into a base 32 encoded string. ### Options - Base.encode32/2 (function) The accepted options are: * `:case` - specifies the character case to use when encoding * `:padding` - specifies whether to apply padding The values for `:case` can be: * `:upper` - uses upper case characters (default) * `:lower` - uses lower case characters The values for `:padding` can be: * `true` - pad the output string to the nearest multiple of 8 (default) * `false` - omit padding from the output string ### Examples - Base.encode32/2 (function) iex> Base.encode32("foobar") "MZXW6YTBOI======" iex> Base.encode32("foobar", case: :lower) "mzxw6ytboi======" iex> Base.encode32("foobar", padding: false) "MZXW6YTBOI" ### Base.encode64/2 (function) Encodes a binary string into a base 64 encoded string. Accepts `padding: false` option which will omit padding from the output string. ### Examples - Base.encode64/2 (function) iex> Base.encode64("foobar") "Zm9vYmFy" iex> Base.encode64("foob") "Zm9vYg==" iex> Base.encode64("foob", padding: false) "Zm9vYg" ### Base.hex_decode32/2 (function) Decodes a base 32 encoded string with extended hexadecimal alphabet into a binary string. ### Options - Base.hex_decode32/2 (function) The accepted options are: * `:case` - specifies the character case to accept when decoding * `:padding` - specifies whether to require padding The values for `:case` can be: * `:upper` - only allows upper case characters (default) * `:lower` - only allows lower case characters * `:mixed` - allows mixed case characters The values for `:padding` can be: * `true` - requires the input string to be padded to the nearest multiple of 8 (default) * `false` - ignores padding from the input string ### Examples - Base.hex_decode32/2 (function) iex> Base.hex_decode32("CPNMUOJ1E8======") {:ok, "foobar"} iex> Base.hex_decode32("cpnmuoj1e8======", case: :lower) {:ok, "foobar"} iex> Base.hex_decode32("cpnMuOJ1E8======", case: :mixed) {:ok, "foobar"} iex> Base.hex_decode32("CPNMUOJ1E8", padding: false) {:ok, "foobar"} ### Base.hex_decode32!/2 (function) Decodes a base 32 encoded string with extended hexadecimal alphabet into a binary string. An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. ### Options - Base.hex_decode32!/2 (function) The accepted options are: * `:case` - specifies the character case to accept when decoding * `:padding` - specifies whether to require padding The values for `:case` can be: * `:upper` - only allows upper case characters (default) * `:lower` - only allows lower case characters * `:mixed` - allows mixed case characters The values for `:padding` can be: * `true` - requires the input string to be padded to the nearest multiple of 8 (default) * `false` - ignores padding from the input string ### Examples - Base.hex_decode32!/2 (function) iex> Base.hex_decode32!("CPNMUOJ1E8======") "foobar" iex> Base.hex_decode32!("cpnmuoj1e8======", case: :lower) "foobar" iex> Base.hex_decode32!("cpnMuOJ1E8======", case: :mixed) "foobar" iex> Base.hex_decode32!("CPNMUOJ1E8", padding: false) "foobar" ### Base.hex_encode32/2 (function) Encodes a binary string into a base 32 encoded string with an extended hexadecimal alphabet. ### Options - Base.hex_encode32/2 (function) The accepted options are: * `:case` - specifies the character case to use when encoding * `:padding` - specifies whether to apply padding The values for `:case` can be: * `:upper` - uses upper case characters (default) * `:lower` - uses lower case characters The values for `:padding` can be: * `true` - pad the output string to the nearest multiple of 8 (default) * `false` - omit padding from the output string ### Examples - Base.hex_encode32/2 (function) iex> Base.hex_encode32("foobar") "CPNMUOJ1E8======" iex> Base.hex_encode32("foobar", case: :lower) "cpnmuoj1e8======" iex> Base.hex_encode32("foobar", padding: false) "CPNMUOJ1E8" ### Base.url_decode64/2 (function) Decodes a base 64 encoded string with URL and filename safe alphabet into a binary string. Accepts `ignore: :whitespace` option which will ignore all the whitespace characters in the input string. Accepts `padding: false` option which will ignore padding from the input string. ### Examples - Base.url_decode64/2 (function) iex> Base.url_decode64("_3_-_A==") {:ok, <<255, 127, 254, 252>>} iex> Base.url_decode64("_3_-_A==\n", ignore: :whitespace) {:ok, <<255, 127, 254, 252>>} iex> Base.url_decode64("_3_-_A", padding: false) {:ok, <<255, 127, 254, 252>>} ### Base.url_decode64!/2 (function) Decodes a base 64 encoded string with URL and filename safe alphabet into a binary string. Accepts `ignore: :whitespace` option which will ignore all the whitespace characters in the input string. Accepts `padding: false` option which will ignore padding from the input string. An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. ### Examples - Base.url_decode64!/2 (function) iex> Base.url_decode64!("_3_-_A==") <<255, 127, 254, 252>> iex> Base.url_decode64!("_3_-_A==\n", ignore: :whitespace) <<255, 127, 254, 252>> iex> Base.url_decode64!("_3_-_A", padding: false) <<255, 127, 254, 252>> ### Base.url_encode64/2 (function) Encodes a binary string into a base 64 encoded string with URL and filename safe alphabet. Accepts `padding: false` option which will omit padding from the output string. ### Examples - Base.url_encode64/2 (function) iex> Base.url_encode64(<<255, 127, 254, 252>>) "_3_-_A==" iex> Base.url_encode64(<<255, 127, 254, 252>>, padding: false) "_3_-_A" ### Base.decode_case/0 (type) ### Base.encode_case/0 (type) ### Bitwise (module) A set of functions that perform calculations on bits. All bitwise functions work only on integers, otherwise an `ArithmeticError` is raised. The functions `band/2`, `bor/2`, `bsl/2`, and `bsr/2` also have operators, respectively: `&&&/2`, `|||/2`, `<<>>/2`. ### Guards - Bitwise (module) All bitwise functions can be used in guards: iex> odd? = fn ...> int when Bitwise.band(int, 1) == 1 -> true ...> _ -> false ...> end iex> odd?.(1) true All functions in this module are inlined by the compiler. ### Bitwise.&&&/2 (function) Bitwise AND operator. Calculates the bitwise AND of its arguments. Allowed in guard tests. Inlined by the compiler. ### Examples - Bitwise.&&&/2 (function) iex> 9 &&& 3 1 ### Bitwise.<< 1 <<< 2 4 iex> 1 <<< -2 0 iex> -1 <<< 2 -4 iex> -1 <<< -2 -1 ### Bitwise.>>>/2 (function) Arithmetic right bitshift operator. Calculates the result of an arithmetic right bitshift. Allowed in guard tests. Inlined by the compiler. ### Examples - Bitwise.>>>/2 (function) iex> 1 >>> 2 0 iex> 1 >>> -2 4 iex> -1 >>> 2 -1 iex> -1 >>> -2 -4 ### Bitwise.band/2 (function) Calculates the bitwise AND of its arguments. Allowed in guard tests. Inlined by the compiler. ### Examples - Bitwise.band/2 (function) iex> band(9, 3) 1 ### Bitwise.bnot/1 (function) Calculates the bitwise NOT of the argument. Allowed in guard tests. Inlined by the compiler. ### Examples - Bitwise.bnot/1 (function) iex> bnot(2) -3 iex> bnot(2) &&& 3 1 ### Bitwise.bor/2 (function) Calculates the bitwise OR of its arguments. Allowed in guard tests. Inlined by the compiler. ### Examples - Bitwise.bor/2 (function) iex> bor(9, 3) 11 ### Bitwise.bsl/2 (function) Calculates the result of an arithmetic left bitshift. Allowed in guard tests. Inlined by the compiler. ### Examples - Bitwise.bsl/2 (function) iex> bsl(1, 2) 4 iex> bsl(1, -2) 0 iex> bsl(-1, 2) -4 iex> bsl(-1, -2) -1 ### Bitwise.bsr/2 (function) Calculates the result of an arithmetic right bitshift. Allowed in guard tests. Inlined by the compiler. ### Examples - Bitwise.bsr/2 (function) iex> bsr(1, 2) 0 iex> bsr(1, -2) 4 iex> bsr(-1, 2) -1 iex> bsr(-1, -2) -4 ### Bitwise.bxor/2 (function) Calculates the bitwise XOR of its arguments. Allowed in guard tests. Inlined by the compiler. ### Examples - Bitwise.bxor/2 (function) iex> bxor(9, 3) 10 ### Bitwise.|||/2 (function) Bitwise OR operator. Calculates the bitwise OR of its arguments. Allowed in guard tests. Inlined by the compiler. ### Examples - Bitwise.|||/2 (function) iex> 9 ||| 3 11 ### Date (module) A Date struct and functions. The Date struct contains the fields year, month, day and calendar. New dates can be built with the `new/3` function or using the `~D` (see `sigil_D/2`) sigil: iex> ~D[2000-01-01] ~D[2000-01-01] Both `new/3` and sigil return a struct where the date fields can be accessed directly: iex> date = ~D[2000-01-01] iex> date.year 2000 iex> date.month 1 The functions on this module work with the `Date` struct as well as any struct that contains the same fields as the `Date` struct, such as `NaiveDateTime` and `DateTime`. Such functions expect `t:Calendar.date/0` in their typespecs (instead of `t:t/0`). Developers should avoid creating the Date structs directly and instead rely on the functions provided by this module as well as the ones in third-party calendar libraries. ### Comparing dates - Date (module) Comparisons in Elixir using `==/2`, `>/2`, ` Enum.min([~D[2017-03-31], ~D[2017-04-01]], Date) ~D[2017-03-31] ### Using epochs - Date (module) The `add/2`, `diff/2` and `shift/2` functions can be used for computing dates or retrieving the number of days between instants. For example, if there is an interest in computing the number of days from the Unix epoch (1970-01-01): iex> Date.diff(~D[2010-04-17], ~D[1970-01-01]) 14716 iex> Date.add(~D[1970-01-01], 14716) ~D[2010-04-17] iex> Date.shift(~D[1970-01-01], year: 40, month: 3, week: 2, day: 2) ~D[2010-04-17] Those functions are optimized to deal with common epochs, such as the Unix Epoch above or the Gregorian Epoch (0000-01-01). ### Date.add/2 (function) Adds the number of days to the given `date`. The days are counted as Gregorian days. The date is returned in the same calendar as it was given in. To shift a date by a `Duration` and according to its underlying calendar, use `Date.shift/2`. ### Examples - Date.add/2 (function) iex> Date.add(~D[2000-01-03], -2) ~D[2000-01-01] iex> Date.add(~D[2000-01-01], 2) ~D[2000-01-03] iex> Date.add(~N[2000-01-01 09:00:00], 2) ~D[2000-01-03] iex> Date.add(~D[-0010-01-01], -2) ~D[-0011-12-30] ### Date.after?/2 (function) Returns `true` if the first date is strictly later than the second. ### Examples - Date.after?/2 (function) iex> Date.after?(~D[2022-02-02], ~D[2021-01-01]) true iex> Date.after?(~D[2021-01-01], ~D[2021-01-01]) false iex> Date.after?(~D[2021-01-01], ~D[2022-02-02]) false ### Date.before?/2 (function) Returns `true` if the first date is strictly earlier than the second. ### Examples - Date.before?/2 (function) iex> Date.before?(~D[2021-01-01], ~D[2022-02-02]) true iex> Date.before?(~D[2021-01-01], ~D[2021-01-01]) false iex> Date.before?(~D[2022-02-02], ~D[2021-01-01]) false ### Date.beginning_of_month/1 (function) Calculates a date that is the first day of the month for the given `date`. ### Examples - Date.beginning_of_month/1 (function) iex> Date.beginning_of_month(~D[2000-01-31]) ~D[2000-01-01] iex> Date.beginning_of_month(~D[2000-01-01]) ~D[2000-01-01] iex> Date.beginning_of_month(~N[2000-01-31 01:23:45]) ~D[2000-01-01] ### Date.beginning_of_week/2 (function) Calculates a date that is the first day of the week for the given `date`. If the day is already the first day of the week, it returns the day itself. For the built-in ISO calendar, the week starts on Monday. A weekday rather than `:default` can be given as `starting_on`. ### Examples - Date.beginning_of_week/2 (function) iex> Date.beginning_of_week(~D[2020-07-11]) ~D[2020-07-06] iex> Date.beginning_of_week(~D[2020-07-06]) ~D[2020-07-06] iex> Date.beginning_of_week(~D[2020-07-11], :sunday) ~D[2020-07-05] iex> Date.beginning_of_week(~D[2020-07-11], :saturday) ~D[2020-07-11] iex> Date.beginning_of_week(~N[2020-07-11 01:23:45]) ~D[2020-07-06] ### Date.compare/2 (function) Compares two date structs. Returns `:gt` if first date is later than the second and `:lt` for vice versa. If the two dates are equal `:eq` is returned. ### Examples - Date.compare/2 (function) iex> Date.compare(~D[2016-04-16], ~D[2016-04-28]) :lt This function can also be used to compare across more complex calendar types by considering only the date fields: iex> Date.compare(~D[2016-04-16], ~N[2016-04-28 01:23:45]) :lt iex> Date.compare(~D[2016-04-16], ~N[2016-04-16 01:23:45]) :eq iex> Date.compare(~N[2016-04-16 12:34:56], ~N[2016-04-16 01:23:45]) :eq ### Date.convert/2 (function) Converts the given `date` from its calendar to the given `calendar`. Returns `{:ok, date}` if the calendars are compatible, or `{:error, :incompatible_calendars}` if they are not. See also `Calendar.compatible_calendars?/2`. ### Examples - Date.convert/2 (function) Imagine someone implements `Calendar.Holocene`, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year: iex> Date.convert(~D[2000-01-01], Calendar.Holocene) {:ok, %Date{calendar: Calendar.Holocene, year: 12000, month: 1, day: 1}} ### Date.convert!/2 (function) Similar to `Date.convert/2`, but raises an `ArgumentError` if the conversion between the two calendars is not possible. ### Examples - Date.convert!/2 (function) Imagine someone implements `Calendar.Holocene`, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year: iex> Date.convert!(~D[2000-01-01], Calendar.Holocene) %Date{calendar: Calendar.Holocene, year: 12000, month: 1, day: 1} ### Date.day_of_era/1 (function) Calculates the day-of-era and era for a given calendar `date`. Returns a tuple `{day, era}` representing the day within the era and the era number. ### Examples - Date.day_of_era/1 (function) iex> Date.day_of_era(~D[0001-01-01]) {1, 1} iex> Date.day_of_era(~D[0000-12-31]) {1, 0} ### Date.day_of_week/2 (function) Calculates the day of the week of a given `date`. Returns the day of the week as an integer. For the ISO 8601 calendar (the default), it is an integer from 1 to 7, where 1 is Monday and 7 is Sunday. An optional `starting_on` value may be supplied, which configures the weekday the week starts on. The default value for it is `:default`, which translates to `:monday` for the built-in ISO calendar. Any other weekday may be given to. ### Examples - Date.day_of_week/2 (function) iex> Date.day_of_week(~D[2016-10-31]) 1 iex> Date.day_of_week(~D[2016-11-01]) 2 iex> Date.day_of_week(~N[2016-11-01 01:23:45]) 2 iex> Date.day_of_week(~D[-0015-10-30]) 3 iex> Date.day_of_week(~D[2016-10-31], :sunday) 2 iex> Date.day_of_week(~D[2016-11-01], :sunday) 3 iex> Date.day_of_week(~N[2016-11-01 01:23:45], :sunday) 3 iex> Date.day_of_week(~D[-0015-10-30], :sunday) 4 ### Date.day_of_year/1 (function) Calculates the day of the year of a given `date`. Returns the day of the year as an integer. For the ISO 8601 calendar (the default), it is an integer from 1 to 366. ### Examples - Date.day_of_year/1 (function) iex> Date.day_of_year(~D[2016-01-01]) 1 iex> Date.day_of_year(~D[2016-11-01]) 306 iex> Date.day_of_year(~D[-0015-10-30]) 303 iex> Date.day_of_year(~D[2004-12-31]) 366 ### Date.days_in_month/1 (function) Returns the number of days in the given `date` month. ### Examples - Date.days_in_month/1 (function) iex> Date.days_in_month(~D[1900-01-13]) 31 iex> Date.days_in_month(~D[1900-02-09]) 28 iex> Date.days_in_month(~N[2000-02-20 01:23:45]) 29 ### Date.diff/2 (function) Calculates the difference between two dates, in a full number of days. It returns the number of Gregorian days between the dates. Only `Date` structs that follow the same or compatible calendars can be compared this way. If two calendars are not compatible, it will raise. ### Examples - Date.diff/2 (function) iex> Date.diff(~D[2000-01-03], ~D[2000-01-01]) 2 iex> Date.diff(~D[2000-01-01], ~D[2000-01-03]) -2 iex> Date.diff(~D[0000-01-02], ~D[-0001-12-30]) 3 iex> Date.diff(~D[2000-01-01], ~N[2000-01-03 09:00:00]) -2 ### Date.end_of_month/1 (function) Calculates a date that is the last day of the month for the given `date`. ### Examples - Date.end_of_month/1 (function) iex> Date.end_of_month(~D[2000-01-01]) ~D[2000-01-31] iex> Date.end_of_month(~D[2000-01-31]) ~D[2000-01-31] iex> Date.end_of_month(~N[2000-01-01 01:23:45]) ~D[2000-01-31] ### Date.end_of_week/2 (function) Calculates a date that is the last day of the week for the given `date`. If the day is already the last day of the week, it returns the day itself. For the built-in ISO calendar, the week ends on Sunday. A weekday rather than `:default` can be given as `starting_on`. ### Examples - Date.end_of_week/2 (function) iex> Date.end_of_week(~D[2020-07-11]) ~D[2020-07-12] iex> Date.end_of_week(~D[2020-07-05]) ~D[2020-07-05] iex> Date.end_of_week(~D[2020-07-06], :sunday) ~D[2020-07-11] iex> Date.end_of_week(~D[2020-07-06], :saturday) ~D[2020-07-10] iex> Date.end_of_week(~N[2020-07-11 01:23:45]) ~D[2020-07-12] ### Date.from_erl/2 (function) Converts an Erlang date tuple to a `Date` struct. Only supports converting dates which are in the ISO calendar, or other calendars in which the days also start at midnight. Attempting to convert dates from other calendars will return an error tuple. ### Examples - Date.from_erl/2 (function) iex> Date.from_erl({2000, 1, 1}) {:ok, ~D[2000-01-01]} iex> Date.from_erl({2000, 13, 1}) {:error, :invalid_date} ### Date.from_erl!/2 (function) Converts an Erlang date tuple but raises for invalid dates. ### Examples - Date.from_erl!/2 (function) iex> Date.from_erl!({2000, 1, 1}) ~D[2000-01-01] iex> Date.from_erl!({2000, 13, 1}) ** (ArgumentError) cannot convert {2000, 13, 1} to date, reason: :invalid_date ### Date.from_gregorian_days/2 (function) Converts a number of gregorian days to a `Date` struct. ### Examples - Date.from_gregorian_days/2 (function) iex> Date.from_gregorian_days(1) ~D[0000-01-02] iex> Date.from_gregorian_days(730_485) ~D[2000-01-01] iex> Date.from_gregorian_days(-1) ~D[-0001-12-31] ### Date.from_iso8601/2 (function) Parses the extended "Dates" format described by [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). The year parsed by this function is limited to four digits. ### Examples - Date.from_iso8601/2 (function) iex> Date.from_iso8601("2015-01-23") {:ok, ~D[2015-01-23]} iex> Date.from_iso8601("2015:01:23") {:error, :invalid_format} iex> Date.from_iso8601("2015-01-32") {:error, :invalid_date} ### Date.from_iso8601!/2 (function) Parses the extended "Dates" format described by [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). Raises if the format is invalid. ### Examples - Date.from_iso8601!/2 (function) iex> Date.from_iso8601!("2015-01-23") ~D[2015-01-23] iex> Date.from_iso8601!("2015:01:23") ** (ArgumentError) cannot parse "2015:01:23" as date, reason: :invalid_format ### Date.leap_year?/1 (function) Returns `true` if the year in the given `date` is a leap year. ### Examples - Date.leap_year?/1 (function) iex> Date.leap_year?(~D[2000-01-01]) true iex> Date.leap_year?(~D[2001-01-01]) false iex> Date.leap_year?(~D[2004-01-01]) true iex> Date.leap_year?(~D[1900-01-01]) false iex> Date.leap_year?(~N[2004-01-01 01:23:45]) true ### Date.months_in_year/1 (function) Returns the number of months in the given `date` year. ### Example - Date.months_in_year/1 (function) iex> Date.months_in_year(~D[1900-01-13]) 12 ### Date.new/4 (function) Builds a new ISO date. Expects all values to be integers. Returns `{:ok, date}` if each entry fits its appropriate range, returns `{:error, reason}` otherwise. ### Examples - Date.new/4 (function) iex> Date.new(2000, 1, 1) {:ok, ~D[2000-01-01]} iex> Date.new(2000, 13, 1) {:error, :invalid_date} iex> Date.new(2000, 2, 29) {:ok, ~D[2000-02-29]} iex> Date.new(2000, 2, 30) {:error, :invalid_date} iex> Date.new(2001, 2, 29) {:error, :invalid_date} ### Date.new!/4 (function) Builds a new ISO date. Expects all values to be integers. Returns `date` if each entry fits its appropriate range, raises if the date is invalid. ### Examples - Date.new!/4 (function) iex> Date.new!(2000, 1, 1) ~D[2000-01-01] iex> Date.new!(2000, 13, 1) ** (ArgumentError) cannot build date, reason: :invalid_date iex> Date.new!(2000, 2, 29) ~D[2000-02-29] ### Date.quarter_of_year/1 (function) Calculates the quarter of the year of a given `date`. Returns the day of the year as an integer. For the ISO 8601 calendar (the default), it is an integer from 1 to 4. ### Examples - Date.quarter_of_year/1 (function) iex> Date.quarter_of_year(~D[2016-10-31]) 4 iex> Date.quarter_of_year(~D[2016-01-01]) 1 iex> Date.quarter_of_year(~N[2016-04-01 01:23:45]) 2 iex> Date.quarter_of_year(~D[-0015-09-30]) 3 ### Date.range/2 (function) Returns a range of dates. A range of dates represents a discrete number of dates where the first and last values are dates with matching calendars. Ranges of dates can be increasing (`first <= last`) and are always inclusive. For a decreasing range, use `range/3` with a step of -1 as first argument. ### Examples - Date.range/2 (function) iex> Date.range(~D[1999-01-01], ~D[2000-01-01]) Date.range(~D[1999-01-01], ~D[2000-01-01]) A range of dates implements the `Enumerable` protocol, which means functions in the `Enum` module can be used to work with ranges: iex> range = Date.range(~D[2001-01-01], ~D[2002-01-01]) iex> range Date.range(~D[2001-01-01], ~D[2002-01-01]) iex> Enum.count(range) 366 iex> ~D[2001-02-01] in range true iex> Enum.take(range, 3) [~D[2001-01-01], ~D[2001-01-02], ~D[2001-01-03]] ### Date.range/3 (function) Returns a range of dates with a step. ### Examples - Date.range/3 (function) iex> range = Date.range(~D[2001-01-01], ~D[2002-01-01], 2) iex> range Date.range(~D[2001-01-01], ~D[2002-01-01], 2) iex> Enum.count(range) 183 iex> ~D[2001-01-03] in range true iex> Enum.take(range, 3) [~D[2001-01-01], ~D[2001-01-03], ~D[2001-01-05]] ### Date.shift/2 (function) Shifts given `date` by `duration` according to its calendar. Allowed units are: `:year`, `:month`, `:week`, `:day`. When using the default ISO calendar, durations are collapsed and applied in the order of months and then days: * when shifting by 1 year and 2 months the date is actually shifted by 14 months * when shifting by 2 weeks and 3 days the date is shifted by 17 days When shifting by month, days are rounded down to the nearest valid date. Raises an `ArgumentError` when called with time scale units. ### Examples - Date.shift/2 (function) iex> Date.shift(~D[2016-01-03], month: 2) ~D[2016-03-03] iex> Date.shift(~D[2016-01-30], month: -1) ~D[2015-12-30] iex> Date.shift(~D[2016-01-31], year: 4, day: 1) ~D[2020-02-01] iex> Date.shift(~D[2016-01-03], Duration.new!(month: 2)) ~D[2016-03-03] # leap years iex> Date.shift(~D[2024-02-29], year: 1) ~D[2025-02-28] iex> Date.shift(~D[2024-02-29], year: 4) ~D[2028-02-29] # rounding down iex> Date.shift(~D[2015-01-31], month: 1) ~D[2015-02-28] ### Date.to_erl/1 (function) Converts the given `date` to an Erlang date tuple. Only supports converting dates which are in the ISO calendar, or other calendars in which the days also start at midnight. Attempting to convert dates from other calendars will raise. ### Examples - Date.to_erl/1 (function) iex> Date.to_erl(~D[2000-01-01]) {2000, 1, 1} iex> Date.to_erl(~N[2000-01-01 00:00:00]) {2000, 1, 1} ### Date.to_gregorian_days/1 (function) Converts a `date` struct to a number of gregorian days. ### Examples - Date.to_gregorian_days/1 (function) iex> Date.to_gregorian_days(~D[0000-01-02]) 1 iex> Date.to_gregorian_days(~D[2000-01-01]) 730_485 iex> Date.to_gregorian_days(~N[2000-01-01 00:00:00]) 730_485 ### Date.to_iso8601/2 (function) Converts the given `date` to [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). By default, `Date.to_iso8601/2` returns dates formatted in the "extended" format, for human readability. It also supports the "basic" format through passing the `:basic` option. Only supports converting dates which are in the ISO calendar, or other calendars in which the days also start at midnight. Attempting to convert dates from other calendars will raise an `ArgumentError`. ### Examples - Date.to_iso8601/2 (function) iex> Date.to_iso8601(~D[2000-02-28]) "2000-02-28" iex> Date.to_iso8601(~D[2000-02-28], :basic) "20000228" iex> Date.to_iso8601(~N[2000-02-28 00:00:00]) "2000-02-28" ### Date.to_string/1 (function) Converts the given date to a string according to its calendar. ### Examples - Date.to_string/1 (function) iex> Date.to_string(~D[2000-02-28]) "2000-02-28" iex> Date.to_string(~N[2000-02-28 01:23:45]) "2000-02-28" iex> Date.to_string(~D[-0100-12-15]) "-0100-12-15" ### Date.utc_today/1 (function) Returns the current date in UTC. ### Examples - Date.utc_today/1 (function) iex> date = Date.utc_today() iex> date.year >= 2016 true ### Date.year_of_era/1 (function) Calculates the year-of-era and era for a given calendar year. Returns a tuple `{year, era}` representing the year within the era and the era number. ### Examples - Date.year_of_era/1 (function) iex> Date.year_of_era(~D[0001-01-01]) {1, 1} iex> Date.year_of_era(~D[0000-12-31]) {1, 0} iex> Date.year_of_era(~D[-0001-01-01]) {2, 0} ### Date.t/0 (type) ### DateTime (module) A datetime implementation with a time zone. This datetime can be seen as a snapshot of a date and time at a given time zone. For such purposes, it also includes both UTC and Standard offsets, as well as the zone abbreviation field used exclusively for formatting purposes. Note future datetimes are not necessarily guaranteed to exist, as time zones may change any time in the future due to geopolitical reasons. See the "Datetimes as snapshots" section for more information. Remember, comparisons in Elixir using `==/2`, `>/2`, ` Enum.min([~U[2022-01-12 00:01:00.00Z], ~U[2021-01-12 00:01:00.00Z]], DateTime) ~U[2021-01-12 00:01:00.00Z] Developers should avoid creating the `DateTime` struct directly and instead rely on the functions provided by this module as well as the ones in third-party calendar libraries. ### Time zone database - DateTime (module) Many functions in this module require a time zone database. A time zone database is a record of the UTC offsets that its locales have used at various times in the past, are using, and are expected to use in the future. Because those plans can change, it needs to be periodically updated. By default, `DateTime` uses the default time zone database returned by `Calendar.get_time_zone_database/0`, which defaults to `Calendar.UTCOnlyTimeZoneDatabase` which only handles "Etc/UTC" datetimes and returns `{:error, :utc_only_time_zone_database}` for any other time zone. Other time zone databases can also be configured. Here are some available options and libraries: * [`time_zone_info`](https://github.com/hrzndhrn/time_zone_info) * [`tz`](https://github.com/mathieuprog/tz) * [`tzdata`](https://github.com/lau/tzdata) * [`zoneinfo`](https://github.com/smartrent/zoneinfo) - recommended for embedded devices To use one of them, first make sure it is added as a dependency in `mix.exs`. It can then be configured either via configuration: config :elixir, :time_zone_database, Tz.TimeZoneDatabase or by calling `Calendar.put_time_zone_database/1`: Calendar.put_time_zone_database(Tz.TimeZoneDatabase) See the proper names in the library installation instructions. ### Datetimes as snapshots - DateTime (module) In the first section, we described datetimes as a "snapshot of a date and time at a given time zone". To understand precisely what we mean, let's see an example. Imagine someone in Poland who wants to schedule a meeting with someone in Brazil in the next year. The meeting will happen at 2:30 AM in the Polish time zone. At what time will the meeting happen in Brazil? You can consult the time zone database today, one year before, using the API in this module and it will give you an answer that is valid right now. However, this answer may not be valid in the future. Why? Because both Brazil and Poland may change their timezone rules, ultimately affecting the result. For example, a country may choose to enter or abandon "Daylight Saving Time", which is a process where we adjust the clock one hour forward or one hour back once per year. Whenever the rules change, the exact instant that 2:30 AM in Polish time will be in Brazil may change. In other words, whenever working with future DateTimes, there is no guarantee the results you get will always be correct, until the event actually happens. Therefore, when you ask for a future time, the answers you get are a snapshot that reflects the current state of the time zone rules. For datetimes in the past, this is not a problem, because time zone rules do not change for past events. To make matters worse, it may be that 2:30 AM in Polish time does not actually even exist or it is ambiguous. If a certain time zone observes "Daylight Saving Time", they will move their clock forward once a year. When this happens, there is a whole hour that does not exist. Then, when they move the clock back, there is a certain hour that will happen twice. So if you want to schedule a meeting when this shift back happens, you would need to explicitly say which occurrence of 2:30 AM you mean: the one in "Summer Time", which occurs before the shift, or the one in "Standard Time", which occurs after it. Applications that are date and time sensitive need to take these scenarios into account and correctly communicate them to users. The good news is: Elixir contains all of the building blocks necessary to tackle those problems. The default timezone database used by Elixir, `Calendar.UTCOnlyTimeZoneDatabase`, only works with UTC, which does not observe those issues. Once you bring a proper time zone database, the functions in this module will query the database and return the relevant information. For example, look at how `DateTime.new/4` returns different results based on the scenarios described in this section. ### Converting between timezones - DateTime (module) Bearing in mind the cautions above, and assuming you've brought in a full timezone database, here are some examples of common shifts between time zones. # Local time to UTC new_york = DateTime.from_naive!(~N[2023-06-26T09:30:00], "America/New_York") #=> #DateTime<2023-06-26 09:30:00-04:00 EDT America/New_York> utc = DateTime.shift_zone!(new_york, "Etc/UTC") #=> ~U[2023-06-26 13:30:00Z] # UTC to local time DateTime.shift_zone!(utc, "Europe/Paris") #=> #DateTime<2023-06-26 15:30:00+02:00 CEST Europe/Paris> ### DateTime.add/4 (function) Adds a specified amount of time to a `DateTime`. Accepts an `amount_to_add` in any `unit`. `unit` can be `:day`, `:hour`, `:minute`, `:second` or any subsecond precision from `t:System.time_unit/0`. It defaults to `:second`. Negative values will move backwards in time. This function always considers the unit to be computed according to the `Calendar.ISO`. This function relies on a contiguous representation of time, ignoring the wall time and timezone changes. For example, if you add one day when there are summer time/daylight saving time changes, it will also change the time forward or backward by one hour, so the elapsed time is precisely 24 hours. Similarly, adding just a few seconds to a datetime just before "spring forward" can cause wall time to increase by more than an hour. While this means this function is precise in terms of elapsed time, its result may be misleading in certain use cases. For example, if a user requests a meeting to happen every day at 15:00 and you use this function to compute all future meetings by adding day after day, this function may change the meeting time to 14:00 or 16:00 if there are changes to the current timezone. Computing of recurring datetimes is not currently supported in Elixir's standard library but it is available by third-party libraries. ### Examples - DateTime.add/4 (function) iex> dt = DateTime.from_naive!(~N[2018-11-15 10:00:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> dt |> DateTime.add(3600, :second, FakeTimeZoneDatabase) #DateTime<2018-11-15 11:00:00+01:00 CET Europe/Copenhagen> iex> DateTime.add(~U[2018-11-15 10:00:00Z], 3600, :second) ~U[2018-11-15 11:00:00Z] When adding 3 seconds just before "spring forward" we go from 1:59:59 to 3:00:02: iex> dt = DateTime.from_naive!(~N[2019-03-31 01:59:59.123], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> dt |> DateTime.add(3, :second, FakeTimeZoneDatabase) #DateTime<2019-03-31 03:00:02.123+02:00 CEST Europe/Copenhagen> When adding 1 day during "spring forward", the hour also changes: iex> dt = DateTime.from_naive!(~N[2019-03-31 01:00:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> dt |> DateTime.add(1, :day, FakeTimeZoneDatabase) #DateTime<2019-04-01 02:00:00+02:00 CEST Europe/Copenhagen> This operation merges the precision of the naive date time with the given unit: iex> result = DateTime.add(~U[2014-10-02 00:29:10Z], 21, :millisecond) ~U[2014-10-02 00:29:10.021Z] iex> result.microsecond {21000, 3} To shift a datetime by a `Duration` and according to its underlying calendar, use `DateTime.shift/3`. ### DateTime.after?/2 (function) Returns `true` if the first datetime is strictly later than the second. ### Examples - DateTime.after?/2 (function) iex> DateTime.after?(~U[2022-02-02 11:00:00Z], ~U[2021-01-01 11:00:00Z]) true iex> DateTime.after?(~U[2021-01-01 11:00:00Z], ~U[2021-01-01 11:00:00Z]) false iex> DateTime.after?(~U[2021-01-01 11:00:00Z], ~U[2022-02-02 11:00:00Z]) false ### DateTime.before?/2 (function) Returns `true` if the first datetime is strictly earlier than the second. ### Examples - DateTime.before?/2 (function) iex> DateTime.before?(~U[2021-01-01 11:00:00Z], ~U[2022-02-02 11:00:00Z]) true iex> DateTime.before?(~U[2021-01-01 11:00:00Z], ~U[2021-01-01 11:00:00Z]) false iex> DateTime.before?(~U[2022-02-02 11:00:00Z], ~U[2021-01-01 11:00:00Z]) false ### DateTime.compare/2 (function) Compares two datetime structs. Returns `:gt` if the first datetime is later than the second and `:lt` for vice versa. If the two datetimes are equal `:eq` is returned. Note that both UTC and Standard offsets will be taken into account when comparison is done. ### Examples - DateTime.compare/2 (function) iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} iex> dt2 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> DateTime.compare(dt1, dt2) :gt ### DateTime.convert/2 (function) Converts a given `datetime` from one calendar to another. If it is not possible to convert unambiguously between the calendars (see `Calendar.compatible_calendars?/2`), an `{:error, :incompatible_calendars}` tuple is returned. ### Examples - DateTime.convert/2 (function) Imagine someone implements `Calendar.Holocene`, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year: iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} iex> DateTime.convert(dt1, Calendar.Holocene) {:ok, %DateTime{calendar: Calendar.Holocene, day: 29, hour: 23, microsecond: {0, 0}, minute: 0, month: 2, second: 7, std_offset: 0, time_zone: "America/Manaus", utc_offset: -14400, year: 12000, zone_abbr: "AMT"}} ### DateTime.convert!/2 (function) Converts a given `datetime` from one calendar to another. If it is not possible to convert unambiguously between the calendars (see `Calendar.compatible_calendars?/2`), an ArgumentError is raised. ### Examples - DateTime.convert!/2 (function) Imagine someone implements `Calendar.Holocene`, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year: iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} iex> DateTime.convert!(dt1, Calendar.Holocene) %DateTime{calendar: Calendar.Holocene, day: 29, hour: 23, microsecond: {0, 0}, minute: 0, month: 2, second: 7, std_offset: 0, time_zone: "America/Manaus", utc_offset: -14400, year: 12000, zone_abbr: "AMT"} ### DateTime.diff/3 (function) Subtracts `datetime2` from `datetime1`. The answer can be returned in any `:day`, `:hour`, `:minute`, or any `unit` available from `t:System.time_unit/0`. The unit is measured according to `Calendar.ISO` and defaults to `:second`. Fractional results are not supported and are truncated. ### Examples - DateTime.diff/3 (function) iex> DateTime.diff(~U[2024-01-15 10:00:10Z], ~U[2024-01-15 10:00:00Z]) 10 This function also considers timezone offsets: iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} iex> dt2 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> DateTime.diff(dt1, dt2) 18000 iex> DateTime.diff(dt2, dt1) -18000 iex> DateTime.diff(dt1, dt2, :hour) 5 iex> DateTime.diff(dt2, dt1, :hour) -5 ### DateTime.from_gregorian_seconds/3 (function) Converts a number of gregorian seconds to a `DateTime` struct. The returned `DateTime` will have `UTC` timezone, if you want other timezone, please use `DateTime.shift_zone/3`. ### Examples - DateTime.from_gregorian_seconds/3 (function) iex> DateTime.from_gregorian_seconds(1) ~U[0000-01-01 00:00:01Z] iex> DateTime.from_gregorian_seconds(63_755_511_991, {5000, 3}) ~U[2020-05-01 00:26:31.005Z] iex> DateTime.from_gregorian_seconds(-1) ~U[-0001-12-31 23:59:59Z] ### DateTime.from_iso8601/2 (function) Parses the extended "Date and time of day" format described by [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). Since ISO 8601 does not include the proper time zone, the given string will be converted to UTC and its offset in seconds will be returned as part of this function. Therefore offset information must be present in the string. As specified in the standard, the separator "T" may be omitted if desired as there is no ambiguity within this function. Note leap seconds are not supported by the built-in Calendar.ISO. ### Examples - DateTime.from_iso8601/2 (function) iex> {:ok, datetime, 0} = DateTime.from_iso8601("2015-01-23T23:50:07Z") iex> datetime ~U[2015-01-23 23:50:07Z] iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07.123+02:30") iex> datetime ~U[2015-01-23 21:20:07.123Z] iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07,123+02:30") iex> datetime ~U[2015-01-23 21:20:07.123Z] iex> {:ok, datetime, 0} = DateTime.from_iso8601("-2015-01-23T23:50:07Z") iex> datetime ~U[-2015-01-23 23:50:07Z] iex> {:ok, datetime, 9000} = DateTime.from_iso8601("-2015-01-23T23:50:07,123+02:30") iex> datetime ~U[-2015-01-23 21:20:07.123Z] iex> {:ok, datetime, 9000} = DateTime.from_iso8601("20150123T235007.123+0230", :basic) iex> datetime ~U[2015-01-23 21:20:07.123Z] iex> DateTime.from_iso8601("2015-01-23P23:50:07") {:error, :invalid_format} iex> DateTime.from_iso8601("2015-01-23T23:50:07") {:error, :missing_offset} iex> DateTime.from_iso8601("2015-01-23 23:50:61") {:error, :invalid_time} iex> DateTime.from_iso8601("2015-01-32 23:50:07") {:error, :invalid_date} iex> DateTime.from_iso8601("2015-01-23T23:50:07.123-00:00") {:error, :invalid_format} ### DateTime.from_iso8601/3 (function) Converts from ISO8601 specifying both a calendar and a mode. See `from_iso8601/2` for more information. ### Examples - DateTime.from_iso8601/3 (function) iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07,123+02:30", Calendar.ISO, :extended) iex> datetime ~U[2015-01-23 21:20:07.123Z] iex> {:ok, datetime, 9000} = DateTime.from_iso8601("20150123T235007.123+0230", Calendar.ISO, :basic) iex> datetime ~U[2015-01-23 21:20:07.123Z] ### DateTime.from_naive/3 (function) Converts the given `NaiveDateTime` to `DateTime`. It expects a time zone to put the `NaiveDateTime` in. If the time zone is "Etc/UTC", it always succeeds. Otherwise, the NaiveDateTime is checked against the time zone database given as `time_zone_database`. See the "Time zone database" section in the module documentation. ### Examples - DateTime.from_naive/3 (function) iex> DateTime.from_naive(~N[2016-05-24 13:26:08.003], "Etc/UTC") {:ok, ~U[2016-05-24 13:26:08.003Z]} When the datetime is ambiguous - for instance during changing from summer to winter time - the two possible valid datetimes are returned in a tuple. The first datetime is also the one which comes first chronologically, while the second one comes last. iex> {:ambiguous, first_dt, second_dt} = DateTime.from_naive(~N[2018-10-28 02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> first_dt #DateTime<2018-10-28 02:30:00+02:00 CEST Europe/Copenhagen> iex> second_dt #DateTime<2018-10-28 02:30:00+01:00 CET Europe/Copenhagen> When there is a gap in wall time - for instance in spring when the clocks are turned forward - the latest valid datetime just before the gap and the first valid datetime just after the gap. iex> {:gap, just_before, just_after} = DateTime.from_naive(~N[2019-03-31 02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> just_before #DateTime<2019-03-31 01:59:59.999999+01:00 CET Europe/Copenhagen> iex> just_after #DateTime<2019-03-31 03:00:00+02:00 CEST Europe/Copenhagen> Most of the time there is one, and just one, valid datetime for a certain date and time in a certain time zone. iex> {:ok, datetime} = DateTime.from_naive(~N[2018-07-28 12:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> datetime #DateTime<2018-07-28 12:30:00+02:00 CEST Europe/Copenhagen> This function accepts any map or struct that contains at least the same fields as a `NaiveDateTime` struct. The most common example of that is a `DateTime`. In this case the information about the time zone of that `DateTime` is completely ignored. This is the same principle as passing a `DateTime` to `Date.to_iso8601/2`. `Date.to_iso8601/2` extracts only the date-specific fields (calendar, year, month and day) of the given structure and ignores all others. This way if you have a `DateTime` in one time zone, you can get the same wall time in another time zone. For instance if you have 2018-08-24 10:00:00 in Copenhagen and want a `DateTime` for 2018-08-24 10:00:00 in UTC you can do: iex> cph_datetime = DateTime.from_naive!(~N[2018-08-24 10:00:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> {:ok, utc_datetime} = DateTime.from_naive(cph_datetime, "Etc/UTC", FakeTimeZoneDatabase) iex> utc_datetime ~U[2018-08-24 10:00:00Z] If instead you want a `DateTime` for the same point time in a different time zone see the `DateTime.shift_zone/3` function which would convert 2018-08-24 10:00:00 in Copenhagen to 2018-08-24 08:00:00 in UTC. ### DateTime.from_naive!/3 (function) Converts the given `NaiveDateTime` to `DateTime`. It expects a time zone to put the NaiveDateTime in. If the time zone is "Etc/UTC", it always succeeds. Otherwise, the NaiveDateTime is checked against the time zone database given as `time_zone_database`. See the "Time zone database" section in the module documentation. ### Examples - DateTime.from_naive!/3 (function) iex> DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC") ~U[2016-05-24 13:26:08.003Z] iex> DateTime.from_naive!(~N[2018-05-24 13:26:08.003], "Europe/Copenhagen", FakeTimeZoneDatabase) #DateTime<2018-05-24 13:26:08.003+02:00 CEST Europe/Copenhagen> ### DateTime.from_unix/3 (function) Converts the given Unix time to `DateTime`. The integer can be given in different unit according to `System.convert_time_unit/3` and it will be converted to microseconds internally. Up to 253402300799 seconds is supported. Unix times are always in UTC and therefore the DateTime will be returned in UTC. ### Examples - DateTime.from_unix/3 (function) iex> {:ok, datetime} = DateTime.from_unix(1_464_096_368) iex> datetime ~U[2016-05-24 13:26:08Z] iex> {:ok, datetime} = DateTime.from_unix(1_432_560_368_868_569, :microsecond) iex> datetime ~U[2015-05-25 13:26:08.868569Z] iex> {:ok, datetime} = DateTime.from_unix(253_402_300_799) iex> datetime ~U[9999-12-31 23:59:59Z] iex> {:error, :invalid_unix_time} = DateTime.from_unix(253_402_300_800) The unit can also be an integer as in `t:System.time_unit/0`: iex> {:ok, datetime} = DateTime.from_unix(143_256_036_886_856, 1024) iex> datetime ~U[6403-03-17 07:05:22.320312Z] Negative Unix times are supported up to -377705116800 seconds: iex> {:ok, datetime} = DateTime.from_unix(-377_705_116_800) iex> datetime ~U[-9999-01-01 00:00:00Z] iex> {:error, :invalid_unix_time} = DateTime.from_unix(-377_705_116_801) ### DateTime.from_unix!/3 (function) Converts the given Unix time to `DateTime`. The integer can be given in different unit according to `System.convert_time_unit/3` and it will be converted to microseconds internally. Unix times are always in UTC and therefore the DateTime will be returned in UTC. ### Examples - DateTime.from_unix!/3 (function) # An easy way to get the Unix epoch is passing 0 to this function iex> DateTime.from_unix!(0) ~U[1970-01-01 00:00:00Z] iex> DateTime.from_unix!(1_464_096_368) ~U[2016-05-24 13:26:08Z] iex> DateTime.from_unix!(1_432_560_368_868_569, :microsecond) ~U[2015-05-25 13:26:08.868569Z] iex> DateTime.from_unix!(143_256_036_886_856, 1024) ~U[6403-03-17 07:05:22.320312Z] ### DateTime.new/4 (function) Builds a datetime from date and time structs. It expects a time zone to put the `DateTime` in. If the time zone is not passed it will default to `"Etc/UTC"`, which always succeeds. Otherwise, the `DateTime` is checked against the time zone database given as `time_zone_database`. See the "Time zone database" section in the module documentation. ### Examples - DateTime.new/4 (function) iex> DateTime.new(~D[2016-05-24], ~T[13:26:08.003], "Etc/UTC") {:ok, ~U[2016-05-24 13:26:08.003Z]} When the datetime is ambiguous - for instance during changing from summer to winter time - the two possible valid datetimes are returned in a tuple. The first datetime is also the one which comes first chronologically, while the second one comes last. iex> {:ambiguous, first_dt, second_dt} = DateTime.new(~D[2018-10-28], ~T[02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> first_dt #DateTime<2018-10-28 02:30:00+02:00 CEST Europe/Copenhagen> iex> second_dt #DateTime<2018-10-28 02:30:00+01:00 CET Europe/Copenhagen> When there is a gap in wall time - for instance in spring when the clocks are turned forward - the latest valid datetime just before the gap and the first valid datetime just after the gap. iex> {:gap, just_before, just_after} = DateTime.new(~D[2019-03-31], ~T[02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> just_before #DateTime<2019-03-31 01:59:59.999999+01:00 CET Europe/Copenhagen> iex> just_after #DateTime<2019-03-31 03:00:00+02:00 CEST Europe/Copenhagen> Most of the time there is one, and just one, valid datetime for a certain date and time in a certain time zone. iex> {:ok, datetime} = DateTime.new(~D[2018-07-28], ~T[12:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> datetime #DateTime<2018-07-28 12:30:00+02:00 CEST Europe/Copenhagen> ### DateTime.new!/4 (function) Builds a datetime from date and time structs, raising on errors. It expects a time zone to put the `DateTime` in. If the time zone is not passed it will default to `"Etc/UTC"`, which always succeeds. Otherwise, the DateTime is checked against the time zone database given as `time_zone_database`. See the "Time zone database" section in the module documentation. ### Examples - DateTime.new!/4 (function) iex> DateTime.new!(~D[2016-05-24], ~T[13:26:08.003], "Etc/UTC") ~U[2016-05-24 13:26:08.003Z] When the datetime is ambiguous - for instance during changing from summer to winter time - an error will be raised. iex> DateTime.new!(~D[2018-10-28], ~T[02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase) ** (ArgumentError) cannot build datetime with ~D[2018-10-28] and ~T[02:30:00] because such instant is ambiguous in time zone Europe/Copenhagen as there is an overlap between #DateTime<2018-10-28 02:30:00+02:00 CEST Europe/Copenhagen> and #DateTime<2018-10-28 02:30:00+01:00 CET Europe/Copenhagen> When there is a gap in wall time - for instance in spring when the clocks are turned forward - an error will be raised. iex> DateTime.new!(~D[2019-03-31], ~T[02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase) ** (ArgumentError) cannot build datetime with ~D[2019-03-31] and ~T[02:30:00] because such instant does not exist in time zone Europe/Copenhagen as there is a gap between #DateTime<2019-03-31 01:59:59.999999+01:00 CET Europe/Copenhagen> and #DateTime<2019-03-31 03:00:00+02:00 CEST Europe/Copenhagen> Most of the time there is one, and just one, valid datetime for a certain date and time in a certain time zone. iex> datetime = DateTime.new!(~D[2018-07-28], ~T[12:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase) iex> datetime #DateTime<2018-07-28 12:30:00+02:00 CEST Europe/Copenhagen> ### DateTime.now/2 (function) Returns the current datetime in the provided time zone. By default, it uses the default time_zone returned by `Calendar.get_time_zone_database/0`, which defaults to `Calendar.UTCOnlyTimeZoneDatabase` which only handles "Etc/UTC" datetimes. Other time zone databases can be passed as argument or set globally. See the "Time zone database" section in the module docs. ### Examples - DateTime.now/2 (function) iex> {:ok, datetime} = DateTime.now("Etc/UTC") iex> datetime.time_zone "Etc/UTC" iex> DateTime.now("Europe/Copenhagen") {:error, :utc_only_time_zone_database} iex> DateTime.now("bad timezone", FakeTimeZoneDatabase) {:error, :time_zone_not_found} ### DateTime.now!/2 (function) Returns the current datetime in the provided time zone or raises on errors See `now/2` for more information. ### Examples - DateTime.now!/2 (function) iex> datetime = DateTime.now!("Etc/UTC") iex> datetime.time_zone "Etc/UTC" iex> DateTime.now!("Europe/Copenhagen") ** (ArgumentError) cannot get current datetime in "Europe/Copenhagen" time zone, reason: :utc_only_time_zone_database iex> DateTime.now!("bad timezone", FakeTimeZoneDatabase) ** (ArgumentError) cannot get current datetime in "bad timezone" time zone, reason: :time_zone_not_found ### DateTime.shift/3 (function) Shifts given `datetime` by `duration` according to its calendar. Allowed units are: `:year`, `:month`, `:week`, `:day`, `:hour`, `:minute`, `:second`, `:microsecond`. This operation is equivalent to shifting the datetime wall clock (in other words, the value as someone in that timezone would see on their watch), then applying the time zone offset to convert it to UTC, and finally computing the new timezone in case of shifts. This ensures `shift/3` always returns a valid datetime. On the other hand, time zones that observe "Daylight Saving Time" or other changes, across summer/winter time will add/remove hours from the resulting datetime: dt = DateTime.new!(~D[2019-03-31], ~T[01:00:00], "Europe/Copenhagen") DateTime.shift(dt, hour: 1) #=> #DateTime<2019-03-31 03:00:00+02:00 CEST Europe/Copenhagen> dt = DateTime.new!(~D[2018-11-04], ~T[00:00:00], "America/Los_Angeles") DateTime.shift(dt, hour: 2) #=> #DateTime<2018-11-04 01:00:00-08:00 PST America/Los_Angeles> In case you don't want these changes to happen automatically or you want to surface time zone conflicts to the user, you can shift the datetime as a naive datetime and then use `from_naive/2`: dt |> NaiveDateTime.shift(duration) |> DateTime.from_naive(dt.time_zone) When using the default ISO calendar, durations are collapsed and applied in the order of months, then seconds and microseconds: * when shifting by 1 year and 2 months the date is actually shifted by 14 months * weeks, days and smaller units are collapsed into seconds and microseconds When shifting by month, days are rounded down to the nearest valid date. ### Examples - DateTime.shift/3 (function) iex> DateTime.shift(~U[2016-01-01 00:00:00Z], month: 2) ~U[2016-03-01 00:00:00Z] iex> DateTime.shift(~U[2016-01-01 00:00:00Z], year: 1, week: 4) ~U[2017-01-29 00:00:00Z] iex> DateTime.shift(~U[2016-01-01 00:00:00Z], minute: -25) ~U[2015-12-31 23:35:00Z] iex> DateTime.shift(~U[2016-01-01 00:00:00Z], minute: 5, microsecond: {500, 4}) ~U[2016-01-01 00:05:00.0005Z] # leap years iex> DateTime.shift(~U[2024-02-29 00:00:00Z], year: 1) ~U[2025-02-28 00:00:00Z] iex> DateTime.shift(~U[2024-02-29 00:00:00Z], year: 4) ~U[2028-02-29 00:00:00Z] # rounding down iex> DateTime.shift(~U[2015-01-31 00:00:00Z], month: 1) ~U[2015-02-28 00:00:00Z] ### DateTime.shift_zone/3 (function) Changes the time zone of a `DateTime`. Returns a `DateTime` for the same point in time, but instead at the time zone provided. It assumes that `DateTime` is valid and exists in the given time zone and calendar. By default, it uses the default time zone database returned by `Calendar.get_time_zone_database/0`, which defaults to `Calendar.UTCOnlyTimeZoneDatabase` which only handles "Etc/UTC" datetimes. Other time zone databases can be passed as argument or set globally. See the "Time zone database" section in the module docs. ### Examples - DateTime.shift_zone/3 (function) iex> {:ok, pacific_datetime} = DateTime.shift_zone(~U[2018-07-16 10:00:00Z], "America/Los_Angeles", FakeTimeZoneDatabase) iex> pacific_datetime #DateTime<2018-07-16 03:00:00-07:00 PDT America/Los_Angeles> iex> DateTime.shift_zone(~U[2018-07-16 10:00:00Z], "bad timezone", FakeTimeZoneDatabase) {:error, :time_zone_not_found} ### DateTime.shift_zone!/3 (function) Changes the time zone of a `DateTime` or raises on errors. See `shift_zone/3` for more information. ### Examples - DateTime.shift_zone!/3 (function) iex> DateTime.shift_zone!(~U[2018-07-16 10:00:00Z], "America/Los_Angeles", FakeTimeZoneDatabase) #DateTime<2018-07-16 03:00:00-07:00 PDT America/Los_Angeles> iex> DateTime.shift_zone!(~U[2018-07-16 10:00:00Z], "bad timezone", FakeTimeZoneDatabase) ** (ArgumentError) cannot shift ~U[2018-07-16 10:00:00Z] to "bad timezone" time zone, reason: :time_zone_not_found ### DateTime.to_date/1 (function) Converts a `DateTime` into a `Date`. Because `Date` does not hold time nor time zone information, data will be lost during the conversion. ### Examples - DateTime.to_date/1 (function) iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> DateTime.to_date(dt) ~D[2000-02-29] ### DateTime.to_gregorian_seconds/1 (function) Converts a `DateTime` struct to a number of gregorian seconds and microseconds. ### Examples - DateTime.to_gregorian_seconds/1 (function) iex> dt = %DateTime{year: 0000, month: 1, day: 1, zone_abbr: "UTC", ...> hour: 0, minute: 0, second: 1, microsecond: {0, 0}, ...> utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"} iex> DateTime.to_gregorian_seconds(dt) {1, 0} iex> dt = %DateTime{year: 2020, month: 5, day: 1, zone_abbr: "UTC", ...> hour: 0, minute: 26, second: 31, microsecond: {5000, 0}, ...> utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"} iex> DateTime.to_gregorian_seconds(dt) {63_755_511_991, 5000} iex> dt = %DateTime{year: 2020, month: 5, day: 1, zone_abbr: "CET", ...> hour: 1, minute: 26, second: 31, microsecond: {5000, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> DateTime.to_gregorian_seconds(dt) {63_755_511_991, 5000} ### DateTime.to_iso8601/3 (function) Converts the given datetime to [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601) format. By default, `DateTime.to_iso8601/2` returns datetimes formatted in the "extended" format, for human readability. It also supports the "basic" format through passing the `:basic` option. You can also optionally specify an offset for the formatted string. If none is given, the one in the given `datetime` is used. Only supports converting datetimes which are in the ISO calendar. If another calendar is given, it is automatically converted to ISO. It raises if not possible. WARNING: the ISO 8601 datetime format does not contain the time zone nor its abbreviation, which means information is lost when converting to such format. ### Examples - DateTime.to_iso8601/3 (function) iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> DateTime.to_iso8601(dt) "2000-02-29T23:00:07+01:00" iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "UTC", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"} iex> DateTime.to_iso8601(dt) "2000-02-29T23:00:07Z" iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} iex> DateTime.to_iso8601(dt, :extended) "2000-02-29T23:00:07-04:00" iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} iex> DateTime.to_iso8601(dt, :basic) "20000229T230007-0400" iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} iex> DateTime.to_iso8601(dt, :extended, 3600) "2000-03-01T04:00:07+01:00" iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} iex> DateTime.to_iso8601(dt, :extended, 0) "2000-03-01T03:00:07+00:00" iex> dt = %DateTime{year: 2000, month: 3, day: 01, zone_abbr: "UTC", ...> hour: 03, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"} iex> DateTime.to_iso8601(dt, :extended, 0) "2000-03-01T03:00:07Z" iex> {:ok, dt, offset} = DateTime.from_iso8601("2000-03-01T03:00:07Z") iex> "2000-03-01T03:00:07Z" = DateTime.to_iso8601(dt, :extended, offset) ### DateTime.to_naive/1 (function) Converts the given `datetime` into a `NaiveDateTime`. Because `NaiveDateTime` does not hold time zone information, any time zone related data will be lost during the conversion. ### Examples - DateTime.to_naive/1 (function) iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 1}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> DateTime.to_naive(dt) ~N[2000-02-29 23:00:07.0] ### DateTime.to_string/1 (function) Converts the given `datetime` to a string according to its calendar. Unfortunately, there is no standard that specifies rendering of a datetime with its complete time zone information, so Elixir uses a custom (but relatively common) representation which appends the time zone abbreviation and full name to the datetime. ### Examples - DateTime.to_string/1 (function) iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> DateTime.to_string(dt) "2000-02-29 23:00:07+01:00 CET Europe/Warsaw" iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "UTC", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"} iex> DateTime.to_string(dt) "2000-02-29 23:00:07Z" iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} iex> DateTime.to_string(dt) "2000-02-29 23:00:07-04:00 AMT America/Manaus" iex> dt = %DateTime{year: -100, month: 12, day: 19, zone_abbr: "CET", ...> hour: 3, minute: 20, second: 31, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Stockholm"} iex> DateTime.to_string(dt) "-0100-12-19 03:20:31+01:00 CET Europe/Stockholm" ### DateTime.to_time/1 (function) Converts a `DateTime` into `Time`. Because `Time` does not hold date nor time zone information, data will be lost during the conversion. ### Examples - DateTime.to_time/1 (function) iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 1}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> DateTime.to_time(dt) ~T[23:00:07.0] ### DateTime.to_unix/2 (function) Converts the given `datetime` to Unix time. The `datetime` is expected to be using the ISO calendar with a year greater than or equal to 0. It will return the integer with the given unit, according to `System.convert_time_unit/3`. ### Examples - DateTime.to_unix/2 (function) iex> 1_464_096_368 |> DateTime.from_unix!() |> DateTime.to_unix() 1464096368 iex> dt = %DateTime{calendar: Calendar.ISO, day: 20, hour: 18, microsecond: {273806, 6}, ...> minute: 58, month: 11, second: 19, time_zone: "America/Montevideo", ...> utc_offset: -10800, std_offset: 3600, year: 2014, zone_abbr: "UYST"} iex> DateTime.to_unix(dt) 1416517099 iex> flamel = %DateTime{calendar: Calendar.ISO, day: 22, hour: 8, microsecond: {527771, 6}, ...> minute: 2, month: 3, second: 25, std_offset: 0, time_zone: "Etc/UTC", ...> utc_offset: 0, year: 1418, zone_abbr: "UTC"} iex> DateTime.to_unix(flamel) -17412508655 ### DateTime.truncate/2 (function) Returns the given datetime with the microsecond field truncated to the given precision (`:microsecond`, `:millisecond` or `:second`). The given datetime is returned unchanged if it already has lower precision than the given precision. ### Examples - DateTime.truncate/2 (function) iex> dt1 = %DateTime{year: 2017, month: 11, day: 7, zone_abbr: "CET", ...> hour: 11, minute: 45, second: 18, microsecond: {123456, 6}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Paris"} iex> DateTime.truncate(dt1, :microsecond) #DateTime<2017-11-07 11:45:18.123456+01:00 CET Europe/Paris> iex> dt2 = %DateTime{year: 2017, month: 11, day: 7, zone_abbr: "CET", ...> hour: 11, minute: 45, second: 18, microsecond: {123456, 6}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Paris"} iex> DateTime.truncate(dt2, :millisecond) #DateTime<2017-11-07 11:45:18.123+01:00 CET Europe/Paris> iex> dt3 = %DateTime{year: 2017, month: 11, day: 7, zone_abbr: "CET", ...> hour: 11, minute: 45, second: 18, microsecond: {123456, 6}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Paris"} iex> DateTime.truncate(dt3, :second) #DateTime<2017-11-07 11:45:18+01:00 CET Europe/Paris> ### DateTime.utc_now/1 (function) Returns the current datetime in UTC. If you want the current time in Unix seconds, use `System.os_time/1` instead. You can also pass a time unit to automatically truncate the resulting datetime. This is available since v1.15.0. The default unit if none gets passed is `:native`, which results on a default resolution of microseconds. ### Examples - DateTime.utc_now/1 (function) iex> datetime = DateTime.utc_now() iex> datetime.time_zone "Etc/UTC" iex> datetime = DateTime.utc_now(:second) iex> datetime.microsecond {0, 0} ### DateTime.utc_now/2 (function) Returns the current datetime in UTC, supporting a specific calendar and precision. If you want the current time in Unix seconds, use `System.os_time/1` instead. ### Examples - DateTime.utc_now/2 (function) iex> datetime = DateTime.utc_now(:microsecond, Calendar.ISO) iex> datetime.time_zone "Etc/UTC" iex> datetime = DateTime.utc_now(:second, Calendar.ISO) iex> datetime.microsecond {0, 0} ### DateTime.t/0 (type) ### Duration (module) Struct and functions for handling durations. A `Duration` struct represents a collection of time scale units, allowing for manipulation and calculation of durations. Date and time scale units are represented as integers, allowing for both positive and negative values. Microseconds are represented using a tuple `{microsecond, precision}`. This ensures compatibility with other calendar types implementing time, such as `Time`, `DateTime`, and `NaiveDateTime`. ### Shifting - Duration (module) The most common use of durations in Elixir's standard library is to "shift" the calendar types. iex> Date.shift(~D[2016-01-03], month: 2) ~D[2016-03-03] In the example above, `Date.shift/2` automatically converts the units into a `Duration` struct, although one can also be given directly: iex> Date.shift(~D[2016-01-03], Duration.new!(month: 2)) ~D[2016-03-03] It is important to note that shifting is not an arithmetic operation. For example, adding `date + 1 month + 1 month` does not yield the same result as `date + 2 months`. Let's see an example: iex> ~D[2016-01-31] |> Date.shift(month: 1) |> Date.shift(month: 1) ~D[2016-03-29] iex> ~D[2016-01-31] |> Date.shift(month: 2) ~D[2016-03-31] As you can see above, the results differ, which explains why operations with durations are called "shift" rather than "add". This happens because, once we add one month to `2016-01-31`, we get `2016-02-29`. Then adding one extra month gives us `2016-03-29` instead of `2016-03-31`. In particular, when applying durations to `Calendar.ISO` types: * larger units (such as years and months) are applied before smaller ones (such as weeks, hours, days, and so on) * units are collapsed into months (`:year` and `:month`), seconds (`:week`, `:day`, `:hour`, `:minute`, `:second`) and microseconds (`:microsecond`) before they are applied * 1 year is equivalent to 12 months, 1 week is equivalent to 7 days. Therefore, 4 weeks _are not_ equivalent to 1 month * in case of non-existing dates, the results are rounded down to the nearest valid date As the `shift/2` functions are calendar aware, they are guaranteed to return valid date/times, considering leap years as well as DST in applicable time zones. ### Intervals - Duration (module) Durations in Elixir can be combined with stream operations to build intervals. For example, to retrieve the next three Wednesdays starting from 17th April, 2024: iex> ~D[2024-04-17] |> Stream.iterate(&Date.shift(&1, week: 1)) |> Enum.take(3) [~D[2024-04-17], ~D[2024-04-24], ~D[2024-05-01]] However, once again, it is important to remember that shifting a duration is not arithmetic, so you may want to use the functions in this module depending on what you to achieve. Compare the results of both examples below: # Adding one month after the other iex> date = ~D[2016-01-31] iex> duration = Duration.new!(month: 1) iex> stream = Stream.iterate(date, fn prev_date -> Date.shift(prev_date, duration) end) iex> Enum.take(stream, 3) [~D[2016-01-31], ~D[2016-02-29], ~D[2016-03-29]] # Multiplying durations by an index iex> date = ~D[2016-01-31] iex> duration = Duration.new!(month: 1) iex> stream = Stream.from_index(fn i -> Date.shift(date, Duration.multiply(duration, i)) end) iex> Enum.take(stream, 3) [~D[2016-01-31], ~D[2016-02-29], ~D[2016-03-31]] The second example consistently points to the last day of the month, as it performs operations on the duration, rather than shifting date after date. ### Duration.add/2 (function) Adds units of given durations `d1` and `d2`. Respects the the highest microsecond precision of the two. ### Examples - Duration.add/2 (function) iex> Duration.add(Duration.new!(week: 2, day: 1), Duration.new!(day: 2)) %Duration{week: 2, day: 3} iex> Duration.add(Duration.new!(microsecond: {400, 3}), Duration.new!(microsecond: {600, 6})) %Duration{microsecond: {1000, 6}} ### Duration.from_iso8601/1 (function) Parses an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Durations) formatted duration string to a `Duration` struct. Duration strings, as well as individual units, may be prefixed with plus/minus signs so that: - `-PT6H3M` parses as `%Duration{hour: -6, minute: -3}` - `-PT6H-3M` parses as `%Duration{hour: -6, minute: 3}` - `+PT6H3M` parses as `%Duration{hour: 6, minute: 3}` - `+PT6H-3M` parses as `%Duration{hour: 6, minute: -3}` Duration designators must be provided in order of magnitude: `P[n]Y[n]M[n]W[n]DT[n]H[n]M[n]S`. Only seconds may be specified with a decimal fraction, using either a comma or a full stop: `P1DT4,5S`. ### Examples - Duration.from_iso8601/1 (function) iex> Duration.from_iso8601("P1Y2M3DT4H5M6S") {:ok, %Duration{year: 1, month: 2, day: 3, hour: 4, minute: 5, second: 6}} iex> Duration.from_iso8601("P3Y-2MT3H") {:ok, %Duration{year: 3, month: -2, hour: 3}} iex> Duration.from_iso8601("-PT10H-30M") {:ok, %Duration{hour: -10, minute: 30}} iex> Duration.from_iso8601("PT4.650S") {:ok, %Duration{second: 4, microsecond: {650000, 3}}} ### Duration.from_iso8601!/1 (function) Same as `from_iso8601/1` but raises an `ArgumentError`. ### Examples - Duration.from_iso8601!/1 (function) iex> Duration.from_iso8601!("P1Y2M3DT4H5M6S") %Duration{year: 1, month: 2, day: 3, hour: 4, minute: 5, second: 6} iex> Duration.from_iso8601!("P10D") %Duration{day: 10} ### Duration.multiply/2 (function) Multiplies `duration` units by given `integer`. ### Examples - Duration.multiply/2 (function) iex> Duration.multiply(Duration.new!(day: 1, minute: 15, second: -10), 3) %Duration{day: 3, minute: 45, second: -30} iex> Duration.multiply(Duration.new!(microsecond: {200, 4}), 3) %Duration{microsecond: {600, 4}} ### Duration.negate/1 (function) Negates `duration` units. ### Examples - Duration.negate/1 (function) iex> Duration.negate(Duration.new!(day: 1, minute: 15, second: -10)) %Duration{day: -1, minute: -15, second: 10} iex> Duration.negate(Duration.new!(microsecond: {500000, 4})) %Duration{microsecond: {-500000, 4}} ### Duration.new!/1 (function) Creates a new `Duration` struct from given `unit_pairs`. Raises an `ArgumentError` when called with invalid unit pairs. ### Examples - Duration.new!/1 (function) iex> Duration.new!(year: 1, week: 3, hour: 4, second: 1) %Duration{year: 1, week: 3, hour: 4, second: 1} iex> Duration.new!(second: 1, microsecond: {1000, 6}) %Duration{second: 1, microsecond: {1000, 6}} iex> Duration.new!(month: 2) %Duration{month: 2} ### Duration.subtract/2 (function) Subtracts units of given durations `d1` and `d2`. Respects the the highest microsecond precision of the two. ### Examples - Duration.subtract/2 (function) iex> Duration.subtract(Duration.new!(week: 2, day: 1), Duration.new!(day: 2)) %Duration{week: 2, day: -1} iex> Duration.subtract(Duration.new!(microsecond: {400, 6}), Duration.new!(microsecond: {600, 3})) %Duration{microsecond: {-200, 6}} ### Duration.to_iso8601/1 (function) Converts the given `duration` to an [ISO 8601-2:2019](https://en.wikipedia.org/wiki/ISO_8601) formatted string. This function implements the extension of ISO 8601:2019, allowing weeks to appear between months and days: `P3M3W3D`. ### Examples - Duration.to_iso8601/1 (function) iex> Duration.to_iso8601(Duration.new!(year: 3)) "P3Y" iex> Duration.to_iso8601(Duration.new!(day: 40, hour: 12, minute: 42, second: 12)) "P40DT12H42M12S" iex> Duration.to_iso8601(Duration.new!(second: 30)) "PT30S" iex> Duration.to_iso8601(Duration.new!([])) "PT0S" iex> Duration.to_iso8601(Duration.new!(second: 1, microsecond: {2_200, 3})) "PT1.002S" iex> Duration.to_iso8601(Duration.new!(second: 1, microsecond: {-1_200_000, 4})) "PT-0.2000S" ### Duration.to_string/2 (function) Converts the given `duration` to a human readable representation. ### Options - Duration.to_string/2 (function) * `:units` - the units to be used alongside each duration component. The default units follow the ISO 80000-3 standard: [ year: "a", month: "mo", week: "wk", day: "d", hour: "h", minute: "min", second: "s" ] * `:separator` - a string used to separate the distinct components. Defaults to `" "`. ### Examples - Duration.to_string/2 (function) iex> Duration.to_string(Duration.new!(second: 30)) "30s" iex> Duration.to_string(Duration.new!(day: 40, hour: 12, minute: 42, second: 12)) "40d 12h 42min 12s" By default, this function uses ISO 80000-3 units, which uses "a" for years. But you can customize all units via the units option: iex> Duration.to_string(Duration.new!(year: 3)) "3a" iex> Duration.to_string(Duration.new!(year: 3), units: [year: "y"]) "3y" You may also choose the separator: iex> Duration.to_string(Duration.new!(day: 40, hour: 12, minute: 42, second: 12), separator: ", ") "40d, 12h, 42min, 12s" A duration without components is rendered as "0s": iex> Duration.to_string(Duration.new!([])) "0s" Microseconds are rendered as part of seconds with the appropriate precision: iex> Duration.to_string(Duration.new!(second: 1, microsecond: {2_200, 3})) "1.002s" iex> Duration.to_string(Duration.new!(second: 1, microsecond: {-1_200_000, 4})) "-0.2000s" ### Duration.duration/0 (type) The duration type specifies a `%Duration{}` struct or a keyword list of valid duration unit pairs. ### Duration.t/0 (type) The duration struct type. ### Duration.unit_pair/0 (type) The unit pair type specifies a pair of a valid duration unit key and value. ### Exception (behaviour) Functions for dealing with throw/catch/exit and exceptions. This module also defines the behaviour required by custom exceptions. To define your own, see `defexception/1`. ### Formatting functions - Exception (behaviour) Several functions in this module help format exceptions. Some of these functions expect the stacktrace as argument. The stacktrace is typically available inside catch and rescue by using the `__STACKTRACE__/0` variable. Do not rely on the particular format returned by the functions in this module. They may be changed in future releases in order to better suit Elixir's tool chain. In other words, by using the functions in this module it is guaranteed you will format exceptions as in the current Elixir version being used. ### Exception.blame/2 (callback) Called from `Exception.blame/3` to augment the exception struct. Can be used to collect additional information about the exception or do some additional expensive computation. ### Exception.blame/3 (function) Attaches information to exceptions for extra debugging. This operation is potentially expensive, as it reads data from the file system, parses beam files, evaluates code and so on. If the exception module implements the optional `c:blame/2` callback, it will be invoked to perform the computation. ### Exception.blame_mfa/3 (function) Blames the invocation of the given module, function and arguments. This function will retrieve the available clauses from bytecode and evaluate them against the given arguments. The clauses are returned as a list of `{args, guards}` pairs where each argument and each top-level condition in a guard separated by `and`/`or` is wrapped in a tuple with blame metadata. This function returns either `{:ok, definition, clauses}` or `:error`. Where `definition` is `:def`, `:defp`, `:defmacro` or `:defmacrop`. ### Exception.exception/1 (callback) Receives the arguments given to `raise/2` and returns the exception struct. The default implementation accepts either a set of keyword arguments that is merged into the struct or a string to be used as the exception's message. ### Exception.format/3 (function) Normalizes and formats throw/errors/exits and stacktraces. It relies on `format_banner/3` and `format_stacktrace/1` to generate the final format. If `kind` is `{:EXIT, pid}`, it does not generate a stacktrace, as such exits are retrieved as messages without stacktraces. ### Exception.format_banner/3 (function) Normalizes and formats any throw/error/exit. The message is formatted and displayed in the same format as used by Elixir's CLI. The third argument is the stacktrace which is used to enrich a normalized error with more information. It is only used when the kind is an error. ### Exception.format_exit/1 (function) Formats an exit. It returns a string. Often there are errors/exceptions inside exits. Exits are often wrapped by the caller and provide stacktraces too. This function formats exits in a way to nicely show the exit reason, caller and stacktrace. ### Exception.format_fa/2 (function) Receives an anonymous function and arity and formats it as shown in stacktraces. The arity may also be a list of arguments. ### Examples - Exception.format_fa/2 (function) Exception.format_fa(fn -> nil end, 1) #=> "#Function<...>/1" ### Exception.format_file_line/3 (function) Formats the given `file` and `line` as shown in stacktraces. If any of the values are `nil`, they are omitted. ### Examples - Exception.format_file_line/3 (function) iex> Exception.format_file_line("foo", 1) "foo:1:" iex> Exception.format_file_line("foo", nil) "foo:" iex> Exception.format_file_line(nil, nil) "" ### Exception.format_file_line_column/4 (function) Formats the given `file`, `line`, and `column` as shown in stacktraces. If any of the values are `nil`, they are omitted. ### Examples - Exception.format_file_line_column/4 (function) iex> Exception.format_file_line_column("foo", 1, 2) "foo:1:2:" iex> Exception.format_file_line_column("foo", 1, nil) "foo:1:" iex> Exception.format_file_line_column("foo", nil, nil) "foo:" iex> Exception.format_file_line_column("foo", nil, 2) "foo:" iex> Exception.format_file_line_column(nil, nil, nil) "" ### Exception.format_mfa/3 (function) Receives a module, fun and arity and formats it as shown in stacktraces. The arity may also be a list of arguments. ### Examples - Exception.format_mfa/3 (function) iex> Exception.format_mfa(Foo, :bar, 1) "Foo.bar/1" iex> Exception.format_mfa(Foo, :bar, []) "Foo.bar()" iex> Exception.format_mfa(nil, :bar, []) "nil.bar()" Anonymous functions are reported as -func/arity-anonfn-count-, where func is the name of the enclosing function. Convert to "anonymous fn in func/arity" ### Exception.format_stacktrace/1 (function) Formats the stacktrace. A stacktrace must be given as an argument. If not, the stacktrace is retrieved from `Process.info/2`. ### Exception.format_stacktrace_entry/1 (function) Receives a stacktrace entry and formats it into a string. ### Exception.message/1 (function) Gets the message for an `exception`. ### Exception.message/1 (callback) Receives the exception struct and must return its message. Many exceptions have a message field which by default is accessed by this function. However, if an exception does not have a message field, this function must be explicitly implemented. ### Exception.normalize/3 (function) Normalizes an exception, converting Erlang exceptions to Elixir exceptions. It takes the `kind` spilled by `catch` as an argument and normalizes only `:error`, returning the untouched payload for others. The third argument is the stacktrace which is used to enrich a normalized error with more information. It is only used when the kind is an error. ### Exception.arity_or_args/0 (type) ### Exception.kind/0 (type) The kind handled by formatting functions ### Exception.location/0 (type) ### Exception.non_error_kind/0 (type) ### Exception.stacktrace/0 (type) ### Exception.stacktrace_entry/0 (type) ### Exception.t/0 (type) The exception type ### Float (module) Functions for working with floating-point numbers. For mathematical operations on top of floating-points, see Erlang's [`:math`](`:math`) module. ### Kernel functions - Float (module) There are functions related to floating-point numbers on the `Kernel` module too. Here is a list of them: * `Kernel.round/1`: rounds a number to the nearest integer. * `Kernel.trunc/1`: returns the integer part of a number. ### Known issues - Float (module) There are some very well known problems with floating-point numbers and arithmetic due to the fact most decimal fractions cannot be represented by a floating-point binary and most operations are not exact, but operate on approximations. Those issues are not specific to Elixir, they are a property of floating point representation itself. For example, the numbers 0.1 and 0.01 are two of them, what means the result of squaring 0.1 does not give 0.01 neither the closest representable. Here is what happens in this case: * The closest representable number to 0.1 is 0.1000000014 * The closest representable number to 0.01 is 0.0099999997 * Doing 0.1 * 0.1 should return 0.01, but because 0.1 is actually 0.1000000014, the result is 0.010000000000000002, and because this is not the closest representable number to 0.01, you'll get the wrong result for this operation There are also other known problems like flooring or rounding numbers. See `round/2` and `floor/2` for more details about them. To learn more about floating-point arithmetic visit: * [0.30000000000000004.com](http://0.30000000000000004.com/) * [What Every Programmer Should Know About Floating-Point Arithmetic](https://floating-point-gui.de/) ### Float.ceil/2 (function) Rounds a float to the smallest float greater than or equal to `number`. `ceil/2` also accepts a precision to round a floating-point value down to an arbitrary number of fractional digits (between 0 and 15). The operation is performed on the binary floating point, without a conversion to decimal. The behavior of `ceil/2` for floats can be surprising. For example: iex> Float.ceil(-12.52, 2) -12.51 One may have expected it to ceil to -12.52. This is not a bug. Most decimal fractions cannot be represented as a binary floating point and therefore the number above is internally represented as -12.51999999, which explains the behavior above. This function always returns floats. `Kernel.trunc/1` may be used instead to truncate the result to an integer afterwards. ### Examples - Float.ceil/2 (function) iex> Float.ceil(34.25) 35.0 iex> Float.ceil(-56.5) -56.0 iex> Float.ceil(34.251, 2) 34.26 iex> Float.ceil(-0.01) -0.0 ### Float.floor/2 (function) Rounds a float to the largest float less than or equal to `number`. `floor/2` also accepts a precision to round a floating-point value down to an arbitrary number of fractional digits (between 0 and 15). The operation is performed on the binary floating point, without a conversion to decimal. This function always returns a float. `Kernel.trunc/1` may be used instead to truncate the result to an integer afterwards. ### Known issues - Float.floor/2 (function) The behavior of `floor/2` for floats can be surprising. For example: iex> Float.floor(12.52, 2) 12.51 One may have expected it to floor to 12.52. This is not a bug. Most decimal fractions cannot be represented as a binary floating point and therefore the number above is internally represented as 12.51999999, which explains the behavior above. ### Examples - Float.floor/2 (function) iex> Float.floor(34.25) 34.0 iex> Float.floor(-56.5) -57.0 iex> Float.floor(34.259, 2) 34.25 ### Float.max_finite/0 (function) Returns the maximum finite value for a float. ### Examples - Float.max_finite/0 (function) iex> Float.max_finite() 1.7976931348623157e308 ### Float.min_finite/0 (function) Returns the minimum finite value for a float. ### Examples - Float.min_finite/0 (function) iex> Float.min_finite() -1.7976931348623157e308 ### Float.parse/1 (function) Parses a binary into a float. If successful, returns a tuple in the form of `{float, remainder_of_binary}`; when the binary cannot be coerced into a valid float, the atom `:error` is returned. If the size of float exceeds the maximum size of `1.7976931348623157e+308`, `:error` is returned even though the textual representation itself might be well formed. If you want to convert a string-formatted float directly to a float, `String.to_float/1` can be used instead. ### Examples - Float.parse/1 (function) iex> Float.parse("34") {34.0, ""} iex> Float.parse("34.25") {34.25, ""} iex> Float.parse("56.5xyz") {56.5, "xyz"} iex> Float.parse(".12") :error iex> Float.parse("pi") :error iex> Float.parse("1.7976931348623159e+308") :error ### Float.pow/2 (function) Computes `base` raised to power of `exponent`. `base` must be a float and `exponent` can be any number. However, if a negative base and a fractional exponent are given, it raises `ArithmeticError`. It always returns a float. See `Integer.pow/2` for exponentiation that returns integers. ### Examples - Float.pow/2 (function) iex> Float.pow(2.0, 0) 1.0 iex> Float.pow(2.0, 1) 2.0 iex> Float.pow(2.0, 10) 1024.0 iex> Float.pow(2.0, -1) 0.5 iex> Float.pow(2.0, -3) 0.125 iex> Float.pow(3.0, 1.5) 5.196152422706632 iex> Float.pow(-2.0, 3) -8.0 iex> Float.pow(-2.0, 4) 16.0 iex> Float.pow(-1.0, 0.5) ** (ArithmeticError) bad argument in arithmetic expression ### Float.ratio/1 (function) Returns a pair of integers whose ratio is exactly equal to the original float and with a positive denominator. ### Examples - Float.ratio/1 (function) iex> Float.ratio(0.0) {0, 1} iex> Float.ratio(3.14) {7070651414971679, 2251799813685248} iex> Float.ratio(-3.14) {-7070651414971679, 2251799813685248} iex> Float.ratio(1.5) {3, 2} iex> Float.ratio(-1.5) {-3, 2} iex> Float.ratio(16.0) {16, 1} iex> Float.ratio(-16.0) {-16, 1} ### Float.round/2 (function) Rounds a floating-point value to an arbitrary number of fractional digits (between 0 and 15). The rounding direction always ties to half up. The operation is performed on the binary floating point, without a conversion to decimal. This function only accepts floats and always returns a float. Use `Kernel.round/1` if you want a function that accepts both floats and integers and always returns an integer. ### Known issues - Float.round/2 (function) The behavior of `round/2` for floats can be surprising. For example: iex> Float.round(5.5675, 3) 5.567 One may have expected it to round to the half up 5.568. This is not a bug. Most decimal fractions cannot be represented as a binary floating point and therefore the number above is internally represented as 5.567499999, which explains the behavior above. If you want exact rounding for decimals, you must use a decimal library. The behavior above is also in accordance to reference implementations, such as "Correctly Rounded Binary-Decimal and Decimal-Binary Conversions" by David M. Gay. ### Examples - Float.round/2 (function) iex> Float.round(12.5) 13.0 iex> Float.round(5.5674, 3) 5.567 iex> Float.round(5.5675, 3) 5.567 iex> Float.round(-5.5674, 3) -5.567 iex> Float.round(-5.5675) -6.0 iex> Float.round(12.341444444444441, 15) 12.341444444444441 iex> Float.round(-0.01) -0.0 ### Float.to_charlist/1 (function) Returns a charlist which corresponds to the shortest text representation of the given float. The underlying algorithm changes depending on the Erlang/OTP version: * For OTP >= 24, it uses the algorithm presented in "Ryū: fast float-to-string conversion" in Proceedings of the SIGPLAN '2018 Conference on Programming Language Design and Implementation. * For OTP < 24, it uses the algorithm presented in "Printing Floating-Point Numbers Quickly and Accurately" in Proceedings of the SIGPLAN '1996 Conference on Programming Language Design and Implementation. For a configurable representation, use `:erlang.float_to_list/2`. Inlined by the compiler. ### Examples - Float.to_charlist/1 (function) iex> Float.to_charlist(7.0) ~c"7.0" ### Float.to_string/1 (function) Returns a binary which corresponds to the shortest text representation of the given float. The underlying algorithm changes depending on the Erlang/OTP version: * For OTP >= 24, it uses the algorithm presented in "Ryū: fast float-to-string conversion" in Proceedings of the SIGPLAN '2018 Conference on Programming Language Design and Implementation. * For OTP < 24, it uses the algorithm presented in "Printing Floating-Point Numbers Quickly and Accurately" in Proceedings of the SIGPLAN '1996 Conference on Programming Language Design and Implementation. For a configurable representation, use `:erlang.float_to_binary/2`. Inlined by the compiler. ### Examples - Float.to_string/1 (function) iex> Float.to_string(7.0) "7.0" ### Float.precision_range/0 (type) ### Function (module) A set of functions for working with functions. Anonymous functions are typically created by using `fn`: iex> add = fn a, b -> a + b end iex> add.(1, 2) 3 Anonymous functions can also have multiple clauses. All clauses should expect the same number of arguments: iex> negate = fn ...> true -> false ...> false -> true ...> end iex> negate.(false) true ### The capture operator - Function (module) It is also possible to capture public module functions and pass them around as if they were anonymous functions by using the capture operator `&/1`: iex> add = &Kernel.+/2 iex> add.(1, 2) 3 iex> length = &String.length/1 iex> length.("hello") 5 To capture a definition within the current module, you can skip the module prefix, such as `&my_fun/2`. In those cases, the captured function can be public (`def`) or private (`defp`). The capture operator can also be used to create anonymous functions that expect at least one argument: iex> add = &(&1 + &2) iex> add.(1, 2) 3 In such cases, using the capture operator is no different than using `fn`. ### Internal and external functions - Function (module) We say that functions that point to definitions residing in modules, such as `&String.length/1`, are **external** functions. All other functions are **local** and they are always bound to the file or module that defined them. Besides the functions in this module to work with functions, `Kernel` also has an `apply/2` function that invokes a function with a dynamic number of arguments, as well as `is_function/1` and `is_function/2`, to check respectively if a given value is a function or a function of a given arity. ### Function.capture/3 (function) Captures the given function. Inlined by the compiler. ### Examples - Function.capture/3 (function) iex> Function.capture(String, :length, 1) &String.length/1 ### Function.identity/1 (function) Returns its input `value`. This function can be passed as an anonymous function to transformation functions. ### Examples - Function.identity/1 (function) iex> Function.identity("Hello world!") "Hello world!" iex> ~c"abcdaabccc" |> Enum.sort() |> Enum.chunk_by(&Function.identity/1) [~c"aaa", ~c"bb", ~c"cccc", ~c"d"] iex> Enum.group_by(~c"abracadabra", &Function.identity/1) %{97 => ~c"aaaaa", 98 => ~c"bb", 99 => ~c"c", 100 => ~c"d", 114 => ~c"rr"} iex> Enum.map([1, 2, 3, 4], &Function.identity/1) [1, 2, 3, 4] ### Function.info/1 (function) Returns a keyword list with information about a function. The returned keys (with the corresponding possible values) for all types of functions (local and external) are the following: * `:type` - `:local` (for anonymous functions) or `:external` (for named functions). * `:module` - an atom which is the module where the function is defined when anonymous or the module which the function refers to when it's a named function. * `:arity` - (integer) the number of arguments the function is to be called with. * `:name` - (atom) the name of the function. * `:env` - a list of the environment or free variables. For named functions, the returned list is always empty. When `fun` is an anonymous function (that is, the type is `:local`), the following additional keys are returned: * `:pid` - PID of the process that originally created the function. * `:index` - (integer) an index into the module function table. * `:new_index` - (integer) an index into the module function table. * `:new_uniq` - (binary) a unique value for this function. It's calculated from the compiled code for the entire module. * `:uniq` - (integer) a unique value for this function. This integer is calculated from the compiled code for the entire module. **Note**: this function must be used only for debugging purposes. Inlined by the compiler. ### Examples - Function.info/1 (function) iex> fun = fn x -> x end iex> info = Function.info(fun) iex> Keyword.get(info, :arity) 1 iex> Keyword.get(info, :type) :local iex> fun = &String.length/1 iex> info = Function.info(fun) iex> Keyword.get(info, :type) :external iex> Keyword.get(info, :name) :length ### Function.info/2 (function) Returns a specific information about the function. The returned information is a two-element tuple in the shape of `{info, value}`. For any function, the information asked for can be any of the atoms `:module`, `:name`, `:arity`, `:env`, or `:type`. For anonymous functions, there is also information about any of the atoms `:index`, `:new_index`, `:new_uniq`, `:uniq`, and `:pid`. For a named function, the value of any of these items is always the atom `:undefined`. For more information on each of the possible returned values, see `info/1`. Inlined by the compiler. ### Examples - Function.info/2 (function) iex> f = fn x -> x end iex> Function.info(f, :arity) {:arity, 1} iex> Function.info(f, :type) {:type, :local} iex> fun = &String.length/1 iex> Function.info(fun, :name) {:name, :length} iex> Function.info(fun, :pid) {:pid, :undefined} ### Function.information/0 (type) ### Integer (module) Functions for working with integers. Some functions that work on integers are found in `Kernel`: * `Kernel.abs/1` * `Kernel.div/2` * `Kernel.max/2` * `Kernel.min/2` * `Kernel.rem/2` ### Integer.digits/2 (function) Returns the ordered digits for the given `integer`. An optional `base` value may be provided representing the radix for the returned digits. This one must be an integer >= 2. ### Examples - Integer.digits/2 (function) iex> Integer.digits(123) [1, 2, 3] iex> Integer.digits(170, 2) [1, 0, 1, 0, 1, 0, 1, 0] iex> Integer.digits(-170, 2) [-1, 0, -1, 0, -1, 0, -1, 0] ### Integer.extended_gcd/2 (function) Returns the extended greatest common divisor of the two given integers. This function uses the extended Euclidean algorithm to return a three-element tuple with the `gcd` and the coefficients `m` and `n` of Bézout's identity such that: gcd(a, b) = m*a + n*b By convention, `extended_gcd(0, 0)` returns `{0, 0, 0}`. ### Examples - Integer.extended_gcd/2 (function) iex> Integer.extended_gcd(240, 46) {2, -9, 47} iex> Integer.extended_gcd(46, 240) {2, 47, -9} iex> Integer.extended_gcd(-46, 240) {2, -47, -9} iex> Integer.extended_gcd(-46, -240) {2, -47, 9} iex> Integer.extended_gcd(14, 21) {7, -1, 1} iex> Integer.extended_gcd(10, 0) {10, 1, 0} iex> Integer.extended_gcd(0, 10) {10, 0, 1} iex> Integer.extended_gcd(0, 0) {0, 0, 0} ### Integer.floor_div/2 (function) Performs a floored integer division. Raises an `ArithmeticError` exception if one of the arguments is not an integer, or when the `divisor` is `0`. This function performs a *floored* integer division, which means that the result will always be rounded towards negative infinity. If you want to perform truncated integer division (rounding towards zero), use `Kernel.div/2` instead. ### Examples - Integer.floor_div/2 (function) iex> Integer.floor_div(5, 2) 2 iex> Integer.floor_div(6, -4) -2 iex> Integer.floor_div(-99, 2) -50 ### Integer.gcd/2 (function) Returns the greatest common divisor of the two given integers. The greatest common divisor (GCD) of `integer1` and `integer2` is the largest positive integer that divides both `integer1` and `integer2` without leaving a remainder. By convention, `gcd(0, 0)` returns `0`. ### Examples - Integer.gcd/2 (function) iex> Integer.gcd(2, 3) 1 iex> Integer.gcd(8, 12) 4 iex> Integer.gcd(8, -12) 4 iex> Integer.gcd(10, 0) 10 iex> Integer.gcd(7, 7) 7 iex> Integer.gcd(0, 0) 0 ### Integer.is_even/1 (macro) Determines if an `integer` is even. Returns `true` if the given `integer` is an even number, otherwise it returns `false`. Allowed in guard clauses. ### Examples - Integer.is_even/1 (macro) iex> Integer.is_even(10) true iex> Integer.is_even(5) false iex> Integer.is_even(-10) true iex> Integer.is_even(0) true ### Integer.is_odd/1 (macro) Determines if `integer` is odd. Returns `true` if the given `integer` is an odd number, otherwise it returns `false`. Allowed in guard clauses. ### Examples - Integer.is_odd/1 (macro) iex> Integer.is_odd(5) true iex> Integer.is_odd(6) false iex> Integer.is_odd(-5) true iex> Integer.is_odd(0) false ### Integer.mod/2 (function) Computes the modulo remainder of an integer division. This function performs a [floored division](`floor_div/2`), which means that the result will always have the sign of the `divisor`. Raises an `ArithmeticError` exception if one of the arguments is not an integer, or when the `divisor` is `0`. ### Examples - Integer.mod/2 (function) iex> Integer.mod(5, 2) 1 iex> Integer.mod(6, -4) -2 ### Integer.parse/2 (function) Parses a text representation of an integer. An optional `base` to the corresponding integer can be provided. If `base` is not given, 10 will be used. If successful, returns a tuple in the form of `{integer, remainder_of_binary}`. Otherwise `:error`. Raises an error if `base` is less than 2 or more than 36. If you want to convert a string-formatted integer directly to an integer, `String.to_integer/1` or `String.to_integer/2` can be used instead. ### Examples - Integer.parse/2 (function) iex> Integer.parse("34") {34, ""} iex> Integer.parse("34.5") {34, ".5"} iex> Integer.parse("three") :error iex> Integer.parse("34", 10) {34, ""} iex> Integer.parse("f4", 16) {244, ""} iex> Integer.parse("Awww++", 36) {509216, "++"} iex> Integer.parse("fab", 10) :error iex> Integer.parse("a2", 38) ** (ArgumentError) invalid base 38 ### Integer.pow/2 (function) Computes `base` raised to power of `exponent`. Both `base` and `exponent` must be integers. The exponent must be zero or positive. See `Float.pow/2` for exponentiation of negative exponents as well as floats. ### Examples - Integer.pow/2 (function) iex> Integer.pow(2, 0) 1 iex> Integer.pow(2, 1) 2 iex> Integer.pow(2, 10) 1024 iex> Integer.pow(2, 11) 2048 iex> Integer.pow(2, 64) 0x10000000000000000 iex> Integer.pow(3, 4) 81 iex> Integer.pow(4, 3) 64 iex> Integer.pow(-2, 3) -8 iex> Integer.pow(-2, 4) 16 iex> Integer.pow(2, -2) ** (ArithmeticError) bad argument in arithmetic expression ### Integer.to_charlist/2 (function) Returns a charlist which corresponds to the text representation of `integer` in the given `base`. `base` can be an integer between 2 and 36. If no `base` is given, it defaults to `10`. Inlined by the compiler. ### Examples - Integer.to_charlist/2 (function) iex> Integer.to_charlist(123) ~c"123" iex> Integer.to_charlist(+456) ~c"456" iex> Integer.to_charlist(-789) ~c"-789" iex> Integer.to_charlist(0123) ~c"123" iex> Integer.to_charlist(100, 16) ~c"64" iex> Integer.to_charlist(-100, 16) ~c"-64" iex> Integer.to_charlist(882_681_651, 36) ~c"ELIXIR" ### Integer.to_string/2 (function) Returns a binary which corresponds to the text representation of `integer` in the given `base`. `base` can be an integer between 2 and 36. If no `base` is given, it defaults to `10`. Inlined by the compiler. ### Examples - Integer.to_string/2 (function) iex> Integer.to_string(123) "123" iex> Integer.to_string(+456) "456" iex> Integer.to_string(-789) "-789" iex> Integer.to_string(0123) "123" iex> Integer.to_string(100, 16) "64" iex> Integer.to_string(-100, 16) "-64" iex> Integer.to_string(882_681_651, 36) "ELIXIR" ### Integer.undigits/2 (function) Returns the integer represented by the ordered `digits`. An optional `base` value may be provided representing the radix for the `digits`. Base has to be an integer greater than or equal to `2`. ### Examples - Integer.undigits/2 (function) iex> Integer.undigits([1, 2, 3]) 123 iex> Integer.undigits([1, 4], 16) 20 iex> Integer.undigits([]) 0 ### JSON (module) JSON encoding and decoding. Both encoder and decoder fully conform to [RFC 8259](https://tools.ietf.org/html/rfc8259) and [ECMA 404](https://ecma-international.org/publications-and-standards/standards/ecma-404/) standards. ### Encoding - JSON (module) Elixir built-in data structures are encoded to JSON as follows: | **Elixir** | **JSON** | |------------------------|----------| | `integer() \| float()` | Number | | `true \| false ` | Boolean | | `nil` | Null | | `binary()` | String | | `atom()` | String | | `list()` | Array | | `%{binary() => _}` | Object | | `%{atom() => _}` | Object | | `%{integer() => _}` | Object | You may also implement the `JSON.Encoder` protocol for custom data structures. ### Decoding - JSON (module) Elixir built-in data structures are decoded from JSON as follows: | **JSON** | **Elixir** | |----------|------------------------| | Number | `integer() \| float()` | | Boolean | `true \| false` | | Null | `nil` | | String | `binary()` | | Object | `%{binary() => _}` | ### JSON.decode/1 (function) Decodes the given JSON. Returns `{:ok, decoded}` or `{:error, reason}`. ### Examples - JSON.decode/1 (function) iex> JSON.decode("[null,123,\"string\",{\"key\":\"value\"}]") {:ok, [nil, 123, "string", %{"key" => "value"}]} ### Error reasons - JSON.decode/1 (function) The error tuple will have one of the following reasons. * `{:unexpected_end, offset}` if `binary` contains incomplete JSON value * `{:invalid_byte, offset, byte}` if `binary` contains unexpected byte or invalid UTF-8 byte * `{:unexpected_sequence, offset, bytes}` if `binary` contains invalid UTF-8 escape ### JSON.decode/3 (function) Decodes the given JSON with the given decoders. Returns `{decoded, acc, rest}` or `{:error, reason}`. See `decode/1` for the error reasons. ### Decoders - JSON.decode/3 (function) All decoders are optional. If not provided, they will fall back to implementations used by the `decode/1` function: * for `array_start`: `fn _ -> [] end` * for `array_push`: `fn elem, acc -> [elem | acc] end` * for `array_finish`: `fn acc, old_acc -> {Enum.reverse(acc), old_acc} end` * for `object_start`: `fn _ -> [] end` * for `object_push`: `fn key, value, acc -> [{key, value} | acc] end` * for `object_finish`: `fn acc, old_acc -> {Map.new(acc), old_acc} end` * for `float`: `&String.to_float/1` * for `integer`: `&String.to_integer/1` * for `string`: `&Function.identity/1` * for `null`: the atom `nil` For streaming decoding, see Erlang's `:json` module. ### JSON.decode!/1 (function) Decodes the given JSON but raises an exception in case of errors. Returns the decoded content. See `decode/1` for possible errors. ### Examples - JSON.decode!/1 (function) iex> JSON.decode!("[null,123,\"string\",{\"key\":\"value\"}]") [nil, 123, "string", %{"key" => "value"}] ### JSON.encode!/2 (function) Encodes the given term to JSON as a binary. The second argument is a function that is recursively invoked to encode a term. ### Examples - JSON.encode!/2 (function) iex> JSON.encode!([123, "string", %{key: "value"}]) "[123,\"string\",{\"key\":\"value\"}]" ### JSON.encode_to_iodata!/2 (function) Encodes the given term to JSON as an iodata. This is the most efficient format if the JSON is going to be used for IO purposes. The second argument is a function that is recursively invoked to encode a term. ### Examples - JSON.encode_to_iodata!/2 (function) iex> data = JSON.encode_to_iodata!([123, "string", %{key: "value"}]) iex> IO.iodata_to_binary(data) "[123,\"string\",{\"key\":\"value\"}]" ### JSON.protocol_encode/2 (function) This is the default encode implementation passed to `encode!/1`. This function is most typically passed as second argument to `encode!/2` and `encode_to_iodata!/2`. The default implementation is an optimized dispatch to the `JSON.Encoder` protocol. ### JSON.decode_error_reason/0 (type) ### Module (behaviour) Provides functions to deal with modules during compilation time. It allows a developer to dynamically add, delete and register attributes, attach documentation and so forth. After a module is compiled, using many of the functions in this module will raise errors, since it is out of their scope to inspect runtime data. Most of the runtime data can be inspected via the [`__info__/1`](`c:Module.__info__/1`) function attached to each compiled module. ### Module attributes - Module (behaviour) Each module can be decorated with one or more attributes. The following ones are currently defined by Elixir: ### `@after_compile` A hook that will be invoked right after the current module is compiled. Accepts a module or a `{module, function_name}`. See the "Compile callbacks" section below. ### `@after_verify` (since v1.14.0) A hook that will be invoked right after the current module is verified for undefined functions, deprecations, etc. Accepts a module or a `{module, function_name}`. See the "Compile callbacks" section below. ### `@before_compile` A hook that will be invoked before the module is compiled. Accepts a module or a `{module, function_or_macro_name}` tuple. See the "Compile callbacks" section below. ### `@behaviour` Note the British spelling! Behaviours can be referenced by modules to ensure they implement required specific function signatures defined by `@callback`. For example, you could specify a `URI.Parser` behaviour as follows: defmodule URI.Parser do @doc "Defines a default port" @callback default_port() :: integer @doc "Parses the given URL" @callback parse(uri_info :: URI.t()) :: URI.t() end And then a module may use it as: defmodule URI.HTTP do @behaviour URI.Parser def default_port(), do: 80 def parse(info), do: info end If the behaviour changes or `URI.HTTP` does not implement one of the callbacks, a warning will be raised. For detailed documentation, see the [behaviour typespec documentation](typespecs.md#behaviours). ### `@impl` (since v1.5.0) To aid in the correct implementation of behaviours, you may optionally declare `@impl` for implemented callbacks of a behaviour. This makes callbacks explicit and can help you to catch errors in your code. The compiler will warn in these cases: * if you mark a function with `@impl` when that function is not a callback. * if you don't mark a function with `@impl` when other functions are marked with `@impl`. If you mark one function with `@impl`, you must mark all other callbacks for that behaviour as `@impl`. `@impl` works on a per-context basis. If you generate a function through a macro and mark it with `@impl`, that won't affect the module where that function is generated in. `@impl` also helps with maintainability by making it clear to other developers that the function is implementing a callback. Using `@impl`, the example above can be rewritten as: defmodule URI.HTTP do @behaviour URI.Parser @impl true def default_port(), do: 80 @impl true def parse(info), do: info end You may pass either `false`, `true`, or a specific behaviour to `@impl`. defmodule Foo do @behaviour Bar @behaviour Baz # Will warn if neither Bar nor Baz specify a callback named bar/0. @impl true def bar(), do: :ok # Will warn if Baz does not specify a callback named baz/0. @impl Baz def baz(), do: :ok end The code is now more readable, as it is now clear which functions are part of your API and which ones are callback implementations. To reinforce this idea, `@impl true` automatically marks the function as `@doc false`, disabling documentation unless `@doc` is explicitly set. ### `@compile` Defines options for module compilation. This is used to configure both Elixir and Erlang compilers, as any other compilation pass added by external tools. For example: defmodule MyModule do @compile {:inline, my_fun: 1} def my_fun(arg) do to_string(arg) end end Multiple uses of `@compile` will accumulate instead of overriding previous ones. See the "Compile options" section below. ### `@deprecated` (since v1.6.0) Provides the deprecation reason for a function. For example: defmodule Keyword do @deprecated "Use Kernel.length/1 instead" def size(keyword) do length(keyword) end end The Mix compiler automatically looks for calls to deprecated modules and emit warnings during compilation. Using the `@deprecated` attribute will also be reflected in the documentation of the given function and macro. You can choose between the `@deprecated` attribute and the documentation metadata to provide hard-deprecations (with warnings) and soft-deprecations (without warnings): This is a soft-deprecation as it simply annotates the documentation as deprecated: @doc deprecated: "Use Kernel.length/1 instead" def size(keyword) This is a hard-deprecation as it emits warnings and annotates the documentation as deprecated: @deprecated "Use Kernel.length/1 instead" def size(keyword) Currently `@deprecated` only supports functions and macros. However you can use the `:deprecated` key in the annotation metadata to annotate the docs of modules, types and callbacks too. We recommend using this feature with care, especially library authors. Deprecating code always pushes the burden towards library users. We also recommend for deprecated functionality to be maintained for long periods of time, even after deprecation, giving developers plenty of time to update (except for cases where keeping the deprecated API is undesired, such as in the presence of security issues). ### `@doc` and `@typedoc` Provides documentation for the entity that follows the attribute. `@doc` is to be used with a function, macro, callback, or macrocallback, while `@typedoc` with a type (public or opaque). Accepts one of these: * a string (often a heredoc) * `false`, which will make the entity invisible to documentation-extraction tools like [`ExDoc`](https://hexdocs.pm/ex_doc/) * a keyword list, since Elixir 1.7.0 For example: defmodule MyModule do @typedoc "This type" @typedoc since: "1.1.0" @type t :: term @doc "Hello world" @doc since: "1.1.0" def hello do "world" end @doc """ Sums `a` to `b`. """ def sum(a, b) do a + b end end As can be seen in the example above, since Elixir 1.7.0 `@doc` and `@typedoc` also accept a keyword list that serves as a way to provide arbitrary metadata about the entity. Tools like [`ExDoc`](https://hexdocs.pm/ex_doc/) and `IEx` may use this information to display annotations. A common use case is the `:since` key, which may be used to annotate in which version the function was introduced. As illustrated in the example, it is possible to use these attributes more than once before an entity. However, the compiler will warn if used twice with binaries as that replaces the documentation text from the preceding use. Multiple uses with keyword lists will merge the lists into one. Note that since the compiler also defines some additional metadata, there are a few reserved keys that will be ignored and warned if used. Currently these are: `:opaque` and `:defaults`. Once this module is compiled, this information becomes available via the `Code.fetch_docs/1` function. ### `@dialyzer` Defines warnings to request or suppress when using `:dialyzer`. Accepts an atom, a tuple, or a list of atoms and tuples. For example: defmodule MyModule do @dialyzer {:nowarn_function, [my_fun: 1]} def my_fun(arg) do M.not_a_function(arg) end end For the list of supported warnings, see [`:dialyzer` module](`:dialyzer`). Multiple uses of `@dialyzer` will accumulate instead of overriding previous ones. ### `@external_resource` Specifies an external resource for the current module. Sometimes a module embeds information from an external file. This attribute allows the module to annotate which external resources have been used. Tools may use this information to ensure the module is recompiled in case any of the external resources change, see for example: [`mix compile.elixir`](https://hexdocs.pm/mix/Mix.Tasks.Compile.Elixir.html). The specified file path provided is interpreted as relative to the folder containing the project's `mix.exs`, which is the current working directory, not the file where `@external_resource` is declared. If the external resource does not exist, the module still has a dependency on it, causing the module to be recompiled as soon as the file is added. For more control over when a module is recompiled, see [`__mix_recompile__?/0`](`m:Mix.Tasks.Compile.Elixir#module-__mix_recompile__-0`). ### `@file` Changes the filename used in stacktraces for the function or macro that follows the attribute, such as: defmodule MyModule do @doc "Hello world" @file "hello.ex" def hello do "world" end end Note that this is only valid for exceptions/diagnostics that come from the definition inner scope (which includes its patterns and guards). For example: defmodule MyModule do # <---- module definition @file "hello.ex" defp unused(a) do # <---- function definition "world" # <---- function scope end @file "bye.ex" def unused(_), do: true end If you run this code with the second "unused" definition commented, you will see that `hello.ex` is used as the stacktrace when reporting warnings, but if you uncomment it you'll see that the error will not mention `bye.ex`, because it's a module-level error rather than an expression-level error. ### `@moduledoc` Provides documentation for the current module. defmodule MyModule do @moduledoc """ A very useful module. """ @moduledoc authors: ["Alice", "Bob"] end Accepts a string (often a heredoc) or `false` where `@moduledoc false` will make the module invisible to documentation extraction tools like [`ExDoc`](https://hexdocs.pm/ex_doc/). Similarly to `@doc` also accepts a keyword list to provide metadata about the module. For more details, see the documentation of `@doc` above. Once this module is compiled, this information becomes available via the `Code.fetch_docs/1` function. ### `@nifs` (since v1.16.0) A list of functions and their arities which will be overridden by a native implementation (NIF). defmodule MyLibrary.MyModule do @nifs [foo: 1, bar: 2] def foo(arg1), do: :erlang.nif_error(:not_loaded) def bar(arg1, arg2), do: :erlang.nif_error(:not_loaded) end See the Erlang documentation for more information: https://www.erlang.org/doc/man/erl_nif ### `@on_definition` A hook that will be invoked when each function or macro in the current module is defined. Useful when annotating functions. Accepts a module or a `{module, function_name}` tuple. The function must take 6 arguments: * the module environment * the kind of the function/macro: `:def`, `:defp`, `:defmacro`, or `:defmacrop` * the function/macro name * the list of quoted arguments * the list of quoted guards * the quoted function body If the function/macro being defined has multiple clauses, the hook will be called for each clause. Unlike other hooks, `@on_definition` will only invoke functions and never macros. This is to avoid `@on_definition` callbacks from redefining functions that have just been defined in favor of more explicit approaches. When just a module is provided, the function is assumed to be `__on_definition__/6`. #### Example defmodule Hooks do def on_def(_env, kind, name, args, guards, body) do IO.puts("Defining #{kind} named #{name} with args:") IO.inspect(args) IO.puts("and guards") IO.inspect(guards) IO.puts("and body") IO.puts(Macro.to_string(body)) end end defmodule MyModule do @on_definition {Hooks, :on_def} def hello(arg) when is_binary(arg) or is_list(arg) do "Hello" <> to_string(arg) end def hello(_) do :ok end end ### `@on_load` A hook that will be invoked whenever the module is loaded. Accepts the function name (as an atom) of a function in the current module. The function must have an arity of 0 (no arguments). If the function does not return `:ok`, the loading of the module will be aborted. For example: defmodule MyModule do @on_load :load_check def load_check do if some_condition() do :ok else :abort end end def some_condition do false end end ### `@vsn` Specify the module version. Accepts any valid Elixir value, for example: defmodule MyModule do @vsn "1.0" end ### Struct attributes - Module (behaviour) * `@derive` - derives an implementation for the given protocol for the struct defined in the current module * `@enforce_keys` - ensures the given keys are always set when building the struct defined in the current module See `defstruct/1` for more information on building and using structs. ### Typespec attributes - Module (behaviour) The following attributes are part of typespecs and are also built-in in Elixir: * `@type` - defines a type to be used in `@spec` * `@typep` - defines a private type to be used in `@spec` * `@opaque` - defines an opaque type to be used in `@spec` * `@spec` - provides a specification for a function * `@callback` - provides a specification for a behaviour callback (and generates a `behaviour_info/1` function in the module, see below) * `@macrocallback` - provides a specification for a macro behaviour callback * `@optional_callbacks` - specifies which behaviour callbacks and macro behaviour callbacks are optional * `@impl` - declares an implementation of a callback function or macro For detailed documentation, see the [typespec documentation](typespecs.md). ### Custom attributes - Module (behaviour) In addition to the built-in attributes outlined above, custom attributes may also be added. Custom attributes are expressed using the `@/1` operator followed by a valid variable name. The value given to the custom attribute must be a valid Elixir value: defmodule MyModule do @custom_attr [some: "stuff"] end For more advanced options available when defining custom attributes, see `register_attribute/3`. ### Compile callbacks - Module (behaviour) There are three compilation callbacks, invoked in this order: `@before_compile`, `@after_compile`, and `@after_verify`. They are described next. ### `@before_compile` A hook that will be invoked before the module is compiled. This is often used to change how the current module is being compiled. Accepts a module or a `{module, function_or_macro_name}` tuple. The function/macro must take one argument: the module environment. If it's a macro, its returned value will be injected at the end of the module definition before the compilation starts. When just a module is provided, the function/macro is assumed to be `__before_compile__/1`. Callbacks will run in the order they are registered. Any overridable definition will be made concrete before the first callback runs. A definition may be made overridable again in another before compile callback and it will be made concrete one last time after all callbacks run. *Note*: the callback function/macro must be placed in a separate module (because when the callback is invoked, the current module does not yet exist). #### Example defmodule A do defmacro __before_compile__(_env) do quote do def hello, do: "world" end end end defmodule B do @before_compile A end B.hello() #=> "world" ### `@after_compile` A hook that will be invoked right after the current module is compiled. Accepts a module or a `{module, function_name}` tuple. The function must take two arguments: the module environment and its bytecode. When just a module is provided, the function is assumed to be `__after_compile__/2`. Callbacks will run in the order they are registered. `Module` functions expecting not yet compiled modules (such as `definitions_in/1`) are still available at the time `@after_compile` is invoked. #### Example defmodule MyModule do @after_compile __MODULE__ def __after_compile__(env, _bytecode) do IO.inspect(env) end end ### `@after_verify` A hook that will be invoked right after the current module is verified for undefined functions, deprecations, etc. A module is always verified after it is compiled. In Mix projects, a module is also verified when any of its runtime dependencies change. Therefore this is useful to perform verification of the current module while avoiding compile-time dependencies. Given the callback is invoked under different scenarios, Elixir provides no guarantees of when in the compilation cycle nor in which process the callback runs. Accepts a module or a `{module, function_name}` tuple. The function must take one argument: the module name. When just a module is provided, the function is assumed to be `__after_verify__/1`. Callbacks will run in the order they are registered. `Module` functions expecting not yet compiled modules are no longer available at the time `@after_verify` is invoked. #### Example defmodule MyModule do @after_verify __MODULE__ def __after_verify__(module) do IO.inspect(module) :ok end end ### Compile options - Module (behaviour) The `@compile` attribute accepts different options that are used by both Elixir and Erlang compilers. Some of the common use cases are documented below: * `@compile :debug_info` - includes `:debug_info` regardless of the corresponding setting in `Code.get_compiler_option/1` * `@compile {:debug_info, false}` - disables `:debug_info` regardless of the corresponding setting in `Code.get_compiler_option/1`. Note disabling `:debug_info` is not recommended as it removes the ability of the Elixir compiler and other tools to static analyse the code. If you want to remove the `:debug_info` while deploying, tools like `mix release` already do such by default. * `@compile {:inline, some_fun: 2, other_fun: 3}` - inlines the given name/arity pairs. Inlining is applied locally, calls from another module are not affected by this option * `@compile {:autoload, false}` - disables automatic loading of modules after compilation. Instead, the module will be loaded after it is dispatched to * `@compile {:no_warn_undefined, Mod}` or `@compile {:no_warn_undefined, {Mod, fun, arity}}` - does not warn if the given module or the given `Mod.fun/arity` are not defined ### Generated functions - Module (behaviour) Sometimes the compiler will generate public functions within modules. These are documented below. ### `behaviour_info/1` This function is generated for modules that define a behaviour, that is, that have one or more `@callback` definitions. The signature for this function, expressed as a spec, is: @spec behaviour_info(:callbacks) :: [function_info] when function_info: {function_name :: atom(), arity :: non_neg_integer()} @spec behaviour_info(:optional_callbacks) :: [function_info] when function_info: {function_name :: atom(), arity :: non_neg_integer()} `behaviour_info(:callbacks)` includes optional callbacks. For example: iex> Enum.sort(GenServer.behaviour_info(:callbacks)) [ code_change: 3, format_status: 1, format_status: 2, handle_call: 3, handle_cast: 2, handle_continue: 2, handle_info: 2, init: 1, terminate: 2 ] ### `module_info/0` This function is generated for all modules. It returns all the attributes returned by `module_info/1` (see below), but as a single keyword list. See also the [Erlang documentation](https://www.erlang.org/doc/system/modules.html#module_info-0). ### `module_info/1` This function is generated for all modules and returns information about the module. The signature for this function, expressed as a spec, is: @spec module_info(:module) :: module() # Returns the module itself @spec module_info(:attributes) :: keyword() @spec module_info(:compile) :: keyword() @spec module_info(:md5) :: binary() @spec module_info(:nifs) :: module() @spec module_info(:exports) :: [function_info] when function_info: {function_name :: atom(), arity :: non_neg_integer()} @spec module_info(:functions) :: [function_info] when function_info: {function_name :: atom(), arity :: non_neg_integer()} For example: iex> URI.module_info(:module) URI iex> {:decode_www_form, 1} in URI.module_info(:exports) true For more information about `module_info/1`, also check out the [Erlang documentation](https://www.erlang.org/doc/system/modules.html#module_info-1). ### `__info__/1` This function is generated for all modules. It's similar to `module_info/1` but includes some additional Elixir-specific information, such as struct and macro information. For documentation, see `c:Module.__info__/1`. ### Module.__info__/1 (callback) Provides runtime information about functions, macros, and other information defined by the module. Each module gets an `__info__/1` function when it's compiled. The function takes one of the following items: * `:attributes` - a keyword list with all persisted attributes * `:compile` - a list with compiler metadata * `:functions` - a keyword list of public functions and their arities * `:macros` - a keyword list of public macros and their arities * `:md5` - the MD5 of the module * `:module` - the module atom name * `:struct` - (since v1.14.0) if the module defines a struct and if so each field in order ### Module.attributes_in/1 (function) Returns all module attributes names defined in `module`. This function can only be used on modules that have not yet been compiled. ### Examples - Module.attributes_in/1 (function) defmodule Example do @foo 1 Module.register_attribute(__MODULE__, :bar, accumulate: true) :foo in Module.attributes_in(__MODULE__) #=> true :bar in Module.attributes_in(__MODULE__) #=> true end ### Module.concat/1 (function) Concatenates a list of aliases and returns a new alias. It handles binaries and atoms. ### Examples - Module.concat/1 (function) iex> Module.concat([Foo, Bar]) Foo.Bar iex> Module.concat([Foo, "Bar"]) Foo.Bar ### Module.concat/2 (function) Concatenates two aliases and returns a new alias. It handles binaries and atoms. ### Examples - Module.concat/2 (function) iex> Module.concat(Foo, Bar) Foo.Bar iex> Module.concat(Foo, "Bar") Foo.Bar ### Module.create/3 (function) Creates a module with the given name and defined by the given quoted expressions. The line where the module is defined and its file **must** be passed as options. See `Code.env_for_eval/1` for a complete list of options. It returns a tuple of shape `{:module, module, binary, term}` where `module` is the module name, `binary` is the module bytecode and `term` is the result of the last expression in `quoted`. Similar to `Kernel.defmodule/2`, the binary will only be written to disk as a `.beam` file if `Module.create/3` is invoked in a file that is currently being compiled. ### Examples - Module.create/3 (function) contents = quote do def world, do: true end Module.create(Hello, contents, Macro.Env.location(__ENV__)) Hello.world() #=> true ### Differences from `defmodule` - Module.create/3 (function) `Module.create/3` works similarly to `Kernel.defmodule/2` and return the same results. While one could also use `Kernel.defmodule/2` to define modules dynamically, this function is preferred when the module body is given by a quoted expression. Another important distinction is that `Module.create/3` allows you to control the environment variables used when defining the module, while `Kernel.defmodule/2` automatically uses the environment it is invoked at. ### Module.defines?/2 (function) Checks if the module defines the given function or macro. Use `defines?/3` to assert for a specific type. This function can only be used on modules that have not yet been compiled. Use `Kernel.function_exported?/3` and `Kernel.macro_exported?/3` to check for public functions and macros respectively in compiled modules. Note that `defines?` returns `false` for functions and macros that have been defined but then marked as overridable and no other implementation has been provided. You can check the overridable status by calling `overridable?/2`. ### Examples - Module.defines?/2 (function) defmodule Example do Module.defines?(__MODULE__, {:version, 0}) #=> false def version, do: 1 Module.defines?(__MODULE__, {:version, 0}) #=> true end ### Module.defines?/3 (function) Checks if the module defines a function or macro of the given `kind`. `kind` can be any of `:def`, `:defp`, `:defmacro`, or `:defmacrop`. This function can only be used on modules that have not yet been compiled. Use `Kernel.function_exported?/3` and `Kernel.macro_exported?/3` to check for public functions and macros respectively in compiled modules. ### Examples - Module.defines?/3 (function) defmodule Example do Module.defines?(__MODULE__, {:version, 0}, :def) #=> false def version, do: 1 Module.defines?(__MODULE__, {:version, 0}, :def) #=> true end ### Module.defines_type?/2 (function) Checks if the current module defines the given type (private, opaque or not). This function is only available for modules being compiled. ### Module.definitions_in/1 (function) Returns all functions and macros defined in `module`. It returns a list with all defined functions and macros, public and private, in the shape of `[{name, arity}, ...]`. This function can only be used on modules that have not yet been compiled. Use the `c:Module.__info__/1` callback to get the public functions and macros in compiled modules. ### Examples - Module.definitions_in/1 (function) defmodule Example do def version, do: 1 defmacrop test(arg), do: arg Module.definitions_in(__MODULE__) #=> [{:version, 0}, {:test, 1}] end ### Module.definitions_in/2 (function) Returns all functions defined in `module`, according to its kind. This function can only be used on modules that have not yet been compiled. Use the `c:Module.__info__/1` callback to get the public functions and macros in compiled modules. ### Examples - Module.definitions_in/2 (function) defmodule Example do def version, do: 1 Module.definitions_in(__MODULE__, :def) #=> [{:version, 0}] Module.definitions_in(__MODULE__, :defp) #=> [] end ### Module.delete_attribute/2 (function) Deletes the entry (or entries) for the given module attribute. It returns the deleted attribute value. If the attribute has not been set nor configured to accumulate, it returns `nil`. If the attribute is set to accumulate, then this function always returns a list. Deleting the attribute removes existing entries but the attribute will still accumulate. ### Examples - Module.delete_attribute/2 (function) defmodule MyModule do Module.put_attribute(__MODULE__, :custom_threshold_for_lib, 10) Module.delete_attribute(__MODULE__, :custom_threshold_for_lib) end ### Module.delete_definition/2 (function) Deletes a definition from a module. It returns `true` if the definition exists and it was removed, otherwise it returns `false`. ### Module.eval_quoted/4 (function) ### Module.get_attribute/3 (function) Gets the given attribute from a module. If the attribute was marked with `accumulate` with `Module.register_attribute/3`, a list is always returned. `nil` is returned if the attribute has not been marked with `accumulate` and has not been set to any value. The `@` macro compiles to a call to this function. For example, the following code: @foo Expands to something akin to: Module.get_attribute(__MODULE__, :foo) This function can only be used on modules that have not yet been compiled. Use the `c:Module.__info__/1` callback to get all persisted attributes, or `Code.fetch_docs/1` to retrieve all documentation related attributes in compiled modules. ### Examples - Module.get_attribute/3 (function) defmodule Foo do Module.put_attribute(__MODULE__, :value, 1) Module.get_attribute(__MODULE__, :value) #=> 1 Module.get_attribute(__MODULE__, :value, :default) #=> 1 Module.get_attribute(__MODULE__, :not_found, :default) #=> :default Module.register_attribute(__MODULE__, :value, accumulate: true) Module.put_attribute(__MODULE__, :value, 1) Module.get_attribute(__MODULE__, :value) #=> [1] end ### Module.get_definition/3 (function) Returns the definition for the given name-arity pair. It returns a tuple with the `version`, the `kind`, the definition `metadata`, and a list with each clause. Each clause is a four-element tuple with metadata, the arguments, the guards, and the clause AST. The clauses are returned in the Elixir AST but a subset that has already been expanded and normalized. This makes it useful for analyzing code but it cannot be reinjected into the module as it will have lost some of its original context. Given this AST representation is mostly internal, it is versioned and it may change at any time. Therefore, **use this API with caution**. ### Options - Module.get_definition/3 (function) * `:skip_clauses` (since v1.14.0) - returns `[]` instead of returning the clauses. This is useful when there is only an interest in fetching the kind and the metadata ### Module.get_last_attribute/3 (function) Gets the last set value of a given attribute from a module. If the attribute was marked with `accumulate` with `Module.register_attribute/3`, the previous value to have been set will be returned. If the attribute does not accumulate, this call is the same as calling `Module.get_attribute/3`. This function can only be used on modules that have not yet been compiled. Use the `c:Module.__info__/1` callback to get all persisted attributes, or `Code.fetch_docs/1` to retrieve all documentation related attributes in compiled modules. ### Examples - Module.get_last_attribute/3 (function) defmodule Foo do Module.put_attribute(__MODULE__, :value, 1) Module.get_last_attribute(__MODULE__, :value) #=> 1 Module.get_last_attribute(__MODULE__, :not_found, :default) #=> :default Module.register_attribute(__MODULE__, :acc, accumulate: true) Module.put_attribute(__MODULE__, :acc, 1) Module.get_last_attribute(__MODULE__, :acc) #=> 1 Module.put_attribute(__MODULE__, :acc, 2) Module.get_last_attribute(__MODULE__, :acc) #=> 2 end ### Module.has_attribute?/2 (function) Checks if the given attribute has been defined. An attribute is defined if it has been registered with `register_attribute/3` or assigned a value. If an attribute has been deleted with `delete_attribute/2` it is no longer considered defined. This function can only be used on modules that have not yet been compiled. ### Examples - Module.has_attribute?/2 (function) defmodule MyModule do @value 1 Module.register_attribute(__MODULE__, :other_value) Module.put_attribute(__MODULE__, :another_value, 1) Module.has_attribute?(__MODULE__, :value) #=> true Module.has_attribute?(__MODULE__, :other_value) #=> true Module.has_attribute?(__MODULE__, :another_value) #=> true Module.has_attribute?(__MODULE__, :undefined) #=> false Module.delete_attribute(__MODULE__, :value) Module.has_attribute?(__MODULE__, :value) #=> false end ### Module.make_overridable/2 (function) Makes the given functions in `module` overridable. An overridable function is lazily defined, allowing a developer to customize it. See `Kernel.defoverridable/1` for more information and documentation. Once a function or a macro is marked as overridable, it will no longer be listed under `definitions_in/1` or return true when given to `defines?/2` until another implementation is given. ### Module.open?/1 (function) Checks if a module is open. A module is "open" if it is currently being defined and its attributes and functions can be modified. ### Module.overridable?/2 (function) Returns `true` if `tuple` in `module` was marked as overridable at some point. Note `overridable?/2` returns `true` even if the definition was already overridden. You can use `defines?/2` to see if a definition exists or one is pending. ### Module.overridables_in/1 (function) Returns all overridable definitions in `module`. Note a definition is included even if it was was already overridden. You can use `defines?/2` to see if a definition exists or one is pending. This function can only be used on modules that have not yet been compiled. ### Examples - Module.overridables_in/1 (function) defmodule Example do def foo, do: 1 def bar, do: 2 defoverridable foo: 0, bar: 0 def foo, do: 3 [bar: 0, foo: 0] = Module.overridables_in(__MODULE__) |> Enum.sort() end ### Module.put_attribute/3 (function) Puts a module attribute with `key` and `value` in the given `module`. ### Examples - Module.put_attribute/3 (function) defmodule MyModule do Module.put_attribute(__MODULE__, :custom_threshold_for_lib, 10) end ### Module.register_attribute/3 (function) Registers an attribute. By registering an attribute, a developer is able to customize how Elixir will store and accumulate the attribute values. ### Options - Module.register_attribute/3 (function) When registering an attribute, two options can be given: * `:accumulate` - several calls to the same attribute will accumulate instead of overriding the previous one. New attributes are always added to the top of the accumulated list. * `:persist` - the attribute will be persisted in the Erlang Abstract Format. Useful when interfacing with Erlang libraries. By default, both options are `false`. Once an attribute has been set to accumulate or persist, the behaviour cannot be reverted. ### Examples - Module.register_attribute/3 (function) defmodule MyModule do Module.register_attribute(__MODULE__, :custom_threshold_for_lib, accumulate: true) @custom_threshold_for_lib 10 @custom_threshold_for_lib 20 @custom_threshold_for_lib #=> [20, 10] end ### Module.reserved_attributes/0 (function) Returns information about module attributes used by Elixir. See the "Module attributes" section in the module documentation for more information on each attribute. ### Examples - Module.reserved_attributes/0 (function) iex> map = Module.reserved_attributes() iex> Map.has_key?(map, :moduledoc) true iex> Map.has_key?(map, :doc) true ### Module.safe_concat/1 (function) Concatenates a list of aliases and returns a new alias only if the alias was already referenced. If the alias was not referenced yet, fails with `ArgumentError`. It handles binaries and atoms. ### Examples - Module.safe_concat/1 (function) iex> Module.safe_concat([List, Chars]) List.Chars ### Module.safe_concat/2 (function) Concatenates two aliases and returns a new alias only if the alias was already referenced. If the alias was not referenced yet, fails with `ArgumentError`. It handles binaries and atoms. ### Examples - Module.safe_concat/2 (function) iex> Module.safe_concat(List, Chars) List.Chars ### Module.spec_to_callback/2 (function) Copies the given spec as a callback. Returns `true` if there is such a spec and it was copied as a callback. If the function associated to the spec has documentation defined prior to invoking this function, the docs are copied too. ### Module.split/1 (function) Splits the given module name into binary parts. `module` has to be an Elixir module, as `split/1` won't work with Erlang-style modules (for example, `split(:lists)` raises an error). `split/1` also supports splitting the string representation of Elixir modules (that is, the result of calling `Atom.to_string/1` with the module name). ### Examples - Module.split/1 (function) iex> Module.split(Very.Long.Module.Name.And.Even.Longer) ["Very", "Long", "Module", "Name", "And", "Even", "Longer"] iex> Module.split("Elixir.String.Chars") ["String", "Chars"] ### Module.def_kind/0 (type) ### Module.definition/0 (type) ### NaiveDateTime (module) A NaiveDateTime struct (without a time zone) and functions. The NaiveDateTime struct contains the fields year, month, day, hour, minute, second, microsecond and calendar. New naive datetimes can be built with the `new/2` and `new/8` functions or using the `~N` (see `sigil_N/2`) sigil: iex> ~N[2000-01-01 23:00:07] ~N[2000-01-01 23:00:07] The date and time fields in the struct can be accessed directly: iex> naive = ~N[2000-01-01 23:00:07] iex> naive.year 2000 iex> naive.second 7 We call them "naive" because this datetime representation does not have a time zone. This means the datetime may not actually exist in certain areas in the world even though it is valid. For example, when daylight saving changes are applied by a region, the clock typically moves forward or backward by one hour. This means certain datetimes never occur or may occur more than once. Since `NaiveDateTime` is not validated against a time zone, such errors would go unnoticed. Developers should avoid creating the NaiveDateTime structs directly and instead, rely on the functions provided by this module as well as the ones in third-party calendar libraries. ### Comparing naive date times - NaiveDateTime (module) Comparisons in Elixir using `==/2`, `>/2`, ` Enum.min([~N[2020-01-01 23:00:07], ~N[2000-01-01 23:00:07]], NaiveDateTime) ~N[2000-01-01 23:00:07] ### Using epochs - NaiveDateTime (module) The `add/3` and `diff/3` functions can be used for computing date times or retrieving the number of seconds between instants. For example, if there is an interest in computing the number of seconds from the Unix epoch (1970-01-01 00:00:00): iex> NaiveDateTime.diff(~N[2010-04-17 14:00:00], ~N[1970-01-01 00:00:00]) 1271512800 iex> NaiveDateTime.add(~N[1970-01-01 00:00:00], 1_271_512_800) ~N[2010-04-17 14:00:00] Those functions are optimized to deal with common epochs, such as the Unix Epoch above or the Gregorian Epoch (0000-01-01 00:00:00). ### NaiveDateTime.add/3 (function) Adds a specified amount of time to a `NaiveDateTime`. Accepts an `amount_to_add` in any `unit`. `unit` can be `:day`, `:hour`, `:minute`, `:second` or any subsecond precision from `t:System.time_unit/0`. It defaults to `:second`. Negative values will move backwards in time. This function always consider the unit to be computed according to the `Calendar.ISO`. ### Examples - NaiveDateTime.add/3 (function) It uses seconds by default: # adds seconds by default iex> NaiveDateTime.add(~N[2014-10-02 00:29:10], 2) ~N[2014-10-02 00:29:12] # accepts negative offsets iex> NaiveDateTime.add(~N[2014-10-02 00:29:10], -2) ~N[2014-10-02 00:29:08] It can also work with subsecond precisions: iex> NaiveDateTime.add(~N[2014-10-02 00:29:10], 2_000, :millisecond) ~N[2014-10-02 00:29:12.000] As well as days/hours/minutes: iex> NaiveDateTime.add(~N[2015-02-28 00:29:10], 2, :day) ~N[2015-03-02 00:29:10] iex> NaiveDateTime.add(~N[2015-02-28 00:29:10], 36, :hour) ~N[2015-03-01 12:29:10] iex> NaiveDateTime.add(~N[2015-02-28 00:29:10], 60, :minute) ~N[2015-02-28 01:29:10] This operation merges the precision of the naive date time with the given unit: iex> result = NaiveDateTime.add(~N[2014-10-02 00:29:10], 21, :millisecond) ~N[2014-10-02 00:29:10.021] iex> result.microsecond {21000, 3} Operations on top of gregorian seconds or the Unix epoch are optimized: # from Gregorian seconds iex> NaiveDateTime.add(~N[0000-01-01 00:00:00], 63_579_428_950) ~N[2014-10-02 00:29:10] Passing a `DateTime` automatically converts it to `NaiveDateTime`, discarding the time zone information: iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> NaiveDateTime.add(dt, 21, :second) ~N[2000-02-29 23:00:28] To shift a naive datetime by a `Duration` and according to its underlying calendar, use `NaiveDateTime.shift/2`. ### NaiveDateTime.after?/2 (function) Returns `true` if the first `NaiveDateTime` is strictly later than the second. ### Examples - NaiveDateTime.after?/2 (function) iex> NaiveDateTime.after?(~N[2022-02-02 11:00:00], ~N[2021-01-01 11:00:00]) true iex> NaiveDateTime.after?(~N[2021-01-01 11:00:00], ~N[2021-01-01 11:00:00]) false iex> NaiveDateTime.after?(~N[2021-01-01 11:00:00], ~N[2022-02-02 11:00:00]) false ### NaiveDateTime.before?/2 (function) Returns `true` if the first `NaiveDateTime` is strictly earlier than the second. ### Examples - NaiveDateTime.before?/2 (function) iex> NaiveDateTime.before?(~N[2021-01-01 11:00:00], ~N[2022-02-02 11:00:00]) true iex> NaiveDateTime.before?(~N[2021-01-01 11:00:00], ~N[2021-01-01 11:00:00]) false iex> NaiveDateTime.before?(~N[2022-02-02 11:00:00], ~N[2021-01-01 11:00:00]) false ### NaiveDateTime.beginning_of_day/1 (function) Calculates a `NaiveDateTime` that is the first moment for the given `NaiveDateTime`. To calculate the beginning of day of a `DateTime`, call this function, then convert back to a `DateTime`: datetime |> NaiveDateTime.beginning_of_day() |> DateTime.from_naive(datetime.time_zone) Note that the beginning of the day may not exist or be ambiguous in a given timezone, so you must handle those cases accordingly. ### Examples - NaiveDateTime.beginning_of_day/1 (function) iex> NaiveDateTime.beginning_of_day(~N[2000-01-01 23:00:07.123456]) ~N[2000-01-01 00:00:00.000000] ### NaiveDateTime.compare/2 (function) Compares two `NaiveDateTime` structs. Returns `:gt` if first is later than the second and `:lt` for vice versa. If the two NaiveDateTime are equal `:eq` is returned. ### Examples - NaiveDateTime.compare/2 (function) iex> NaiveDateTime.compare(~N[2016-04-16 13:30:15], ~N[2016-04-28 16:19:25]) :lt iex> NaiveDateTime.compare(~N[2016-04-16 13:30:15.1], ~N[2016-04-16 13:30:15.01]) :gt This function can also be used to compare a DateTime without the time zone information: iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> NaiveDateTime.compare(dt, ~N[2000-02-29 23:00:07]) :eq iex> NaiveDateTime.compare(dt, ~N[2000-01-29 23:00:07]) :gt iex> NaiveDateTime.compare(dt, ~N[2000-03-29 23:00:07]) :lt ### NaiveDateTime.convert/2 (function) Converts the given `naive_datetime` from one calendar to another. If it is not possible to convert unambiguously between the calendars (see `Calendar.compatible_calendars?/2`), an `{:error, :incompatible_calendars}` tuple is returned. ### Examples - NaiveDateTime.convert/2 (function) Imagine someone implements `Calendar.Holocene`, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year: iex> NaiveDateTime.convert(~N[2000-01-01 13:30:15], Calendar.Holocene) {:ok, %NaiveDateTime{calendar: Calendar.Holocene, year: 12000, month: 1, day: 1, hour: 13, minute: 30, second: 15, microsecond: {0, 0}}} ### NaiveDateTime.convert!/2 (function) Converts the given `naive_datetime` from one calendar to another. If it is not possible to convert unambiguously between the calendars (see `Calendar.compatible_calendars?/2`), an ArgumentError is raised. ### Examples - NaiveDateTime.convert!/2 (function) Imagine someone implements `Calendar.Holocene`, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year: iex> NaiveDateTime.convert!(~N[2000-01-01 13:30:15], Calendar.Holocene) %NaiveDateTime{calendar: Calendar.Holocene, year: 12000, month: 1, day: 1, hour: 13, minute: 30, second: 15, microsecond: {0, 0}} ### NaiveDateTime.diff/3 (function) Subtracts `naive_datetime2` from `naive_datetime1`. The answer can be returned in any `:day`, `:hour`, `:minute`, or any `unit` available from `t:System.time_unit/0`. The unit is measured according to `Calendar.ISO` and defaults to `:second`. Fractional results are not supported and are truncated. ### Examples - NaiveDateTime.diff/3 (function) iex> NaiveDateTime.diff(~N[2014-10-02 00:29:12], ~N[2014-10-02 00:29:10]) 2 iex> NaiveDateTime.diff(~N[2014-10-02 00:29:12], ~N[2014-10-02 00:29:10], :microsecond) 2_000_000 iex> NaiveDateTime.diff(~N[2014-10-02 00:29:10.042], ~N[2014-10-02 00:29:10.021]) 0 iex> NaiveDateTime.diff(~N[2014-10-02 00:29:10.042], ~N[2014-10-02 00:29:10.021], :millisecond) 21 iex> NaiveDateTime.diff(~N[2014-10-02 00:29:10], ~N[2014-10-02 00:29:12]) -2 iex> NaiveDateTime.diff(~N[-0001-10-02 00:29:10], ~N[-0001-10-02 00:29:12]) -2 It can also compute the difference in days, hours, or minutes: iex> NaiveDateTime.diff(~N[2014-10-10 00:29:10], ~N[2014-10-02 00:29:10], :day) 8 iex> NaiveDateTime.diff(~N[2014-10-02 12:29:10], ~N[2014-10-02 00:29:10], :hour) 12 iex> NaiveDateTime.diff(~N[2014-10-02 00:39:10], ~N[2014-10-02 00:29:10], :minute) 10 But it also rounds incomplete days to zero: iex> NaiveDateTime.diff(~N[2014-10-10 00:29:09], ~N[2014-10-02 00:29:10], :day) 7 ### NaiveDateTime.end_of_day/1 (function) Calculates a `NaiveDateTime` that is the last moment for the given `NaiveDateTime`. To calculate the end of day of a `DateTime`, call this function, then convert back to a `DateTime`: datetime |> NaiveDateTime.end_of_day() |> DateTime.from_naive(datetime.time_zone) Note that the end of the day may not exist or be ambiguous in a given timezone, so you must handle those cases accordingly. ### Examples - NaiveDateTime.end_of_day/1 (function) iex> NaiveDateTime.end_of_day(~N[2000-01-01 23:00:07.123456]) ~N[2000-01-01 23:59:59.999999] ### NaiveDateTime.from_erl/3 (function) Converts an Erlang datetime tuple to a `NaiveDateTime` struct. Attempting to convert an invalid ISO calendar date will produce an error tuple. ### Examples - NaiveDateTime.from_erl/3 (function) iex> NaiveDateTime.from_erl({{2000, 1, 1}, {13, 30, 15}}) {:ok, ~N[2000-01-01 13:30:15]} iex> NaiveDateTime.from_erl({{2000, 1, 1}, {13, 30, 15}}, 5000) {:ok, ~N[2000-01-01 13:30:15.005000]} iex> NaiveDateTime.from_erl({{2000, 1, 1}, {13, 30, 15}}, {5000, 3}) {:ok, ~N[2000-01-01 13:30:15.005]} iex> NaiveDateTime.from_erl({{2000, 13, 1}, {13, 30, 15}}) {:error, :invalid_date} iex> NaiveDateTime.from_erl({{2000, 13, 1}, {13, 30, 15}}) {:error, :invalid_date} ### NaiveDateTime.from_erl!/3 (function) Converts an Erlang datetime tuple to a `NaiveDateTime` struct. Raises if the datetime is invalid. Attempting to convert an invalid ISO calendar date will produce an error tuple. ### Examples - NaiveDateTime.from_erl!/3 (function) iex> NaiveDateTime.from_erl!({{2000, 1, 1}, {13, 30, 15}}) ~N[2000-01-01 13:30:15] iex> NaiveDateTime.from_erl!({{2000, 1, 1}, {13, 30, 15}}, 5000) ~N[2000-01-01 13:30:15.005000] iex> NaiveDateTime.from_erl!({{2000, 1, 1}, {13, 30, 15}}, {5000, 3}) ~N[2000-01-01 13:30:15.005] iex> NaiveDateTime.from_erl!({{2000, 13, 1}, {13, 30, 15}}) ** (ArgumentError) cannot convert {{2000, 13, 1}, {13, 30, 15}} to naive datetime, reason: :invalid_date ### NaiveDateTime.from_gregorian_seconds/3 (function) Converts a number of gregorian seconds to a `NaiveDateTime` struct. ### Examples - NaiveDateTime.from_gregorian_seconds/3 (function) iex> NaiveDateTime.from_gregorian_seconds(1) ~N[0000-01-01 00:00:01] iex> NaiveDateTime.from_gregorian_seconds(63_755_511_991, {5000, 3}) ~N[2020-05-01 00:26:31.005] iex> NaiveDateTime.from_gregorian_seconds(-1) ~N[-0001-12-31 23:59:59] ### NaiveDateTime.from_iso8601/2 (function) Parses the extended "Date and time of day" format described by [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). Time zone offset may be included in the string but they will be simply discarded as such information is not included in naive date times. As specified in the standard, the separator "T" may be omitted if desired as there is no ambiguity within this function. Note leap seconds are not supported by the built-in Calendar.ISO. ### Examples - NaiveDateTime.from_iso8601/2 (function) iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07") {:ok, ~N[2015-01-23 23:50:07]} iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07") {:ok, ~N[2015-01-23 23:50:07]} iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07Z") {:ok, ~N[2015-01-23 23:50:07]} iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07.0") {:ok, ~N[2015-01-23 23:50:07.0]} iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07,0123456") {:ok, ~N[2015-01-23 23:50:07.012345]} iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07.0123456") {:ok, ~N[2015-01-23 23:50:07.012345]} iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123Z") {:ok, ~N[2015-01-23 23:50:07.123]} iex> NaiveDateTime.from_iso8601("2015-01-23P23:50:07") {:error, :invalid_format} iex> NaiveDateTime.from_iso8601("2015:01:23 23-50-07") {:error, :invalid_format} iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07A") {:error, :invalid_format} iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:61") {:error, :invalid_time} iex> NaiveDateTime.from_iso8601("2015-01-32 23:50:07") {:error, :invalid_date} iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123+02:30") {:ok, ~N[2015-01-23 23:50:07.123]} iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123+00:00") {:ok, ~N[2015-01-23 23:50:07.123]} iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123-02:30") {:ok, ~N[2015-01-23 23:50:07.123]} iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123-00:00") {:error, :invalid_format} iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123-00:60") {:error, :invalid_format} iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123-24:00") {:error, :invalid_format} ### NaiveDateTime.from_iso8601!/2 (function) Parses the extended "Date and time of day" format described by [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). Raises if the format is invalid. ### Examples - NaiveDateTime.from_iso8601!/2 (function) iex> NaiveDateTime.from_iso8601!("2015-01-23T23:50:07.123Z") ~N[2015-01-23 23:50:07.123] iex> NaiveDateTime.from_iso8601!("2015-01-23T23:50:07,123Z") ~N[2015-01-23 23:50:07.123] iex> NaiveDateTime.from_iso8601!("2015-01-23P23:50:07") ** (ArgumentError) cannot parse "2015-01-23P23:50:07" as naive datetime, reason: :invalid_format ### NaiveDateTime.local_now/1 (function) Returns the "local time" for the machine the Elixir program is running on. WARNING: This function can cause insidious bugs. It depends on the time zone configuration at run time. This can changed and be set to a time zone that has daylight saving jumps (spring forward or fall back). This function can be used to display what the time is right now for the time zone configuration that the machine happens to have. An example would be a desktop program displaying a clock to the user. For any other uses it is probably a bad idea to use this function. For most cases, use `DateTime.now/2` or `DateTime.utc_now/1` instead. Does not include fractional seconds. ### Examples - NaiveDateTime.local_now/1 (function) iex> naive_datetime = NaiveDateTime.local_now() iex> naive_datetime.year >= 2019 true ### NaiveDateTime.new/2 (function) Builds a naive datetime from date and time structs. ### Examples - NaiveDateTime.new/2 (function) iex> NaiveDateTime.new(~D[2010-01-13], ~T[23:00:07.005]) {:ok, ~N[2010-01-13 23:00:07.005]} ### NaiveDateTime.new/8 (function) Builds a new ISO naive datetime. Expects all values to be integers. Returns `{:ok, naive_datetime}` if each entry fits its appropriate range, returns `{:error, reason}` otherwise. ### Examples - NaiveDateTime.new/8 (function) iex> NaiveDateTime.new(2000, 1, 1, 0, 0, 0) {:ok, ~N[2000-01-01 00:00:00]} iex> NaiveDateTime.new(2000, 13, 1, 0, 0, 0) {:error, :invalid_date} iex> NaiveDateTime.new(2000, 2, 29, 0, 0, 0) {:ok, ~N[2000-02-29 00:00:00]} iex> NaiveDateTime.new(2000, 2, 30, 0, 0, 0) {:error, :invalid_date} iex> NaiveDateTime.new(2001, 2, 29, 0, 0, 0) {:error, :invalid_date} iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 59, {0, 1}) {:ok, ~N[2000-01-01 23:59:59.0]} iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 59, 999_999) {:ok, ~N[2000-01-01 23:59:59.999999]} iex> NaiveDateTime.new(2000, 1, 1, 24, 59, 59, 999_999) {:error, :invalid_time} iex> NaiveDateTime.new(2000, 1, 1, 23, 60, 59, 999_999) {:error, :invalid_time} iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 60, 999_999) {:error, :invalid_time} iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 59, 1_000_000) {:error, :invalid_time} iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 59, {0, 1}, Calendar.ISO) {:ok, ~N[2000-01-01 23:59:59.0]} ### NaiveDateTime.new!/2 (function) Builds a naive datetime from date and time structs. ### Examples - NaiveDateTime.new!/2 (function) iex> NaiveDateTime.new!(~D[2010-01-13], ~T[23:00:07.005]) ~N[2010-01-13 23:00:07.005] ### NaiveDateTime.new!/8 (function) Builds a new ISO naive datetime. Expects all values to be integers. Returns `naive_datetime` if each entry fits its appropriate range, raises if time or date is invalid. ### Examples - NaiveDateTime.new!/8 (function) iex> NaiveDateTime.new!(2000, 1, 1, 0, 0, 0) ~N[2000-01-01 00:00:00] iex> NaiveDateTime.new!(2000, 2, 29, 0, 0, 0) ~N[2000-02-29 00:00:00] iex> NaiveDateTime.new!(2000, 1, 1, 23, 59, 59, {0, 1}) ~N[2000-01-01 23:59:59.0] iex> NaiveDateTime.new!(2000, 1, 1, 23, 59, 59, 999_999) ~N[2000-01-01 23:59:59.999999] iex> NaiveDateTime.new!(2000, 1, 1, 23, 59, 59, {0, 1}, Calendar.ISO) ~N[2000-01-01 23:59:59.0] iex> NaiveDateTime.new!(2000, 1, 1, 24, 59, 59, 999_999) ** (ArgumentError) cannot build naive datetime, reason: :invalid_time ### NaiveDateTime.shift/2 (function) Shifts given `naive_datetime` by `duration` according to its calendar. Allowed units are: `:year`, `:month`, `:week`, `:day`, `:hour`, `:minute`, `:second`, `:microsecond`. When using the default ISO calendar, durations are collapsed and applied in the order of months, then seconds and microseconds: * when shifting by 1 year and 2 months the date is actually shifted by 14 months * weeks, days and smaller units are collapsed into seconds and microseconds When shifting by month, days are rounded down to the nearest valid date. ### Examples - NaiveDateTime.shift/2 (function) iex> NaiveDateTime.shift(~N[2016-01-31 00:00:00], month: 1) ~N[2016-02-29 00:00:00] iex> NaiveDateTime.shift(~N[2016-01-31 00:00:00], year: 4, day: 1) ~N[2020-02-01 00:00:00] iex> NaiveDateTime.shift(~N[2016-01-31 00:00:00], year: -2, day: 1) ~N[2014-02-01 00:00:00] iex> NaiveDateTime.shift(~N[2016-01-31 00:00:00], second: 45) ~N[2016-01-31 00:00:45] iex> NaiveDateTime.shift(~N[2016-01-31 00:00:00], microsecond: {100, 6}) ~N[2016-01-31 00:00:00.000100] # leap years iex> NaiveDateTime.shift(~N[2024-02-29 00:00:00], year: 1) ~N[2025-02-28 00:00:00] iex> NaiveDateTime.shift(~N[2024-02-29 00:00:00], year: 4) ~N[2028-02-29 00:00:00] # rounding down iex> NaiveDateTime.shift(~N[2015-01-31 00:00:00], month: 1) ~N[2015-02-28 00:00:00] ### NaiveDateTime.to_date/1 (function) Converts a `NaiveDateTime` into a `Date`. Because `Date` does not hold time information, data will be lost during the conversion. ### Examples - NaiveDateTime.to_date/1 (function) iex> NaiveDateTime.to_date(~N[2002-01-13 23:00:07]) ~D[2002-01-13] ### NaiveDateTime.to_erl/1 (function) Converts a `NaiveDateTime` struct to an Erlang datetime tuple. Only supports converting naive datetimes which are in the ISO calendar, attempting to convert naive datetimes from other calendars will raise. WARNING: Loss of precision may occur, as Erlang time tuples only store hour/minute/second. ### Examples - NaiveDateTime.to_erl/1 (function) iex> NaiveDateTime.to_erl(~N[2000-01-01 13:30:15]) {{2000, 1, 1}, {13, 30, 15}} This function can also be used to convert a DateTime to an Erlang datetime tuple without the time zone information: iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> NaiveDateTime.to_erl(dt) {{2000, 2, 29}, {23, 00, 07}} ### NaiveDateTime.to_gregorian_seconds/1 (function) Converts a `NaiveDateTime` struct to a number of gregorian seconds and microseconds. ### Examples - NaiveDateTime.to_gregorian_seconds/1 (function) iex> NaiveDateTime.to_gregorian_seconds(~N[0000-01-01 00:00:01]) {1, 0} iex> NaiveDateTime.to_gregorian_seconds(~N[2020-05-01 00:26:31.005]) {63_755_511_991, 5000} ### NaiveDateTime.to_iso8601/2 (function) Converts the given naive datetime to [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). By default, `NaiveDateTime.to_iso8601/2` returns naive datetimes formatted in the "extended" format, for human readability. It also supports the "basic" format through passing the `:basic` option. Only supports converting naive datetimes which are in the ISO calendar, attempting to convert naive datetimes from other calendars will raise. ### Examples - NaiveDateTime.to_iso8601/2 (function) iex> NaiveDateTime.to_iso8601(~N[2000-02-28 23:00:13]) "2000-02-28T23:00:13" iex> NaiveDateTime.to_iso8601(~N[2000-02-28 23:00:13.001]) "2000-02-28T23:00:13.001" iex> NaiveDateTime.to_iso8601(~N[2000-02-28 23:00:13.001], :basic) "20000228T230013.001" This function can also be used to convert a DateTime to ISO 8601 without the time zone information: iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> NaiveDateTime.to_iso8601(dt) "2000-02-29T23:00:07" ### NaiveDateTime.to_string/1 (function) Converts the given naive datetime to a string according to its calendar. For redability, this function follows the RFC3339 suggestion of removing the "T" separator between the date and time components. ### Examples - NaiveDateTime.to_string/1 (function) iex> NaiveDateTime.to_string(~N[2000-02-28 23:00:13]) "2000-02-28 23:00:13" iex> NaiveDateTime.to_string(~N[2000-02-28 23:00:13.001]) "2000-02-28 23:00:13.001" iex> NaiveDateTime.to_string(~N[-0100-12-15 03:20:31]) "-0100-12-15 03:20:31" This function can also be used to convert a DateTime to a string without the time zone information: iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", ...> hour: 23, minute: 0, second: 7, microsecond: {0, 0}, ...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} iex> NaiveDateTime.to_string(dt) "2000-02-29 23:00:07" ### NaiveDateTime.to_time/1 (function) Converts a `NaiveDateTime` into `Time`. Because `Time` does not hold date information, data will be lost during the conversion. ### Examples - NaiveDateTime.to_time/1 (function) iex> NaiveDateTime.to_time(~N[2002-01-13 23:00:07]) ~T[23:00:07] ### NaiveDateTime.truncate/2 (function) Returns the given naive datetime with the microsecond field truncated to the given precision (`:microsecond`, `:millisecond` or `:second`). The given naive datetime is returned unchanged if it already has lower precision than the given precision. ### Examples - NaiveDateTime.truncate/2 (function) iex> NaiveDateTime.truncate(~N[2017-11-06 00:23:51.123456], :microsecond) ~N[2017-11-06 00:23:51.123456] iex> NaiveDateTime.truncate(~N[2017-11-06 00:23:51.123456], :millisecond) ~N[2017-11-06 00:23:51.123] iex> NaiveDateTime.truncate(~N[2017-11-06 00:23:51.123456], :second) ~N[2017-11-06 00:23:51] ### NaiveDateTime.utc_now/1 (function) Returns the current naive datetime in UTC. Prefer using `DateTime.utc_now/0` when possible as, opposite to `NaiveDateTime`, it will keep the time zone information. You can also provide a time unit to automatically truncate the naive datetime. This is available since v1.15.0. ### Examples - NaiveDateTime.utc_now/1 (function) iex> naive_datetime = NaiveDateTime.utc_now() iex> naive_datetime.year >= 2016 true iex> naive_datetime = NaiveDateTime.utc_now(:second) iex> naive_datetime.microsecond {0, 0} ### NaiveDateTime.utc_now/2 (function) Returns the current naive datetime in UTC, supporting a specific calendar and precision. Prefer using `DateTime.utc_now/2` when possible as, opposite to `NaiveDateTime`, it will keep the time zone information. ### Examples - NaiveDateTime.utc_now/2 (function) iex> naive_datetime = NaiveDateTime.utc_now(:second, Calendar.ISO) iex> naive_datetime.year >= 2016 true iex> naive_datetime = NaiveDateTime.utc_now(:second, Calendar.ISO) iex> naive_datetime.microsecond {0, 0} ### NaiveDateTime.t/0 (type) ### Record (module) Module to work with, define, and import records. Records are simply tuples where the first element is an atom: iex> Record.is_record({User, "john", 27}) true This module provides conveniences for working with records at compilation time, where compile-time field names are used to manipulate the tuples, providing fast operations on top of the tuples' compact structure. In Elixir, records are used mostly in two situations: 1. to work with short, internal data 2. to interface with Erlang records The macros `defrecord/3` and `defrecordp/3` can be used to create records while `extract/2` and `extract_all/1` can be used to extract records from Erlang files. ### Types - Record (module) Types can be defined for tuples with the `record/2` macro (only available in typespecs). This macro will expand to a tuple as seen in the example below: defmodule MyModule do require Record Record.defrecord(:user, name: "john", age: 25) @type user :: record(:user, name: String.t(), age: integer) # expands to: "@type user :: {:user, String.t(), integer}" end ### Reflection - Record (module) The record tag and its fields are stored as metadata in the "Docs" chunk of the record definition macro. You can retrieve the documentation for a module by calling `Code.fetch_docs/1`. ### Record.defrecord/3 (macro) Defines a set of macros to create, access, and pattern match on a record. The name of the generated macros will be `name` (which has to be an atom). `tag` is also an atom and is used as the "tag" for the record (i.e., the first element of the record tuple); by default (if `nil`), it's the same as `name`. `kv` is a keyword list of `name: default_value` fields for the new record. The following macros are generated: * `name/0` to create a new record with default values for all fields * `name/1` to create a new record with the given fields and values, to get the zero-based index of the given field in a record or to convert the given record to a keyword list * `name/2` to update an existing record with the given fields and values or to access a given field in a given record All these macros are public macros (as defined by `defmacro`). See the "Examples" section for examples on how to use these macros. ### Examples - Record.defrecord/3 (macro) defmodule User do require Record Record.defrecord(:user, name: "meg", age: "25") end In the example above, a set of macros named `user` but with different arities will be defined to manipulate the underlying record. # Import the module to make the user macros locally available import User # To create records record = user() #=> {:user, "meg", 25} record = user(age: 26) #=> {:user, "meg", 26} # To get a field from the record user(record, :name) #=> "meg" # To update the record user(record, age: 26) #=> {:user, "meg", 26} # To get the zero-based index of the field in record tuple # (index 0 is occupied by the record "tag") user(:name) #=> 1 # Convert a record to a keyword list user(record) #=> [name: "meg", age: 26] The generated macros can also be used in order to pattern match on records and to bind variables during the match: record = user() #=> {:user, "meg", 25} user(name: name) = record name #=> "meg" By default, Elixir uses the record name as the first element of the tuple (the "tag"). However, a different tag can be specified when defining a record, as in the following example, in which we use `Customer` as the second argument of `defrecord/3`: defmodule User do require Record Record.defrecord(:user, Customer, name: nil) end require User User.user() #=> {Customer, nil} ### Defining extracted records with anonymous functions in the values - Record.defrecord/3 (macro) If a record defines an anonymous function in the default values, an `ArgumentError` will be raised. This can happen unintentionally when defining a record after extracting it from an Erlang library that uses anonymous functions for defaults. Record.defrecord(:my_rec, Record.extract(...)) ** (ArgumentError) invalid value for record field fun_field, cannot escape #Function<12.90072148/2 in :erl_eval.expr/5>. To work around this error, redefine the field with your own &M.f/a function, like so: defmodule MyRec do require Record Record.defrecord(:my_rec, Record.extract(...) |> Keyword.merge(fun_field: &__MODULE__.foo/2)) def foo(bar, baz), do: IO.inspect({bar, baz}) end ### Record.defrecordp/3 (macro) Same as `defrecord/3` but generates private macros. ### Record.extract/2 (function) Extracts record information from an Erlang file. Returns a quoted expression containing the fields as a list of tuples. `name`, which is the name of the extracted record, is expected to be an atom *at compile time*. ### Options - Record.extract/2 (function) This function requires one of the following options, which are exclusive to each other (i.e., only one of them can be used in the same call): * `:from` - (binary representing a path to a file) path to the Erlang file that contains the record definition to extract; with this option, this function uses the same path lookup used by the `-include` attribute used in Erlang modules. * `:from_lib` - (binary representing a path to a file) path to the Erlang file that contains the record definition to extract; with this option, this function uses the same path lookup used by the `-include_lib` attribute used in Erlang modules. It additionally accepts the following optional, non-exclusive options: * `:includes` - (a list of directories as binaries) if the record being extracted depends on relative includes, this option allows developers to specify the directory where those relative includes exist. * `:macros` - (keyword list of macro names and values) if the record being extracted depends on the values of macros, this option allows the value of those macros to be set. These options are expected to be literals (including the binary values) at compile time. ### Examples - Record.extract/2 (function) iex> Record.extract(:file_info, from_lib: "kernel/include/file.hrl") [ size: :undefined, type: :undefined, access: :undefined, atime: :undefined, mtime: :undefined, ctime: :undefined, mode: :undefined, links: :undefined, major_device: :undefined, minor_device: :undefined, inode: :undefined, uid: :undefined, gid: :undefined ] ### Record.extract_all/1 (function) Extracts all records information from an Erlang file. Returns a keyword list of `{record_name, fields}` tuples where `record_name` is the name of an extracted record and `fields` is a list of `{field, value}` tuples representing the fields for that record. ### Options - Record.extract_all/1 (function) Accepts the same options as listed for `Record.extract/2`. ### Record.is_record/1 (macro) Checks if the given `data` is a record. This is implemented as a macro so it can be used in guard clauses. ### Examples - Record.is_record/1 (macro) Record.is_record({User, "john", 27}) #=> true Record.is_record({}) #=> false ### Record.is_record/2 (macro) Checks if the given `data` is a record of kind `kind`. This is implemented as a macro so it can be used in guard clauses. ### Examples - Record.is_record/2 (macro) iex> record = {User, "john", 27} iex> Record.is_record(record, User) true ### Regex (module) Provides regular expressions for Elixir. Regex is based on PCRE (Perl Compatible Regular Expressions) and built on top of Erlang's `:re` module. More information can be found in the [`:re` module documentation](`:re`). Regular expressions in Elixir can be created using the sigils `~r` (see `sigil_r/2`): # A simple regular expression that matches foo anywhere in the string ~r/foo/ # A regular expression with case insensitive and Unicode options ~r/foo/iu Regular expressions created via sigils are pre-compiled and stored in the `.beam` file. Note that this may be a problem if you are precompiling Elixir, see the "Precompilation" section for more information. A Regex is represented internally as the `Regex` struct. Therefore, `%Regex{}` can be used whenever there is a need to match on them. Keep in mind that all of the structs fields are private. There is also not guarantee two regular expressions from the same source are equal, for example: ~r/(? .)(? .)/ == ~r/(? .)(? .)/ may return `true` or `false` depending on your machine, endianness, available optimizations and others. You can, however, retrieve the source of a compiled regular expression by accessing the `source` field, and then compare those directly: ~r/(? .)(? .)/.source == ~r/(? .)(? .)/.source ### Escapes - Regex (module) Escape sequences are split into two categories. ### Non-printing characters - Regex (module) * `\a` - Alarm, that is, the BEL character (hex 07) * `\e` - Escape (hex 1B) * `\f` - Form feed (hex 0C) * `\n` - Line feed (hex 0A) * `\r` - Carriage return (hex 0D) * `\t` - Tab (hex 09) * `\xhh` - Character with hex code hh * `\x{hhh..}` - Character with hex code hhh.. `\u` and `\U` are not supported. Other escape sequences, such as `\ddd` for octals, are supported but discouraged. ### Generic character types - Regex (module) * `\d` - Any decimal digit * `\D` - Any character that is not a decimal digit * `\h` - Any horizontal whitespace character * `\H` - Any character that is not a horizontal whitespace character * `\s` - Any whitespace character * `\S` - Any character that is not a whitespace character * `\v` - Any vertical whitespace character * `\V` - Any character that is not a vertical whitespace character * `\w` - Any "word" character * `\W` - Any "non-word" character ### Modifiers - Regex (module) The modifiers available when creating a Regex are: * `:unicode` (u) - enables Unicode specific patterns like `\p` and causes character classes like `\w`, `\W`, `\s`, and the like to also match on Unicode (see examples below in "Character classes"). It expects valid Unicode strings to be given on match * `:caseless` (i) - adds case insensitivity * `:dotall` (s) - causes dot to match newlines and also set newline to anycrlf; the new line setting can be overridden by setting `(*CR)` or `(*LF)` or `(*CRLF)` or `(*ANY)` according to `:re` documentation * `:multiline` (m) - causes `^` and `$` to mark the beginning and end of each line; use `\A` and `\z` to match the end or beginning of the string * `:extended` (x) - whitespace characters are ignored except when escaped or within `[..]`, and allow `#` to delimit comments * `:firstline` (f) - forces the unanchored pattern to match before or at the first newline, though the matched text may continue over the newline * `:ungreedy` (U) - inverts the "greediness" of the regexp (the previous `r` option is deprecated in favor of `U`) The options not available are: * `:anchored` - not available, use `^` or `\A` instead * `:dollar_endonly` - not available, use `\z` instead * `:no_auto_capture` - not available, use `?:` instead * `:newline` - not available, use `(*CR)` or `(*LF)` or `(*CRLF)` or `(*ANYCRLF)` or `(*ANY)` at the beginning of the regexp according to the `:re` documentation ### Captures - Regex (module) Many functions in this module handle what to capture in a regex match via the `:capture` option. The supported values are: * `:all` - all captured subpatterns including the complete matching string (this is the default) * `:first` - only the first captured subpattern, which is always the complete matching part of the string; all explicitly captured subpatterns are discarded * `:all_but_first` - all but the first matching subpattern, i.e. all explicitly captured subpatterns, but not the complete matching part of the string * `:none` - does not return matching subpatterns at all * `:all_names` - captures all named subpattern matches in the Regex as a list ordered **alphabetically** by the names of the subpatterns * `list(binary | atom)` - a list of named captures to capture ### Character classes - Regex (module) Regex supports several built in named character classes. These are used by enclosing the class name in `[: :]` inside a group. For example: iex> String.match?("123", ~r/^[[:alnum:]]+$/) true iex> String.match?("123 456", ~r/^[[:alnum:][:blank:]]+$/) true The supported class names are: * alnum - Letters and digits * alpha - Letters * blank - Space or tab only * cntrl - Control characters * digit - Decimal digits (same as \\d) * graph - Printing characters, excluding space * lower - Lowercase letters * print - Printing characters, including space * punct - Printing characters, excluding letters, digits, and space * space - Whitespace (the same as \s from PCRE 8.34) * upper - Uppercase letters * word - "Word" characters (same as \w) * xdigit - Hexadecimal digits There is another character class, `ascii`, that erroneously matches Latin-1 characters instead of the 0-127 range specified by POSIX. This cannot be fixed without altering the behavior of other classes, so we recommend matching the range with `[\\0-\x7f]` instead. Note the behavior of those classes may change according to the Unicode and other modifiers: iex> String.match?("josé", ~r/^[[:lower:]]+$/) false iex> String.match?("josé", ~r/^[[:lower:]]+$/u) true iex> Regex.replace(~r/\s/, "Unicode\u00A0spaces", "-") "Unicode spaces" iex> Regex.replace(~r/\s/u, "Unicode\u00A0spaces", "-") "Unicode-spaces" ### Precompilation - Regex (module) Regular expressions built with sigil are precompiled and stored in `.beam` files. Precompiled regexes will be checked in runtime and may work slower between operating systems and OTP releases. This is rarely a problem, as most Elixir code shared during development is compiled on the target (such as dependencies, archives, and escripts) and, when running in production, the code must either be compiled on the target (via `mix compile` or similar) or released on the host (via `mix releases` or similar) with a matching OTP, operating system and architecture as the target. If you know you are running on a different system than the current one and you are doing multiple matches with the regex, you can manually invoke `Regex.recompile/1` or `Regex.recompile!/1` to perform a runtime version check and recompile the regex if necessary. ### Regex.compile/2 (function) Compiles the regular expression. The given options can either be a binary with the characters representing the same regex options given to the `~r` (see `sigil_r/2`) sigil, or a list of options, as expected by the Erlang's [`:re`](`:re`) module. It returns `{:ok, regex}` in case of success, `{:error, reason}` otherwise. ### Examples - Regex.compile/2 (function) iex> Regex.compile("foo") {:ok, ~r/foo/} iex> Regex.compile("*foo") {:error, {~c"nothing to repeat", 0}} iex> Regex.compile("foo", "i") {:ok, ~r/foo/i} iex> Regex.compile("foo", [:caseless]) {:ok, Regex.compile!("foo", [:caseless])} ### Regex.compile!/2 (function) Compiles the regular expression and raises `Regex.CompileError` in case of errors. ### Regex.escape/1 (function) Escapes a string to be literally matched in a regex. ### Examples - Regex.escape/1 (function) iex> Regex.escape(".") "\\." iex> Regex.escape("\\what if") "\\\\what\\ if" ### Regex.match?/2 (function) Returns a boolean indicating whether there was a match or not. ### Examples - Regex.match?/2 (function) iex> Regex.match?(~r/foo/, "foo") true iex> Regex.match?(~r/foo/, "bar") false Elixir also provides text-based match operator `=~/2` and function `String.match?/2` as an alternative to test strings against regular expressions and strings. ### Regex.named_captures/3 (function) Returns the given captures as a map or `nil` if no captures are found. ### Options - Regex.named_captures/3 (function) * `:return` - when set to `:index`, returns byte index and match length. Defaults to `:binary`. ### Examples - Regex.named_captures/3 (function) iex> Regex.named_captures(~r/c(? d)/, "abcd") %{"foo" => "d"} iex> Regex.named_captures(~r/a(? b)c(? d)/, "abcd") %{"bar" => "d", "foo" => "b"} iex> Regex.named_captures(~r/a(? b)c(? d)/, "efgh") nil ### Regex.names/1 (function) Returns a list of names in the regex. ### Examples - Regex.names/1 (function) iex> Regex.names(~r/(? bar)/) ["foo"] ### Regex.opts/1 (function) Returns the regex options. See the documentation of `Regex.compile/2` for more information. ### Examples - Regex.opts/1 (function) iex> Regex.opts(~r/foo/m) [:multiline] iex> Regex.opts(Regex.compile!("foo", [:caseless])) [:caseless] ### Regex.re_pattern/1 (function) Returns the underlying `re_pattern` in the regular expression. ### Regex.recompile/1 (function) Recompiles the existing regular expression if necessary. This checks the version stored in the regular expression and recompiles the regex in case of version mismatch. ### Regex.recompile!/1 (function) Recompiles the existing regular expression and raises `Regex.CompileError` in case of errors. ### Regex.replace/4 (function) Receives a regex, a binary and a replacement, returns a new binary where all matches are replaced by the replacement. The replacement can be either a string or a function that returns a string. The resulting string is used as a replacement for every match. When the replacement is a string, it allows specific captures of the match using brackets at the regex expression and accessing them in the replacement via `\N` or `\g{N}`, where `N` is the number of the capture. In case `\0` is used, the whole match is inserted. Note that in regexes the backslash needs to be escaped, hence in practice you'll need to use `\\N` and `\\g{N}`. When the replacement is a function, it allows specific captures too. The function may have arity N where each argument maps to a capture, with the first argument being the whole match. If the function expects more arguments than captures found, the remaining arguments will receive `""`. ### Options - Regex.replace/4 (function) * `:global` - when `false`, replaces only the first occurrence (defaults to `true`) ### Examples - Regex.replace/4 (function) iex> Regex.replace(~r/d/, "abc", "d") "abc" iex> Regex.replace(~r/b/, "abc", "d") "adc" iex> Regex.replace(~r/b/, "abc", "[\\0]") "a[b]c" iex> Regex.replace(~r/a(b|d)c/, "abcadc", "[\\1]") "[b][d]" iex> Regex.replace(~r/\.(\d)$/, "500.5", ".\\g{1}0") "500.50" iex> Regex.replace(~r/a(b|d)c/, "abcadc", fn _, x -> "[#{x}]" end) "[b][d]" iex> Regex.replace(~r/(\w+)@(\w+).(\w+)/, "abc@def.com", fn _full, _c1, _c2, c3 -> "TLD: #{c3}" end) "TLD: com" iex> Regex.replace(~r/a/, "abcadc", "A", global: false) "Abcadc" ### Regex.run/3 (function) Runs the regular expression against the given string until the first match. It returns a list with all captures or `nil` if no match occurred. ### Options - Regex.run/3 (function) * `:return` - when set to `:index`, returns byte index and match length. Defaults to `:binary`. * `:capture` - what to capture in the result. See the ["Captures" section](#module-captures) to see the possible capture values. * `:offset` - (since v1.12.0) specifies the starting offset to match in the given string. Defaults to zero. ### Examples - Regex.run/3 (function) iex> Regex.run(~r/c(d)/, "abcd") ["cd", "d"] iex> Regex.run(~r/e/, "abcd") nil iex> Regex.run(~r/c(d)/, "abcd", return: :index) [{2, 2}, {3, 1}] iex> Regex.run(~r/c(d)/, "abcd", capture: :first) ["cd"] iex> Regex.run(~r/c(? d)/, "abcd", capture: ["foo", "bar"]) ["d", ""] ### Regex.scan/3 (function) Same as `run/3` but returns all non-overlapping matches of the regular expression. A list of lists is returned, where each entry in the primary list represents a match and each entry in the secondary list represents the captured contents. ### Options - Regex.scan/3 (function) * `:return` - when set to `:index`, returns byte index and match length. Defaults to `:binary`. * `:capture` - what to capture in the result. See the ["Captures" section](#module-captures) to see the possible capture values. * `:offset` - (since v1.12.0) specifies the starting offset to match in the given string. Defaults to zero. ### Examples - Regex.scan/3 (function) iex> Regex.scan(~r/c(d|e)/, "abcd abce") [["cd", "d"], ["ce", "e"]] iex> Regex.scan(~r/c(?:d|e)/, "abcd abce") [["cd"], ["ce"]] iex> Regex.scan(~r/e/, "abcd") [] iex> Regex.scan(~r/ab|bc|cd/, "abcd") [["ab"], ["cd"]] iex> Regex.scan(~r/ab|bc|cd/, "abbccd") [["ab"], ["bc"], ["cd"]] iex> Regex.scan(~r/\p{Sc}/u, "$, £, and €") [["$"], ["£"], ["€"]] iex> Regex.scan(~r/=+/, "=ü†ƒ8===", return: :index) [[{0, 1}], [{9, 3}]] iex> Regex.scan(~r/c(d|e)/, "abcd abce", capture: :first) [["cd"], ["ce"]] ### Regex.source/1 (function) Returns the regex source as a binary. ### Examples - Regex.source/1 (function) iex> Regex.source(~r/foo/) "foo" ### Regex.split/3 (function) Splits the given target based on the given pattern and in the given number of parts. ### Options - Regex.split/3 (function) * `:parts` - when specified, splits the string into the given number of parts. If not specified, `:parts` defaults to `:infinity`, which will split the string into the maximum number of parts possible based on the given pattern. * `:trim` - when `true`, removes empty strings (`""`) from the result. Defaults to `false`. * `:on` - specifies which captures to split the string on, and in what order. Defaults to `:first` which means captures inside the regex do not affect the splitting process. See the ["Captures" section](#module-captures) to see the possible capture values. * `:include_captures` - when `true`, includes in the result the matches of the regular expression. The matches are not counted towards the maximum number of parts if combined with the `:parts` option. Defaults to `false`. ### Examples - Regex.split/3 (function) iex> Regex.split(~r/-/, "a-b-c") ["a", "b", "c"] iex> Regex.split(~r/-/, "a-b-c", parts: 2) ["a", "b-c"] iex> Regex.split(~r/-/, "abc") ["abc"] iex> Regex.split(~r//, "abc") ["", "a", "b", "c", ""] iex> Regex.split(~r/a(? b)c/, "abc") ["", ""] iex> Regex.split(~r/a(? b)c/, "abc", on: [:second]) ["a", "c"] iex> Regex.split(~r/(x)/, "Elixir", include_captures: true) ["Eli", "x", "ir"] iex> Regex.split(~r/a(? b)c/, "abc", on: [:second], include_captures: true) ["a", "b", "c"] iex> Regex.split(~r/-/, "-a-b--c", trim: true) ["a", "b", "c"] ### Regex.version/0 (function) Returns the version of the underlying Regex engine. ### Regex.t/0 (type) ### String (module) Strings in Elixir are UTF-8 encoded binaries. Strings in Elixir are a sequence of Unicode characters, typically written between double quoted strings, such as `"hello"` and `"héllò"`. In case a string must have a double-quote in itself, the double quotes must be escaped with a backslash, for example: `"this is a string with \"double quotes\""`. You can concatenate two strings with the `<>/2` operator: iex> "hello" <> " " <> "world" "hello world" The functions in this module act according to [The Unicode Standard, Version 16.0.0](http://www.unicode.org/versions/Unicode16.0.0/). ### Interpolation - String (module) Strings in Elixir also support interpolation. This allows you to place some value in the middle of a string by using the `#{}` syntax: iex> name = "joe" iex> "hello #{name}" "hello joe" Any Elixir expression is valid inside the interpolation. If a string is given, the string is interpolated as is. If any other value is given, Elixir will attempt to convert it to a string using the `String.Chars` protocol. This allows, for example, to output an integer from the interpolation: iex> "2 + 2 = #{2 + 2}" "2 + 2 = 4" In case the value you want to interpolate cannot be converted to a string, because it doesn't have a human textual representation, a protocol error will be raised. ### Escape characters - String (module) Besides allowing double-quotes to be escaped with a backslash, strings also support the following escape characters: * `\0` - Null byte * `\a` - Bell * `\b` - Backspace * `\t` - Horizontal tab * `\n` - Line feed (New lines) * `\v` - Vertical tab * `\f` - Form feed * `\r` - Carriage return * `\e` - Command Escape * `\s` - Space * `\#` - Returns the `#` character itself, skipping interpolation * `\\` - Single backslash * `\xNN` - A byte represented by the hexadecimal `NN` * `\uNNNN` - A Unicode code point represented by `NNNN` * `\u{NNNNNN}` - A Unicode code point represented by `NNNNNN` Note it is generally not advised to use `\xNN` in Elixir strings, as introducing an invalid byte sequence would make the string invalid. If you have to introduce a character by its hexadecimal representation, it is best to work with Unicode code points, such as `\uNNNN`. In fact, understanding Unicode code points can be essential when doing low-level manipulations of string, so let's explore them in detail next. ### Unicode and code points - String (module) In order to facilitate meaningful communication between computers across multiple languages, a standard is required so that the ones and zeros on one machine mean the same thing when they are transmitted to another. The Unicode Standard acts as an official registry of virtually all the characters we know: this includes characters from classical and historical texts, emoji, and formatting and control characters as well. Unicode organizes all of the characters in its repertoire into code charts, and each character is given a unique numerical index. This numerical index is known as a Code Point. In Elixir you can use a `?` in front of a character literal to reveal its code point: iex> ?a 97 iex> ?ł 322 Note that most Unicode code charts will refer to a code point by its hexadecimal (hex) representation, e.g. `97` translates to `0061` in hex, and we can represent any Unicode character in an Elixir string by using the `\u` escape character followed by its code point number: iex> "\u0061" === "a" true iex> 0x0061 = 97 = ?a 97 The hex representation will also help you look up information about a code point, e.g. [https://codepoints.net/U+0061](https://codepoints.net/U+0061) has a data sheet all about the lower case `a`, a.k.a. code point 97. Remember you can get the hex presentation of a number by calling `Integer.to_string/2`: iex> Integer.to_string(?a, 16) "61" ### UTF-8 encoded and encodings - String (module) Now that we understand what the Unicode standard is and what code points are, we can finally talk about encodings. Whereas the code point is **what** we store, an encoding deals with **how** we store it: encoding is an implementation. In other words, we need a mechanism to convert the code point numbers into bytes so they can be stored in memory, written to disk, and such. Elixir uses UTF-8 to encode its strings, which means that code points are encoded as a series of 8-bit bytes. UTF-8 is a **variable width** character encoding that uses one to four bytes to store each code point. It is capable of encoding all valid Unicode code points. Let's see an example: iex> string = "héllo" "héllo" iex> String.length(string) 5 iex> byte_size(string) 6 Although the string above has 5 characters, it uses 6 bytes, as two bytes are used to represent the character `é`. ### Grapheme clusters - String (module) This module also works with the concept of grapheme cluster (from now on referenced as graphemes). Graphemes can consist of multiple code points that may be perceived as a single character by readers. For example, "é" can be represented either as a single "e with acute" code point, as seen above in the string `"héllo"`, or as the letter "e" followed by a "combining acute accent" (two code points): iex> string = "\u0065\u0301" "é" iex> byte_size(string) 3 iex> String.length(string) 1 iex> String.codepoints(string) ["e", "́"] iex> String.graphemes(string) ["é"] Although it looks visually the same as before, the example above is made of two characters, it is perceived by users as one. Graphemes can also be two characters that are interpreted as one by some languages. For example, some languages may consider "ch" as a single character. However, since this information depends on the locale, it is not taken into account by this module. In general, the functions in this module rely on the Unicode Standard, but do not contain any of the locale specific behavior. More information about graphemes can be found in the [Unicode Standard Annex #29](https://www.unicode.org/reports/tr29/). For converting a binary to a different encoding and for Unicode normalization mechanisms, see Erlang's `:unicode` module. ### String and binary operations - String (module) To act according to the Unicode Standard, many functions in this module run in linear time, as they need to traverse the whole string considering the proper Unicode code points. For example, `String.length/1` will take longer as the input grows. On the other hand, `Kernel.byte_size/1` always runs in constant time (i.e. regardless of the input size). This means often there are performance costs in using the functions in this module, compared to the more low-level operations that work directly with binaries: * `Kernel.binary_part/3` - retrieves part of the binary * `Kernel.bit_size/1` and `Kernel.byte_size/1` - size related functions * `Kernel.is_bitstring/1` and `Kernel.is_binary/1` - type-check function * Plus a number of functions for working with binaries (bytes) in the [`:binary` module](`:binary`) A `utf8` modifier is also available inside the binary syntax `<<>>`. It can be used to match code points out of a binary/string: iex> < > = "é" iex> eacute 233 See the [*Patterns and Guards* guide](patterns-and-guards.md) and the documentation for [`<<>>`](`<<>>/1`) for more information on binary pattern matching. You can also fully convert a string into a list of integer code points, known as "charlists" in Elixir, by calling `String.to_charlist/1`: iex> String.to_charlist("héllo") [104, 233, 108, 108, 111] If you would rather see the underlying bytes of a string, instead of its codepoints, a common trick is to concatenate the null byte `<<0>>` to it: iex> "héllo" <> <<0>> <<104, 195, 169, 108, 108, 111, 0>> Alternatively, you can view a string's binary representation by passing an option to `IO.inspect/2`: IO.inspect("héllo", binaries: :as_binaries) #=> <<104, 195, 169, 108, 108, 111>> ### Self-synchronization - String (module) The UTF-8 encoding is self-synchronizing. This means that if malformed data (i.e., data that is not possible according to the definition of the encoding) is encountered, only one code point needs to be rejected. This module relies on this behavior to ignore such invalid characters. For example, `length/1` will return a correct result even if an invalid code point is fed into it. In other words, this module expects invalid data to be detected elsewhere, usually when retrieving data from the external source. For example, a driver that reads strings from a database will be responsible to check the validity of the encoding. `String.chunk/2` can be used for breaking a string into valid and invalid parts. ### Compile binary patterns - String (module) Many functions in this module work with patterns. For example, `String.split/3` can split a string into multiple strings given a pattern. This pattern can be a string, a list of strings or a compiled pattern: iex> String.split("foo bar", " ") ["foo", "bar"] iex> String.split("foo bar!", [" ", "!"]) ["foo", "bar", ""] iex> pattern = :binary.compile_pattern([" ", "!"]) iex> String.split("foo bar!", pattern) ["foo", "bar", ""] The compiled pattern is useful when the same match will be done over and over again. Note though that the compiled pattern cannot be stored in a module attribute as the pattern is generated at runtime and does not survive compile time. ### String.at/2 (function) Returns the grapheme at the `position` of the given UTF-8 `string`. If `position` is greater than `string` length, then it returns `nil`. > #### Linear Access {: .warning} > > This function has to linearly traverse the string. > If you want to access a string or a binary in constant time based on the > number of bytes, use `Kernel.binary_slice/3` or `:binary.at/2` instead. ### Examples - String.at/2 (function) iex> String.at("elixir", 0) "e" iex> String.at("elixir", 1) "l" iex> String.at("elixir", 10) nil iex> String.at("elixir", -1) "r" iex> String.at("elixir", -10) nil ### String.bag_distance/2 (function) Computes the bag distance between two strings. Returns a float value between 0 and 1 representing the bag distance between `string1` and `string2`. The bag distance is meant to be an efficient approximation of the distance between two strings to quickly rule out strings that are largely different. The algorithm is outlined in the "String Matching with Metric Trees Using an Approximate Distance" paper by Ilaria Bartolini, Paolo Ciaccia, and Marco Patella. ### Examples - String.bag_distance/2 (function) iex> String.bag_distance("abc", "") 0.0 iex> String.bag_distance("abcd", "a") 0.25 iex> String.bag_distance("abcd", "ab") 0.5 iex> String.bag_distance("abcd", "abc") 0.75 iex> String.bag_distance("abcd", "abcd") 1.0 ### String.byte_slice/3 (function) Returns a substring starting at (or after) `start_bytes` and of at most the given `size_bytes`. This function works on bytes and then adjusts the string to eliminate truncated codepoints. This is useful when you have a string and you need to guarantee it does not exceed a certain amount of bytes. If the offset is greater than the number of bytes in the string, then it returns `""`. Similar to `String.slice/2`, a negative `start_bytes` will be adjusted to the end of the string (but in bytes). This function does not guarantee the string won't have invalid codepoints, it only guarantees to remove truncated codepoints immediately at the beginning or the end of the slice. ### Examples - String.byte_slice/3 (function) Consider the string "héllo". Let's see its representation: iex> inspect("héllo", binaries: :as_binaries) "<<104, 195, 169, 108, 108, 111>>" Although the string has 5 characters, it is made of 6 bytes. Now imagine we want to get only the first two bytes. To do so, let's use `binary_slice/3`, which is unaware of codepoints: iex> binary_slice("héllo", 0, 2) <<104, 195>> As you can see, this operation is unsafe and returns an invalid string. That's because we cut the string in the middle of the bytes representing "é". On the other hand, we could use `String.slice/3`: iex> String.slice("héllo", 0, 2) "hé" While the above is correct, it has 3 bytes. If you have a requirement where you need *at most* 2 bytes, the result would also be invalid. In such scenarios, you can use this function, which will slice the given bytes, but clean up the truncated codepoints: iex> String.byte_slice("héllo", 0, 2) "h" Truncated codepoints at the beginning are also cleaned up: iex> String.byte_slice("héllo", 2, 3) "llo" Note that, if you want to work on raw bytes, then you must use `binary_slice/3` instead. ### String.capitalize/2 (function) Converts the first character in the given string to uppercase and the remainder to lowercase according to `mode`. `mode` may be `:default`, `:ascii`, `:greek` or `:turkic`. The `:default` mode considers all non-conditional transformations outlined in the Unicode standard. `:ascii` capitalizes only the letters A to Z. `:greek` includes the context sensitive mappings found in Greek. `:turkic` properly handles the letter `i` with the dotless variant. Also see `upcase/2` and `capitalize/2` for other conversions. If you want a variation of this function that does not lowercase the rest of string, see Erlang's `:string.titlecase/1`. ### Examples - String.capitalize/2 (function) iex> String.capitalize("abcd") "Abcd" iex> String.capitalize("ABCD") "Abcd" iex> String.capitalize("fin") "Fin" iex> String.capitalize("olá") "Olá" ### String.chunk/2 (function) Splits the string into chunks of characters that share a common trait. The trait can be one of two options: * `:valid` - the string is split into chunks of valid and invalid character sequences * `:printable` - the string is split into chunks of printable and non-printable character sequences Returns a list of binaries each of which contains only one kind of characters. If the given string is empty, an empty list is returned. ### Examples - String.chunk/2 (function) iex> String.chunk(<>, :valid) ["abc\0"] iex> String.chunk(<>, :valid) ["abc\0", <<0xFFFF::utf16>>] iex> String.chunk(<>, :printable) ["abc", <<0, 0x0FFFF::utf8>>] ### String.codepoints/1 (function) Returns a list of code points encoded as strings. To retrieve code points in their natural integer representation, see `to_charlist/1`. For details about code points and graphemes, see the `String` module documentation. ### Examples - String.codepoints/1 (function) iex> String.codepoints("olá") ["o", "l", "á"] iex> String.codepoints("оптими зации") ["о", "п", "т", "и", "м", "и", " ", "з", "а", "ц", "и", "и"] iex> String.codepoints("ἅἪῼ") ["ἅ", "Ἢ", "ῼ"] iex> String.codepoints("\u00e9") ["é"] iex> String.codepoints("\u0065\u0301") ["e", "́"] ### String.contains?/2 (function) Searches if `string` contains any of the given `contents`. `contents` can be either a string, a list of strings, or a compiled pattern. If `contents` is a list, this function will search if any of the strings in `contents` are part of `string`. > #### Searching for a string in a list {: .tip} > > If you want to check if `string` is listed in `contents`, > where `contents` is a list, use `Enum.member?(contents, string)` > instead. ### Examples - String.contains?/2 (function) iex> String.contains?("elixir of life", "of") true iex> String.contains?("elixir of life", ["life", "death"]) true iex> String.contains?("elixir of life", ["death", "mercury"]) false The argument can also be a compiled pattern: iex> pattern = :binary.compile_pattern(["life", "death"]) iex> String.contains?("elixir of life", pattern) true An empty string will always match: iex> String.contains?("elixir of life", "") true iex> String.contains?("elixir of life", ["", "other"]) true An empty list will never match: iex> String.contains?("elixir of life", []) false iex> String.contains?("", []) false Be aware that this function can match within or across grapheme boundaries. For example, take the grapheme "é" which is made of the characters "e" and the acute accent. The following returns `true`: iex> String.contains?(String.normalize("é", :nfd), "e") true However, if "é" is represented by the single character "e with acute" accent, then it will return `false`: iex> String.contains?(String.normalize("é", :nfc), "e") false ### String.downcase/2 (function) Converts all characters in the given string to lowercase according to `mode`. `mode` may be `:default`, `:ascii`, `:greek` or `:turkic`. The `:default` mode considers all non-conditional transformations outlined in the Unicode standard. `:ascii` lowercases only the letters A to Z. `:greek` includes the context sensitive mappings found in Greek. `:turkic` properly handles the letter i with the dotless variant. Also see `upcase/2` and `capitalize/2` for other conversions. ### Examples - String.downcase/2 (function) iex> String.downcase("ABCD") "abcd" iex> String.downcase("AB 123 XPTO") "ab 123 xpto" iex> String.downcase("OLÁ") "olá" The `:ascii` mode ignores Unicode characters and provides a more performant implementation when you know the string contains only ASCII characters: iex> String.downcase("OLÁ", :ascii) "olÁ" The `:greek` mode properly handles the context sensitive sigma in Greek: iex> String.downcase("ΣΣ") "σσ" iex> String.downcase("ΣΣ", :greek) "σς" And `:turkic` properly handles the letter i with the dotless variant: iex> String.downcase("Iİ") "ii̇" iex> String.downcase("Iİ", :turkic) "ıi" ### String.duplicate/2 (function) Returns a string `subject` repeated `n` times. Inlined by the compiler. ### Examples - String.duplicate/2 (function) iex> String.duplicate("abc", 0) "" iex> String.duplicate("abc", 1) "abc" iex> String.duplicate("abc", 2) "abcabc" ### String.ends_with?/2 (function) Returns `true` if `string` ends with any of the suffixes given. `suffixes` can be either a single suffix or a list of suffixes. ### Examples - String.ends_with?/2 (function) iex> String.ends_with?("language", "age") true iex> String.ends_with?("language", ["youth", "age"]) true iex> String.ends_with?("language", ["youth", "elixir"]) false An empty suffix will always match: iex> String.ends_with?("language", "") true iex> String.ends_with?("language", ["", "other"]) true ### String.equivalent?/2 (function) Returns `true` if `string1` is canonically equivalent to `string2`. It performs Normalization Form Canonical Decomposition (NFD) on the strings before comparing them. This function is equivalent to: String.normalize(string1, :nfd) == String.normalize(string2, :nfd) If you plan to compare multiple strings, multiple times in a row, you may normalize them upfront and compare them directly to avoid multiple normalization passes. ### Examples - String.equivalent?/2 (function) iex> String.equivalent?("abc", "abc") true iex> String.equivalent?("man\u0303ana", "mañana") true iex> String.equivalent?("abc", "ABC") false iex> String.equivalent?("nø", "nó") false ### String.first/1 (function) Returns the first grapheme from a UTF-8 string, `nil` if the string is empty. ### Examples - String.first/1 (function) iex> String.first("elixir") "e" iex> String.first("եոգլի") "ե" iex> String.first("") nil ### String.graphemes/1 (function) Returns Unicode graphemes in the string as per Extended Grapheme Cluster algorithm. The algorithm is outlined in the [Unicode Standard Annex #29, Unicode Text Segmentation](https://www.unicode.org/reports/tr29/). For details about code points and graphemes, see the `String` module documentation. ### Examples - String.graphemes/1 (function) iex> String.graphemes("Ńaïve") ["Ń", "a", "ï", "v", "e"] iex> String.graphemes("\u00e9") ["é"] iex> String.graphemes("\u0065\u0301") ["é"] ### String.jaro_distance/2 (function) Computes the Jaro distance (similarity) between two strings. Returns a float value between `0.0` (equates to no similarity) and `1.0` (is an exact match) representing [Jaro](https://en.wikipedia.org/wiki/Jaro-Winkler_distance) distance between `string1` and `string2`. The Jaro distance metric is designed and best suited for short strings such as person names. Elixir itself uses this function to provide the "did you mean?" functionality. For instance, when you are calling a function in a module and you have a typo in the function name, we attempt to suggest the most similar function name available, if any, based on the `jaro_distance/2` score. ### Examples - String.jaro_distance/2 (function) iex> String.jaro_distance("Dwayne", "Duane") 0.8222222222222223 iex> String.jaro_distance("even", "odd") 0.0 iex> String.jaro_distance("same", "same") 1.0 ### String.last/1 (function) Returns the last grapheme from a UTF-8 string, `nil` if the string is empty. It traverses the whole string to find its last grapheme. ### Examples - String.last/1 (function) iex> String.last("") nil iex> String.last("elixir") "r" iex> String.last("եոգլի") "ի" ### String.length/1 (function) Returns the number of Unicode graphemes in a UTF-8 string. ### Examples - String.length/1 (function) iex> String.length("elixir") 6 iex> String.length("եոգլի") 5 ### String.match?/2 (function) Checks if `string` matches the given regular expression. ### Examples - String.match?/2 (function) iex> String.match?("foo", ~r/foo/) true iex> String.match?("bar", ~r/foo/) false Elixir also provides text-based match operator `=~/2` and function `Regex.match?/2` as alternatives to test strings against regular expressions. ### String.myers_difference/2 (function) Returns a keyword list that represents an edit script. Check `List.myers_difference/2` for more information. ### Examples - String.myers_difference/2 (function) iex> string1 = "fox hops over the dog" iex> string2 = "fox jumps over the lazy cat" iex> String.myers_difference(string1, string2) [eq: "fox ", del: "ho", ins: "jum", eq: "ps over the ", del: "dog", ins: "lazy cat"] ### String.next_codepoint/1 (function) Returns the next code point in a string. The result is a tuple with the code point and the remainder of the string or `nil` in case the string reached its end. As with other functions in the `String` module, `next_codepoint/1` works with binaries that are invalid UTF-8. If the string starts with a sequence of bytes that is not valid in UTF-8 encoding, the first element of the returned tuple is a binary with the first byte. ### Examples - String.next_codepoint/1 (function) iex> String.next_codepoint("olá") {"o", "lá"} iex> invalid = "\x80\x80OK" # first two bytes are invalid in UTF-8 iex> {_, rest} = String.next_codepoint(invalid) {<<128>>, <<128, 79, 75>>} iex> String.next_codepoint(rest) {<<128>>, "OK"} ### Comparison with binary pattern matching - String.next_codepoint/1 (function) Binary pattern matching provides a similar way to decompose a string: iex> < > = "Elixir" "Elixir" iex> codepoint 69 iex> rest "lixir" though not entirely equivalent because `codepoint` comes as an integer, and the pattern won't match invalid UTF-8. Binary pattern matching, however, is simpler and more efficient, so pick the option that better suits your use case. ### String.next_grapheme/1 (function) Returns the next grapheme in a string. The result is a tuple with the grapheme and the remainder of the string or `nil` in case the String reached its end. ### Examples - String.next_grapheme/1 (function) iex> String.next_grapheme("olá") {"o", "lá"} iex> String.next_grapheme("") nil ### String.next_grapheme_size/1 (function) Returns the size (in bytes) of the next grapheme. The result is a tuple with the next grapheme size in bytes and the remainder of the string or `nil` in case the string reached its end. ### Examples - String.next_grapheme_size/1 (function) iex> String.next_grapheme_size("olá") {1, "lá"} iex> String.next_grapheme_size("") nil ### String.normalize/2 (function) Converts all characters in `string` to Unicode normalization form identified by `form`. Invalid Unicode codepoints are skipped and the remaining of the string is converted. If you want the algorithm to stop and return on invalid codepoint, use `:unicode.characters_to_nfd_binary/1`, `:unicode.characters_to_nfc_binary/1`, `:unicode.characters_to_nfkd_binary/1`, and `:unicode.characters_to_nfkc_binary/1` instead. Normalization forms `:nfkc` and `:nfkd` should not be blindly applied to arbitrary text. Because they erase many formatting distinctions, they will prevent round-trip conversion to and from many legacy character sets. ### Forms - String.normalize/2 (function) The supported forms are: * `:nfd` - Normalization Form Canonical Decomposition. Characters are decomposed by canonical equivalence, and multiple combining characters are arranged in a specific order. * `:nfc` - Normalization Form Canonical Composition. Characters are decomposed and then recomposed by canonical equivalence. * `:nfkd` - Normalization Form Compatibility Decomposition. Characters are decomposed by compatibility equivalence, and multiple combining characters are arranged in a specific order. * `:nfkc` - Normalization Form Compatibility Composition. Characters are decomposed and then recomposed by compatibility equivalence. ### Examples - String.normalize/2 (function) iex> String.normalize("yêṩ", :nfd) "yêṩ" iex> String.normalize("leña", :nfc) "leña" iex> String.normalize("fi", :nfkd) "fi" iex> String.normalize("fi", :nfkc) "fi" ### String.pad_leading/3 (function) Returns a new string padded with a leading filler which is made of elements from the `padding`. Passing a list of strings as `padding` will take one element of the list for every missing entry. If the list is shorter than the number of inserts, the filling will start again from the beginning of the list. Passing a string `padding` is equivalent to passing the list of graphemes in it. If no `padding` is given, it defaults to whitespace. When `count` is less than or equal to the length of `string`, given `string` is returned. Raises `ArgumentError` if the given `padding` contains a non-string element. ### Examples - String.pad_leading/3 (function) iex> String.pad_leading("abc", 5) " abc" iex> String.pad_leading("abc", 4, "12") "1abc" iex> String.pad_leading("abc", 6, "12") "121abc" iex> String.pad_leading("abc", 5, ["1", "23"]) "123abc" ### String.pad_trailing/3 (function) Returns a new string padded with a trailing filler which is made of elements from the `padding`. Passing a list of strings as `padding` will take one element of the list for every missing entry. If the list is shorter than the number of inserts, the filling will start again from the beginning of the list. Passing a string `padding` is equivalent to passing the list of graphemes in it. If no `padding` is given, it defaults to whitespace. When `count` is less than or equal to the length of `string`, given `string` is returned. Raises `ArgumentError` if the given `padding` contains a non-string element. ### Examples - String.pad_trailing/3 (function) iex> String.pad_trailing("abc", 5) "abc " iex> String.pad_trailing("abc", 4, "12") "abc1" iex> String.pad_trailing("abc", 6, "12") "abc121" iex> String.pad_trailing("abc", 5, ["1", "23"]) "abc123" ### String.printable?/2 (function) Checks if a string contains only printable characters up to `character_limit`. Takes an optional `character_limit` as a second argument. If `character_limit` is `0`, this function will return `true`. ### Examples - String.printable?/2 (function) iex> String.printable?("abc") true iex> String.printable?("abc" <> <<0>>) false iex> String.printable?("abc" <> <<0>>, 2) true iex> String.printable?("abc" <> <<0>>, 0) true ### String.replace/4 (function) Returns a new string created by replacing occurrences of `pattern` in `subject` with `replacement`. The `subject` is always a string. The `pattern` may be a string, a list of strings, a regular expression, or a compiled pattern. The `replacement` may be a string or a function that receives the matched pattern and must return the replacement as a string or iodata. By default it replaces all occurrences but this behavior can be controlled through the `:global` option; see the "Options" section below. ### Options - String.replace/4 (function) * `:global` - (boolean) if `true`, all occurrences of `pattern` are replaced with `replacement`, otherwise only the first occurrence is replaced. Defaults to `true` ### Examples - String.replace/4 (function) iex> String.replace("a,b,c", ",", "-") "a-b-c" iex> String.replace("a,b,c", ",", "-", global: false) "a-b,c" The pattern may also be a list of strings and the replacement may also be a function that receives the matches: iex> String.replace("a,b,c", ["a", "c"], fn < > -> < > end) "b,b,d" When the pattern is a regular expression, one can give `\N` or `\g{N}` in the `replacement` string to access a specific capture in the regular expression: iex> String.replace("a,b,c", ~r/,(.)/, ",\\1\\g{1}") "a,bb,cc" Note that we had to escape the backslash escape character (i.e., we used `\\N` instead of just `\N` to escape the backslash; same thing for `\\g{N}`). By giving `\0`, one can inject the whole match in the replacement string. A compiled pattern can also be given: iex> pattern = :binary.compile_pattern(",") iex> String.replace("a,b,c", pattern, "[]") "a[]b[]c" When an empty string is provided as a `pattern`, the function will treat it as an implicit empty string between each grapheme and the string will be interspersed. If an empty string is provided as `replacement` the `subject` will be returned: iex> String.replace("ELIXIR", "", ".") ".E.L.I.X.I.R." iex> String.replace("ELIXIR", "", "") "ELIXIR" Be aware that this function can replace within or across grapheme boundaries. For example, take the grapheme "é" which is made of the characters "e" and the acute accent. The following will replace only the letter "e", moving the accent to the letter "o": iex> String.replace(String.normalize("é", :nfd), "e", "o") "ó" However, if "é" is represented by the single character "e with acute" accent, then it won't be replaced at all: iex> String.replace(String.normalize("é", :nfc), "e", "o") "é" ### String.replace_invalid/2 (function) Returns a new string created by replacing all invalid bytes with `replacement` (`"�"` by default). ### Examples - String.replace_invalid/2 (function) iex> String.replace_invalid("asd" <> <<0xFF::8>>) "asd�" iex> String.replace_invalid("nem rán bề bề") "nem rán bề bề" iex> String.replace_invalid("nem rán b" <> <<225, 187>> <> " bề") "nem rán b� bề" iex> String.replace_invalid("nem rán b" <> <<225, 187>> <> " bề", "ERROR!") "nem rán bERROR! bề" ### String.replace_leading/3 (function) Replaces all leading occurrences of `match` by `replacement` of `match` in `string`. Returns the string untouched if there are no occurrences. If `match` is `""`, this function raises an `ArgumentError` exception: this happens because this function replaces **all** the occurrences of `match` at the beginning of `string`, and it's impossible to replace "multiple" occurrences of `""`. ### Examples - String.replace_leading/3 (function) iex> String.replace_leading("hello world", "hello ", "") "world" iex> String.replace_leading("hello hello world", "hello ", "") "world" iex> String.replace_leading("hello world", "hello ", "ola ") "ola world" iex> String.replace_leading("hello hello world", "hello ", "ola ") "ola ola world" This function can replace across grapheme boundaries. See `replace/3` for more information and examples. ### String.replace_prefix/3 (function) Replaces prefix in `string` by `replacement` if it matches `match`. Returns the string untouched if there is no match. If `match` is an empty string (`""`), `replacement` is just prepended to `string`. ### Examples - String.replace_prefix/3 (function) iex> String.replace_prefix("world", "hello ", "") "world" iex> String.replace_prefix("hello world", "hello ", "") "world" iex> String.replace_prefix("hello hello world", "hello ", "") "hello world" iex> String.replace_prefix("world", "hello ", "ola ") "world" iex> String.replace_prefix("hello world", "hello ", "ola ") "ola world" iex> String.replace_prefix("hello hello world", "hello ", "ola ") "ola hello world" iex> String.replace_prefix("world", "", "hello ") "hello world" This function can replace across grapheme boundaries. See `replace/3` for more information and examples. ### String.replace_suffix/3 (function) Replaces suffix in `string` by `replacement` if it matches `match`. Returns the string untouched if there is no match. If `match` is an empty string (`""`), `replacement` is just appended to `string`. ### Examples - String.replace_suffix/3 (function) iex> String.replace_suffix("hello", " world", "") "hello" iex> String.replace_suffix("hello world", " world", "") "hello" iex> String.replace_suffix("hello world world", " world", "") "hello world" iex> String.replace_suffix("hello", " world", " mundo") "hello" iex> String.replace_suffix("hello world", " world", " mundo") "hello mundo" iex> String.replace_suffix("hello world world", " world", " mundo") "hello world mundo" iex> String.replace_suffix("hello", "", " world") "hello world" This function can replace across grapheme boundaries. See `replace/3` for more information and examples. ### String.replace_trailing/3 (function) Replaces all trailing occurrences of `match` by `replacement` in `string`. Returns the string untouched if there are no occurrences. If `match` is `""`, this function raises an `ArgumentError` exception: this happens because this function replaces **all** the occurrences of `match` at the end of `string`, and it's impossible to replace "multiple" occurrences of `""`. ### Examples - String.replace_trailing/3 (function) iex> String.replace_trailing("hello world", " world", "") "hello" iex> String.replace_trailing("hello world world", " world", "") "hello" iex> String.replace_trailing("hello world", " world", " mundo") "hello mundo" iex> String.replace_trailing("hello world world", " world", " mundo") "hello mundo mundo" This function can replace across grapheme boundaries. See `replace/3` for more information and examples. ### String.reverse/1 (function) Reverses the graphemes in given string. ### Examples - String.reverse/1 (function) iex> String.reverse("abcd") "dcba" iex> String.reverse("hello world") "dlrow olleh" iex> String.reverse("hello ∂og") "go∂ olleh" Keep in mind reversing the same string twice does not necessarily yield the original string: iex> "̀e" "̀e" iex> String.reverse("̀e") "è" iex> String.reverse(String.reverse("̀e")) "è" In the first example the accent is before the vowel, so it is considered two graphemes. However, when you reverse it once, you have the vowel followed by the accent, which becomes one grapheme. Reversing it again will keep it as one single grapheme. ### String.slice/2 (function) Returns a substring from the offset given by the start of the range to the offset given by the end of the range. This function works on Unicode graphemes. For example, slicing the first three characters of the string "héllo" will return "hél", which internally is represented by more than three bytes. Use `String.byte_slice/3` if you want to slice by a given number of bytes, while respecting the codepoint boundaries. If you want to work on raw bytes, check `Kernel.binary_part/3` or `Kernel.binary_slice/3` instead. If the start of the range is not a valid offset for the given string or if the range is in reverse order, returns `""`. If the start or end of the range is negative, the whole string is traversed first in order to convert the negative indices into positive ones. ### Examples - String.slice/2 (function) iex> String.slice("elixir", 1..3) "lix" iex> String.slice("elixir", 1..10) "lixir" iex> String.slice("elixir", -4..-1) "ixir" iex> String.slice("elixir", -4..6) "ixir" iex> String.slice("elixir", -100..100) "elixir" For ranges where `start > stop`, you need to explicitly mark them as increasing: iex> String.slice("elixir", 2..-1//1) "ixir" iex> String.slice("elixir", 1..-2//1) "lixi" You can use `../0` as a shortcut for `0..-1//1`, which returns the whole string as is: iex> String.slice("elixir", ..) "elixir" The step can be any positive number. For example, to get every 2 characters of the string: iex> String.slice("elixir", 0..-1//2) "eii" If the first position is after the string ends or after the last position of the range, it returns an empty string: iex> String.slice("elixir", 10..3//1) "" iex> String.slice("a", 1..1500) "" ### String.slice/3 (function) Returns a substring starting at the offset `start`, and of the given `length`. This function works on Unicode graphemes. For example, slicing the first three characters of the string "héllo" will return "hél", which internally is represented by more than three bytes. Use `String.byte_slice/3` if you want to slice by a given number of bytes, while respecting the codepoint boundaries. If you want to work on raw bytes, check `Kernel.binary_part/3` or `Kernel.binary_slice/3` instead. If the offset is greater than string length, then it returns `""`. ### Examples - String.slice/3 (function) iex> String.slice("elixir", 1, 3) "lix" iex> String.slice("elixir", 1, 10) "lixir" iex> String.slice("elixir", 10, 3) "" If the start position is negative, it is normalized against the string length and clamped to 0: iex> String.slice("elixir", -4, 4) "ixir" iex> String.slice("elixir", -10, 3) "eli" If start is more than the string length, an empty string is returned: iex> String.slice("elixir", 10, 1500) "" ### String.split/1 (function) Divides a string into substrings at each Unicode whitespace occurrence with leading and trailing whitespace ignored. Groups of whitespace are treated as a single occurrence. Divisions do not occur on non-breaking whitespace. ### Examples - String.split/1 (function) iex> String.split("foo bar") ["foo", "bar"] iex> String.split("foo" <> <<194, 133>> <> "bar") ["foo", "bar"] iex> String.split(" foo bar ") ["foo", "bar"] iex> String.split("no\u00a0break") ["no\u00a0break"] Removes empty strings, like when using `trim: true` in `String.split/3`. iex> String.split(" ") [] ### String.split/3 (function) Divides a string into parts based on a pattern. Returns a list of these parts. The `pattern` may be a string, a list of strings, a regular expression, or a compiled pattern. The string is split into as many parts as possible by default, but can be controlled via the `:parts` option. Empty strings are only removed from the result if the `:trim` option is set to `true`. When the pattern used is a regular expression, the string is split using `Regex.split/3`. If the pattern cannot be found, a list containing the original string will be returned. ### Options - String.split/3 (function) * `:parts` (positive integer or `:infinity`) - the string is split into at most as many parts as this option specifies. If `:infinity`, the string will be split into all possible parts. Defaults to `:infinity`. * `:trim` (boolean) - if `true`, empty strings are removed from the resulting list. This function also accepts all options accepted by `Regex.split/3` if `pattern` is a regular expression. ### Examples - String.split/3 (function) Splitting with a string pattern: iex> String.split("a,b,c", ",") ["a", "b", "c"] iex> String.split("a,b,c", ",", parts: 2) ["a", "b,c"] iex> String.split(" a b c ", " ", trim: true) ["a", "b", "c"] A list of patterns: iex> String.split("1,2 3,4", [" ", ","]) ["1", "2", "3", "4"] A regular expression: iex> String.split("a,b,c", ~r{,}) ["a", "b", "c"] iex> String.split("a,b,c", ~r{,}, parts: 2) ["a", "b,c"] iex> String.split(" a b c ", ~r{\s}, trim: true) ["a", "b", "c"] iex> String.split("abc", ~r{b}, include_captures: true) ["a", "b", "c"] A compiled pattern: iex> pattern = :binary.compile_pattern([" ", ","]) iex> String.split("1,2 3,4", pattern) ["1", "2", "3", "4"] Splitting on empty string returns graphemes: iex> String.split("abc", "") ["", "a", "b", "c", ""] iex> String.split("abc", "", trim: true) ["a", "b", "c"] iex> String.split("abc", "", parts: 1) ["abc"] iex> String.split("abc", "", parts: 3) ["", "a", "bc"] Splitting on an non-existing pattern returns the original string: iex> String.split("abc", ",") ["abc"] Be aware that this function can split within or across grapheme boundaries. For example, take the grapheme "é" which is made of the characters "e" and the acute accent. The following will split the string into two parts: iex> String.split(String.normalize("é", :nfd), "e") ["", "́"] However, if "é" is represented by the single character "e with acute" accent, then it will split the string into just one part: iex> String.split(String.normalize("é", :nfc), "e") ["é"] ### String.split_at/2 (function) Splits a string into two at the specified offset. When the offset given is negative, location is counted from the end of the string. The offset is capped to the length of the string. Returns a tuple with two elements. > #### Linear Access {: .warning} > > This function splits on graphemes and for such it has to linearly traverse > the string. > If you want to split a string or a binary based on the number of bytes, > use `Kernel.binary_part/3` instead. ### Examples - String.split_at/2 (function) iex> String.split_at("sweetelixir", 5) {"sweet", "elixir"} iex> String.split_at("sweetelixir", -6) {"sweet", "elixir"} iex> String.split_at("abc", 0) {"", "abc"} iex> String.split_at("abc", 1000) {"abc", ""} iex> String.split_at("abc", -1000) {"", "abc"} ### String.splitter/3 (function) Returns an enumerable that splits a string on demand. This is in contrast to `split/3` which splits the entire string upfront. This function does not support regular expressions by design. When using regular expressions, it is often more efficient to have the regular expressions traverse the string at once than in parts, like this function does. ### Options - String.splitter/3 (function) * :trim - when `true`, does not emit empty patterns ### Examples - String.splitter/3 (function) iex> String.splitter("1,2 3,4 5,6 7,8,...,99999", [" ", ","]) |> Enum.take(4) ["1", "2", "3", "4"] iex> String.splitter("abcd", "") |> Enum.take(10) ["", "a", "b", "c", "d", ""] iex> String.splitter("abcd", "", trim: true) |> Enum.take(10) ["a", "b", "c", "d"] A compiled pattern can also be given: iex> pattern = :binary.compile_pattern([" ", ","]) iex> String.splitter("1,2 3,4 5,6 7,8,...,99999", pattern) |> Enum.take(4) ["1", "2", "3", "4"] ### String.starts_with?/2 (function) Returns `true` if `string` starts with any of the prefixes given. `prefix` can be either a string, a list of strings, or a compiled pattern. ### Examples - String.starts_with?/2 (function) iex> String.starts_with?("elixir", "eli") true iex> String.starts_with?("elixir", ["erlang", "elixir"]) true iex> String.starts_with?("elixir", ["erlang", "ruby"]) false An empty string will always match: iex> String.starts_with?("elixir", "") true iex> String.starts_with?("elixir", ["", "other"]) true An empty list will never match: iex> String.starts_with?("elixir", []) false iex> String.starts_with?("", []) false ### String.to_atom/1 (function) Converts a string to an existing atom or creates a new one. Warning: this function creates atoms dynamically and atoms are not garbage-collected. Therefore, `string` should not be an untrusted value, such as input received from a socket or during a web request. Consider using `to_existing_atom/1` instead. By default, the maximum number of atoms is `1_048_576`. This limit can be raised or lowered using the VM option `+t`. The maximum atom size is of 255 Unicode code points. Inlined by the compiler. ### Examples - String.to_atom/1 (function) iex> String.to_atom("my_atom") :my_atom ### String.to_charlist/1 (function) Converts a string into a charlist. Specifically, this function takes a UTF-8 encoded binary and returns a list of its integer code points. It is similar to `codepoints/1` except that the latter returns a list of code points as strings. In case you need to work with bytes, take a look at the [`:binary` module](`:binary`). ### Examples - String.to_charlist/1 (function) iex> String.to_charlist("foo") ~c"foo" ### String.to_existing_atom/1 (function) Converts a string to an existing atom or raises if the atom does not exist. The maximum atom size is of 255 Unicode code points. Raises an `ArgumentError` if the atom does not exist. Inlined by the compiler. > #### Atoms and modules {: .info} > > Since Elixir is a compiled language, the atoms defined in a module > will only exist after said module is loaded, which typically happens > whenever a function in the module is executed. Therefore, it is > generally recommended to call `String.to_existing_atom/1` only to > convert atoms defined within the module making the function call > to `to_existing_atom/1`. > > To create a module name itself from a string safely, > it is recommended to use `Module.safe_concat/1`. ### Examples - String.to_existing_atom/1 (function) iex> _ = :my_atom iex> String.to_existing_atom("my_atom") :my_atom ### String.to_float/1 (function) Returns a float whose text representation is `string`. `string` must be the string representation of a float including leading digits and a decimal point. To parse a string without decimal point as a float, refer to `Float.parse/1`. Otherwise, an `ArgumentError` will be raised. Inlined by the compiler. ### Examples - String.to_float/1 (function) iex> String.to_float("2.2017764e+0") 2.2017764 iex> String.to_float("3.0") 3.0 String.to_float("3") ** (ArgumentError) argument error String.to_float(".3") ** (ArgumentError) argument error ### String.to_integer/1 (function) Returns an integer whose text representation is `string`. `string` must be the string representation of an integer. Otherwise, an `ArgumentError` will be raised. If you want to parse a string that may contain an ill-formatted integer, use `Integer.parse/1`. Inlined by the compiler. ### Examples - String.to_integer/1 (function) iex> String.to_integer("123") 123 Passing a string that does not represent an integer leads to an error: String.to_integer("invalid data") ** (ArgumentError) argument error ### String.to_integer/2 (function) Returns an integer whose text representation is `string` in base `base`. Inlined by the compiler. ### Examples - String.to_integer/2 (function) iex> String.to_integer("3FF", 16) 1023 ### String.trim/1 (function) Returns a string where all leading and trailing Unicode whitespaces have been removed. ### Examples - String.trim/1 (function) iex> String.trim("\n abc\n ") "abc" ### String.trim/2 (function) Returns a string where all leading and trailing `to_trim` characters have been removed. ### Examples - String.trim/2 (function) iex> String.trim("a abc a", "a") " abc " ### String.trim_leading/1 (function) Returns a string where all leading Unicode whitespaces have been removed. ### Examples - String.trim_leading/1 (function) iex> String.trim_leading("\n abc ") "abc " ### String.trim_leading/2 (function) Returns a string where all leading `to_trim` characters have been removed. ### Examples - String.trim_leading/2 (function) iex> String.trim_leading("__ abc _", "_") " abc _" iex> String.trim_leading("1 abc", "11") "1 abc" ### String.trim_trailing/1 (function) Returns a string where all trailing Unicode whitespaces has been removed. ### Examples - String.trim_trailing/1 (function) iex> String.trim_trailing(" abc\n ") " abc" ### String.trim_trailing/2 (function) Returns a string where all trailing `to_trim` characters have been removed. ### Examples - String.trim_trailing/2 (function) iex> String.trim_trailing("_ abc __", "_") "_ abc " iex> String.trim_trailing("abc 1", "11") "abc 1" ### String.upcase/2 (function) Converts all characters in the given string to uppercase according to `mode`. `mode` may be `:default`, `:ascii`, `:greek` or `:turkic`. The `:default` mode considers all non-conditional transformations outlined in the Unicode standard. `:ascii` uppercases only the letters a to z. `:greek` includes the context sensitive mappings found in Greek. `:turkic` properly handles the letter i with the dotless variant. ### Examples - String.upcase/2 (function) iex> String.upcase("abcd") "ABCD" iex> String.upcase("ab 123 xpto") "AB 123 XPTO" iex> String.upcase("olá") "OLÁ" The `:ascii` mode ignores Unicode characters and provides a more performant implementation when you know the string contains only ASCII characters: iex> String.upcase("olá", :ascii) "OLá" And `:turkic` properly handles the letter i with the dotless variant: iex> String.upcase("ıi") "II" iex> String.upcase("ıi", :turkic) "Iİ" Also see `downcase/2` and `capitalize/2` for other conversions. ### String.valid?/2 (function) Checks whether `string` contains only valid characters. `algorithm` may be `:default` or `:fast_ascii`. Both algorithms are equivalent from a validation perspective (they will always produce the same output), but `:fast_ascii` can yield significant performance benefits in specific scenarios. If all of the following conditions are true, you may want to experiment with the `:fast_ascii` algorithm to see if it yields performance benefits in your specific scenario: * You are running Erlang/OTP 26 or newer on a 64 bit platform * You expect most of your strings to be longer than ~64 bytes * You expect most of your strings to contain mostly ASCII codepoints Note that the `:fast_ascii` algorithm does not affect correctness, you can expect the output of `String.valid?/2` to be the same regardless of algorithm. The only difference to be expected is one of performance, which can be expected to improve roughly linearly in string length compared to the `:default` algorithm. ### Examples - String.valid?/2 (function) iex> String.valid?("a") true iex> String.valid?("ø") true iex> String.valid?(<<0xFFFF::16>>) false iex> String.valid?(<<0xEF, 0xB7, 0x90>>) true iex> String.valid?("asd" <> <<0xFFFF::16>>) false iex> String.valid?("a", :fast_ascii) true iex> String.valid?(4) ** (FunctionClauseError) no function clause matching in String.valid?/2 ### String.codepoint/0 (type) A single Unicode code point encoded in UTF-8. It may be one or more bytes. ### String.grapheme/0 (type) Multiple code points that may be perceived as a single character by readers ### String.pattern/0 (type) Pattern used in functions like `replace/4` and `split/3`. It must be one of: * a string * an empty list * a list containing non-empty strings * a compiled search pattern created by `:binary.compile_pattern/1` ### String.t/0 (type) A UTF-8 encoded binary. The types `String.t()` and `binary()` are equivalent to analysis tools. Although, for those reading the documentation, `String.t()` implies it is a UTF-8 encoded binary. ### Time (module) A Time struct and functions. The Time struct contains the fields hour, minute, second and microseconds. New times can be built with the `new/4` function or using the `~T` (see `sigil_T/2`) sigil: iex> ~T[23:00:07.001] ~T[23:00:07.001] Both `new/4` and sigil return a struct where the time fields can be accessed directly: iex> time = ~T[23:00:07.001] iex> time.hour 23 iex> time.microsecond {1000, 3} The functions on this module work with the `Time` struct as well as any struct that contains the same fields as the `Time` struct, such as `NaiveDateTime` and `DateTime`. Such functions expect `t:Calendar.time/0` in their typespecs (instead of `t:t/0`). Developers should avoid creating the Time structs directly and instead rely on the functions provided by this module as well as the ones in third-party calendar libraries. ### Comparing times - Time (module) Comparisons in Elixir using `==/2`, `>/2`, ` Enum.min([~T[23:00:07.001], ~T[10:00:07.001]], Time) ~T[10:00:07.001] ### Time.add/3 (function) Adds the `amount_to_add` of `unit`s to the given `time`. Accepts an `amount_to_add` in any `unit`. `unit` can be `:hour`, `:minute`, `:second` or any subsecond precision from `t:System.time_unit/0`. It defaults to `:second`. Negative values will move backwards in time. This function always consider the unit to be computed according to the `Calendar.ISO`. Note the result value represents the time of day, meaning that it is cyclic, for instance, it will never go over 24 hours for the ISO calendar. ### Examples - Time.add/3 (function) iex> Time.add(~T[10:00:00], 27000) ~T[17:30:00] iex> Time.add(~T[11:00:00.005], 2400) ~T[11:40:00.005] iex> Time.add(~T[00:00:00.000], 86_399_999, :millisecond) ~T[23:59:59.999] Negative values are allowed: iex> Time.add(~T[23:00:00], -60) ~T[22:59:00] Note that the time is cyclic: iex> Time.add(~T[17:10:05], 86400) ~T[17:10:05] Hours and minutes are also supported: iex> Time.add(~T[17:10:05], 2, :hour) ~T[19:10:05] iex> Time.add(~T[17:10:05], 30, :minute) ~T[17:40:05] This operation merges the precision of the time with the given unit: iex> result = Time.add(~T[00:29:10], 21, :millisecond) ~T[00:29:10.021] iex> result.microsecond {21000, 3} To shift a time by a `Duration` and according to its underlying calendar, use `Time.shift/2`. ### Time.after?/2 (function) Returns `true` if the first time is strictly later than the second. ### Examples - Time.after?/2 (function) iex> Time.after?(~T[16:04:28], ~T[16:04:16]) true iex> Time.after?(~T[16:04:16], ~T[16:04:16]) false iex> Time.after?(~T[16:04:16.001], ~T[16:04:16.01]) false ### Time.before?/2 (function) Returns `true` if the first time is strictly earlier than the second. ### Examples - Time.before?/2 (function) iex> Time.before?(~T[16:04:16], ~T[16:04:28]) true iex> Time.before?(~T[16:04:16], ~T[16:04:16]) false iex> Time.before?(~T[16:04:16.01], ~T[16:04:16.001]) false ### Time.compare/2 (function) Compares two time structs. Returns `:gt` if first time is later than the second and `:lt` for vice versa. If the two times are equal `:eq` is returned. ### Examples - Time.compare/2 (function) iex> Time.compare(~T[16:04:16], ~T[16:04:28]) :lt iex> Time.compare(~T[16:04:16], ~T[16:04:16]) :eq iex> Time.compare(~T[16:04:16.01], ~T[16:04:16.001]) :gt This function can also be used to compare across more complex calendar types by considering only the time fields: iex> Time.compare(~N[1900-01-01 16:04:16], ~N[2015-01-01 16:04:16]) :eq iex> Time.compare(~N[2015-01-01 16:04:16], ~N[2015-01-01 16:04:28]) :lt iex> Time.compare(~N[2015-01-01 16:04:16.01], ~N[2000-01-01 16:04:16.001]) :gt ### Time.convert/2 (function) Converts given `time` to a different calendar. Returns `{:ok, time}` if the conversion was successful, or `{:error, reason}` if it was not, for some reason. ### Examples - Time.convert/2 (function) Imagine someone implements `Calendar.Holocene`, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year: iex> Time.convert(~T[13:30:15], Calendar.Holocene) {:ok, %Time{calendar: Calendar.Holocene, hour: 13, minute: 30, second: 15, microsecond: {0, 0}}} ### Time.convert!/2 (function) Similar to `Time.convert/2`, but raises an `ArgumentError` if the conversion between the two calendars is not possible. ### Examples - Time.convert!/2 (function) Imagine someone implements `Calendar.Holocene`, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year: iex> Time.convert!(~T[13:30:15], Calendar.Holocene) %Time{calendar: Calendar.Holocene, hour: 13, minute: 30, second: 15, microsecond: {0, 0}} ### Time.diff/3 (function) Returns the difference between two times, considering only the hour, minute, second and microsecond. As with the `compare/2` function both `Time` structs and other structures containing time can be used. If for instance a `NaiveDateTime` or `DateTime` is passed, only the hour, minute, second, and microsecond is considered. Any additional information about a date or time zone is ignored when calculating the difference. The answer can be returned in any `:hour`, `:minute`, `:second` or any subsecond `unit` available from `t:System.time_unit/0`. If the first time value is earlier than the second, a negative number is returned. The unit is measured according to `Calendar.ISO` and defaults to `:second`. Fractional results are not supported and are truncated. ### Examples - Time.diff/3 (function) iex> Time.diff(~T[00:29:12], ~T[00:29:10]) 2 # When passing a `NaiveDateTime` the date part is ignored. iex> Time.diff(~N[2017-01-01 00:29:12], ~T[00:29:10]) 2 # Two `NaiveDateTime` structs could have big differences in the date # but only the time part is considered. iex> Time.diff(~N[2017-01-01 00:29:12], ~N[1900-02-03 00:29:10]) 2 iex> Time.diff(~T[00:29:12], ~T[00:29:10], :microsecond) 2_000_000 iex> Time.diff(~T[00:29:10], ~T[00:29:12], :microsecond) -2_000_000 iex> Time.diff(~T[02:29:10], ~T[00:29:10], :hour) 2 iex> Time.diff(~T[02:29:10], ~T[00:29:11], :hour) 1 ### Time.from_erl/3 (function) Converts an Erlang time tuple to a `Time` struct. ### Examples - Time.from_erl/3 (function) iex> Time.from_erl({23, 30, 15}) {:ok, ~T[23:30:15]} iex> Time.from_erl({23, 30, 15}, 5000) {:ok, ~T[23:30:15.005000]} iex> Time.from_erl({23, 30, 15}, {5000, 3}) {:ok, ~T[23:30:15.005]} iex> Time.from_erl({24, 30, 15}) {:error, :invalid_time} ### Time.from_erl!/3 (function) Converts an Erlang time tuple to a `Time` struct. ### Examples - Time.from_erl!/3 (function) iex> Time.from_erl!({23, 30, 15}) ~T[23:30:15] iex> Time.from_erl!({23, 30, 15}, 5000) ~T[23:30:15.005000] iex> Time.from_erl!({23, 30, 15}, {5000, 3}) ~T[23:30:15.005] iex> Time.from_erl!({24, 30, 15}) ** (ArgumentError) cannot convert {24, 30, 15} to time, reason: :invalid_time ### Time.from_iso8601/2 (function) Parses the extended "Local time" format described by [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). Time zone offset may be included in the string but they will be simply discarded as such information is not included in times. As specified in the standard, the separator "T" may be omitted if desired as there is no ambiguity within this function. ### Examples - Time.from_iso8601/2 (function) iex> Time.from_iso8601("23:50:07") {:ok, ~T[23:50:07]} iex> Time.from_iso8601("23:50:07Z") {:ok, ~T[23:50:07]} iex> Time.from_iso8601("T23:50:07Z") {:ok, ~T[23:50:07]} iex> Time.from_iso8601("23:50:07,0123456") {:ok, ~T[23:50:07.012345]} iex> Time.from_iso8601("23:50:07.0123456") {:ok, ~T[23:50:07.012345]} iex> Time.from_iso8601("23:50:07.123Z") {:ok, ~T[23:50:07.123]} iex> Time.from_iso8601("2015:01:23 23-50-07") {:error, :invalid_format} iex> Time.from_iso8601("23:50:07A") {:error, :invalid_format} iex> Time.from_iso8601("23:50:07.") {:error, :invalid_format} iex> Time.from_iso8601("23:50:61") {:error, :invalid_time} ### Time.from_iso8601!/2 (function) Parses the extended "Local time" format described by [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). Raises if the format is invalid. ### Examples - Time.from_iso8601!/2 (function) iex> Time.from_iso8601!("23:50:07,123Z") ~T[23:50:07.123] iex> Time.from_iso8601!("23:50:07.123Z") ~T[23:50:07.123] iex> Time.from_iso8601!("2015:01:23 23-50-07") ** (ArgumentError) cannot parse "2015:01:23 23-50-07" as time, reason: :invalid_format ### Time.from_seconds_after_midnight/3 (function) Converts a number of seconds after midnight to a `Time` struct. ### Examples - Time.from_seconds_after_midnight/3 (function) iex> Time.from_seconds_after_midnight(10_000) ~T[02:46:40] iex> Time.from_seconds_after_midnight(30_000, {5000, 3}) ~T[08:20:00.005] iex> Time.from_seconds_after_midnight(-1) ~T[23:59:59] iex> Time.from_seconds_after_midnight(100_000) ~T[03:46:40] ### Time.new/5 (function) Builds a new time. Expects all values to be integers. Returns `{:ok, time}` if each entry fits its appropriate range, returns `{:error, reason}` otherwise. Microseconds can also be given with a precision, which must be an integer between 0 and 6. The built-in calendar does not support leap seconds. ### Examples - Time.new/5 (function) iex> Time.new(0, 0, 0, 0) {:ok, ~T[00:00:00.000000]} iex> Time.new(23, 59, 59, 999_999) {:ok, ~T[23:59:59.999999]} iex> Time.new(24, 59, 59, 999_999) {:error, :invalid_time} iex> Time.new(23, 60, 59, 999_999) {:error, :invalid_time} iex> Time.new(23, 59, 60, 999_999) {:error, :invalid_time} iex> Time.new(23, 59, 59, 1_000_000) {:error, :invalid_time} # Invalid precision Time.new(23, 59, 59, {999_999, 10}) {:error, :invalid_time} ### Time.new!/5 (function) Builds a new time. Expects all values to be integers. Returns `time` if each entry fits its appropriate range, raises if the time is invalid. Microseconds can also be given with a precision, which must be an integer between 0 and 6. The built-in calendar does not support leap seconds. ### Examples - Time.new!/5 (function) iex> Time.new!(0, 0, 0, 0) ~T[00:00:00.000000] iex> Time.new!(23, 59, 59, 999_999) ~T[23:59:59.999999] iex> Time.new!(24, 59, 59, 999_999) ** (ArgumentError) cannot build time, reason: :invalid_time ### Time.shift/2 (function) Shifts given `time` by `duration` according to its calendar. Available duration units are: `:hour`, `:minute`, `:second`, `:microsecond`. When using the default ISO calendar, durations are collapsed to seconds and microseconds before they are applied. Raises an `ArgumentError` when called with date scale units. ### Examples - Time.shift/2 (function) iex> Time.shift(~T[01:00:15], hour: 12) ~T[13:00:15] iex> Time.shift(~T[01:35:00], hour: 6, minute: -15) ~T[07:20:00] iex> Time.shift(~T[01:15:00], second: 125) ~T[01:17:05] iex> Time.shift(~T[01:00:15], microsecond: {100, 6}) ~T[01:00:15.000100] iex> Time.shift(~T[01:15:00], Duration.new!(second: 65)) ~T[01:16:05] ### Time.to_erl/1 (function) Converts given `time` to an Erlang time tuple. WARNING: Loss of precision may occur, as Erlang time tuples only contain hours/minutes/seconds. ### Examples - Time.to_erl/1 (function) iex> Time.to_erl(~T[23:30:15.999]) {23, 30, 15} iex> Time.to_erl(~N[2010-04-17 23:30:15.999]) {23, 30, 15} ### Time.to_iso8601/2 (function) Converts the given time to [ISO 8601:2019](https://en.wikipedia.org/wiki/ISO_8601). By default, `Time.to_iso8601/2` returns times formatted in the "extended" format, for human readability. It also supports the "basic" format through passing the `:basic` option. ### Examples - Time.to_iso8601/2 (function) iex> Time.to_iso8601(~T[23:00:13]) "23:00:13" iex> Time.to_iso8601(~T[23:00:13.001]) "23:00:13.001" iex> Time.to_iso8601(~T[23:00:13.001], :basic) "230013.001" iex> Time.to_iso8601(~N[2010-04-17 23:00:13]) "23:00:13" ### Time.to_seconds_after_midnight/1 (function) Converts a `Time` struct to a number of seconds after midnight. The returned value is a two-element tuple with the number of seconds and microseconds. ### Examples - Time.to_seconds_after_midnight/1 (function) iex> Time.to_seconds_after_midnight(~T[23:30:15]) {84615, 0} iex> Time.to_seconds_after_midnight(~N[2010-04-17 23:30:15.999]) {84615, 999000} ### Time.to_string/1 (function) Converts the given `time` to a string. ### Examples - Time.to_string/1 (function) iex> Time.to_string(~T[23:00:00]) "23:00:00" iex> Time.to_string(~T[23:00:00.001]) "23:00:00.001" iex> Time.to_string(~T[23:00:00.123456]) "23:00:00.123456" iex> Time.to_string(~N[2015-01-01 23:00:00.001]) "23:00:00.001" iex> Time.to_string(~N[2015-01-01 23:00:00.123456]) "23:00:00.123456" ### Time.truncate/2 (function) Returns the given time with the microsecond field truncated to the given precision (`:microsecond`, `millisecond` or `:second`). The given time is returned unchanged if it already has lower precision than the given precision. ### Examples - Time.truncate/2 (function) iex> Time.truncate(~T[01:01:01.123456], :microsecond) ~T[01:01:01.123456] iex> Time.truncate(~T[01:01:01.123456], :millisecond) ~T[01:01:01.123] iex> Time.truncate(~T[01:01:01.123456], :second) ~T[01:01:01] ### Time.utc_now/1 (function) Returns the current time in UTC. ### Examples - Time.utc_now/1 (function) iex> time = Time.utc_now() iex> time.hour >= 0 true ### Time.t/0 (type) ### Tuple (module) Functions for working with tuples. Please note the following functions for tuples are found in `Kernel`: * `elem/2` - accesses a tuple by index * `put_elem/3` - inserts a value into a tuple by index * `tuple_size/1` - gets the number of elements in a tuple Tuples are intended as fixed-size containers for multiple elements. To manipulate a collection of elements, use a list instead. `Enum` functions do not work on tuples. Tuples are denoted with curly braces: iex> {} {} iex> {1, :two, "three"} {1, :two, "three"} A tuple may contain elements of different types, which are stored contiguously in memory. Accessing any element takes constant time, but modifying a tuple, which produces a shallow copy, takes linear time. Tuples are good for reading data while lists are better for traversals. Tuples are typically used either when a function has multiple return values or for error handling. `File.read/1` returns `{:ok, contents}` if reading the given file is successful, or else `{:error, reason}` such as when the file does not exist. The functions in this module that add and remove elements from tuples are rarely used in practice, as they typically imply tuples are being used as collections. To append to a tuple, it is preferable to extract the elements from the old tuple with pattern matching, and then create a new tuple: tuple = {:ok, :example} # Avoid result = Tuple.insert_at(tuple, 2, %{}) # Prefer {:ok, atom} = tuple result = {:ok, atom, %{}} ### Tuple.delete_at/2 (function) Removes an element from a tuple. Deletes the element at the given `index` from `tuple`. Raises an `ArgumentError` if `index` is negative or greater than or equal to the length of `tuple`. Index is zero-based. Inlined by the compiler. ### Examples - Tuple.delete_at/2 (function) iex> tuple = {:foo, :bar, :baz} iex> Tuple.delete_at(tuple, 0) {:bar, :baz} ### Tuple.duplicate/2 (function) Creates a new tuple. Creates a tuple of `size` containing the given `data` at every position. Inlined by the compiler. ### Examples - Tuple.duplicate/2 (function) iex> Tuple.duplicate(:hello, 3) {:hello, :hello, :hello} ### Tuple.insert_at/3 (function) Inserts an element into a tuple. Inserts `value` into `tuple` at the given `index`. Raises an `ArgumentError` if `index` is negative or greater than the length of `tuple`. Index is zero-based. Inlined by the compiler. ### Examples - Tuple.insert_at/3 (function) iex> tuple = {:bar, :baz} iex> Tuple.insert_at(tuple, 0, :foo) {:foo, :bar, :baz} iex> Tuple.insert_at(tuple, 2, :bong) {:bar, :baz, :bong} ### Tuple.product/1 (function) Computes a product of tuple elements. ### Examples - Tuple.product/1 (function) iex> Tuple.product({255, 255}) 65025 iex> Tuple.product({255, 1.0}) 255.0 iex> Tuple.product({}) 1 ### Tuple.sum/1 (function) Computes a sum of tuple elements. ### Examples - Tuple.sum/1 (function) iex> Tuple.sum({255, 255}) 510 iex> Tuple.sum({255, 0.0}) 255.0 iex> Tuple.sum({}) 0 ### Tuple.to_list/1 (function) Converts a tuple to a list. Returns a new list with all the tuple elements. Inlined by the compiler. ### Examples - Tuple.to_list/1 (function) iex> tuple = {:foo, :bar, :baz} iex> Tuple.to_list(tuple) [:foo, :bar, :baz] ### URI (module) Utilities for working with URIs. This module provides functions for working with URIs (for example, parsing URIs or encoding query strings). The functions in this module are implemented according to [RFC 3986](https://tools.ietf.org/html/rfc3986). Additionally, the Erlang [`:uri_string` module](`:uri_string`) provides certain functionalities, such as RFC 3986 compliant URI normalization. ### URI.__struct__/0 (function) The URI struct. The fields are defined to match the following URI representation (with field names between brackets): [scheme]://[userinfo]@[host]:[port][path]?[query]#[fragment] Note the `authority` field is deprecated. `parse/1` will still populate it for backwards compatibility but you should generally avoid setting or getting it. ### URI.append_path/2 (function) Appends `path` to the given `uri`. Path must start with `/` and cannot contain additional URL components like fragments or query strings. This function further assumes the path is valid and it does not contain a query string or fragment parts. ### Examples - URI.append_path/2 (function) iex> URI.append_path(URI.parse("http://example.com/foo/?x=1"), "/my-path") |> URI.to_string() "http://example.com/foo/my-path?x=1" iex> URI.append_path(URI.parse("http://example.com"), "my-path") ** (ArgumentError) path must start with "/", got: "my-path" ### URI.append_query/2 (function) Appends `query` to the given `uri`. The given `query` is not automatically encoded, use `encode/2` or `encode_www_form/1`. ### Examples - URI.append_query/2 (function) iex> URI.append_query(URI.parse("http://example.com/"), "x=1") |> URI.to_string() "http://example.com/?x=1" iex> URI.append_query(URI.parse("http://example.com/?x=1"), "y=2") |> URI.to_string() "http://example.com/?x=1&y=2" iex> URI.append_query(URI.parse("http://example.com/?x=1"), "x=2") |> URI.to_string() "http://example.com/?x=1&x=2" ### URI.char_reserved?/1 (function) Checks if `character` is a reserved one in a URI. As specified in [RFC 3986, section 2.2](https://tools.ietf.org/html/rfc3986#section-2.2), the following characters are reserved: `:`, `/`, `?`, `#`, `[`, `]`, `@`, `!`, `$`, `&`, `'`, `(`, `)`, `*`, `+`, `,`, `;`, `=` ### Examples - URI.char_reserved?/1 (function) iex> URI.char_reserved?(?+) true ### URI.char_unescaped?/1 (function) Checks if `character` is allowed unescaped in a URI. This is the default used by `URI.encode/2` where both [reserved](`char_reserved?/1`) and [unreserved characters](`char_unreserved?/1`) are kept unescaped. ### Examples - URI.char_unescaped?/1 (function) iex> URI.char_unescaped?(?{) false ### URI.char_unreserved?/1 (function) Checks if `character` is an unreserved one in a URI. As specified in [RFC 3986, section 2.3](https://tools.ietf.org/html/rfc3986#section-2.3), the following characters are unreserved: * Alphanumeric characters: `A-Z`, `a-z`, `0-9` * `~`, `_`, `-`, `.` ### Examples - URI.char_unreserved?/1 (function) iex> URI.char_unreserved?(?_) true ### URI.decode/1 (function) Percent-unescapes a URI. ### Examples - URI.decode/1 (function) iex> URI.decode("https%3A%2F%2Felixir-lang.org") "https://elixir-lang.org" ### URI.decode_query/3 (function) Decodes `query` into a map. Given a query string in the form of `key1=value1&key2=value2...`, this function inserts each key-value pair in the query string as one entry in the given `map`. Keys and values in the resulting map will be binaries. Keys and values will be percent-unescaped. You can specify one of the following `encoding` options: * `:www_form` - (default, since v1.12.0) keys and values are decoded as per `decode_www_form/1`. This is the format typically used by browsers on query strings and form data. It decodes "+" as " ". * `:rfc3986` - (since v1.12.0) keys and values are decoded as per `decode/1`. The result is the same as `:www_form` except for leaving "+" as is in line with [RFC 3986](https://tools.ietf.org/html/rfc3986). Encoding defaults to `:www_form` for backward compatibility. Use `query_decoder/1` if you want to iterate over each value manually. ### Examples - URI.decode_query/3 (function) iex> URI.decode_query("foo=1&bar=2") %{"bar" => "2", "foo" => "1"} iex> URI.decode_query("percent=oh+yes%21", %{"starting" => "map"}) %{"percent" => "oh yes!", "starting" => "map"} iex> URI.decode_query("percent=oh+yes%21", %{}, :rfc3986) %{"percent" => "oh+yes!"} ### URI.decode_www_form/1 (function) Decodes `string` as "x-www-form-urlencoded". Note "x-www-form-urlencoded" is not specified as part of RFC 3986. However, it is a commonly used format to encode query strings and form data by browsers. ### Examples - URI.decode_www_form/1 (function) iex> URI.decode_www_form("%3Call+in%2F") " URI.default_port("ftp") 21 iex> URI.default_port("ponzi") nil ### URI.default_port/2 (function) Registers the default `port` for the given `scheme`. After this function is called, `port` will be returned by `default_port/1` for the given scheme `scheme`. Note that this function changes the default port for the given `scheme` *globally*, meaning for every application. It is recommended for this function to be invoked in your application's start callback in case you want to register new URIs. ### URI.encode/2 (function) Percent-encodes all characters that require escaping in `string`. The optional `predicate` argument specifies a function used to detect whether a byte in the `string` should be escaped: * if the function returns a truthy value, the byte should be kept as-is. * if the function returns a falsy value, the byte should be escaped. The `predicate` argument can use some built-in functions: * `URI.char_unescaped?/1` (default) - reserved characters (such as `:` and `/`) or unreserved (such as letters and numbers) are kept as-is. It's typically used to encode the whole URI. * `URI.char_unreserved?/1` - unreserved characters (such as letters and numbers) are kept as-is. It's typically used to encode components in a URI, such as query or fragment. * `URI.char_reserved?/1` - Reserved characters (such as `:` and `/`) are kept as-is. And, you can also use custom functions. See `encode_www_form/1` if you are interested in encoding `string` as "x-www-form-urlencoded". ### Examples - URI.encode/2 (function) iex> URI.encode("ftp://s-ite.tld/?value=put it+й") "ftp://s-ite.tld/?value=put%20it+%D0%B9" iex> URI.encode("a string", &(&1 != ?i)) "a str%69ng" ### URI.encode_query/2 (function) Encodes `enumerable` into a query string using `encoding`. Takes an enumerable that enumerates as a list of two-element tuples (for instance, a map or a keyword list) and returns a string in the form of `key1=value1&key2=value2...`. Keys and values can be any term that implements the `String.Chars` protocol with the exception of lists, which are explicitly forbidden. You can specify one of the following `encoding` strategies: * `:www_form` - (default, since v1.12.0) keys and values are URL encoded as per `encode_www_form/1`. This is the format typically used by browsers on query strings and form data. It encodes " " as "+". * `:rfc3986` - (since v1.12.0) the same as `:www_form` except it encodes " " as "%20" according [RFC 3986](https://tools.ietf.org/html/rfc3986). This is the best option if you are encoding in a non-browser situation, since encoding spaces as "+" can be ambiguous to URI parsers. This can inadvertently lead to spaces being interpreted as literal plus signs. Encoding defaults to `:www_form` for backward compatibility. ### Examples - URI.encode_query/2 (function) iex> query = %{"foo" => 1, "bar" => 2} iex> URI.encode_query(query) "bar=2&foo=1" iex> query = %{"key" => "value with spaces"} iex> URI.encode_query(query) "key=value+with+spaces" iex> query = %{"key" => "value with spaces"} iex> URI.encode_query(query, :rfc3986) "key=value%20with%20spaces" iex> URI.encode_query(%{key: [:a, :list]}) ** (ArgumentError) encode_query/2 values cannot be lists, got: [:a, :list] ### URI.encode_www_form/1 (function) Encodes `string` as "x-www-form-urlencoded". Note "x-www-form-urlencoded" is not specified as part of RFC 3986. However, it is a commonly used format to encode query strings and form data by browsers. ### Example - URI.encode_www_form/1 (function) iex> URI.encode_www_form("put: it+й") "put%3A+it%2B%D0%B9" ### URI.merge/2 (function) Merges two URIs. This function merges two URIs as per [RFC 3986, section 5.2](https://tools.ietf.org/html/rfc3986#section-5.2). ### Examples - URI.merge/2 (function) iex> URI.merge(URI.parse("http://google.com"), "/query") |> to_string() "http://google.com/query" iex> URI.merge("http://example.com", "http://google.com") |> to_string() "http://google.com" ### URI.new/1 (function) Creates a new URI struct from a URI or a string. If a `%URI{}` struct is given, it returns `{:ok, uri}`. If a string is given, it will parse and validate it. If the string is valid, it returns `{:ok, uri}`, otherwise it returns `{:error, part}` with the invalid part of the URI. For parsing URIs without further validation, see `parse/1`. This function can parse both absolute and relative URLs. You can check if a URI is absolute or relative by checking if the `scheme` field is `nil` or not. When a URI is given without a port, the value returned by `URI.default_port/1` for the URI's scheme is used for the `:port` field. The scheme is also normalized to lowercase. ### Examples - URI.new/1 (function) iex> URI.new("https://elixir-lang.org/") {:ok, %URI{ fragment: nil, host: "elixir-lang.org", path: "/", port: 443, query: nil, scheme: "https", userinfo: nil }} iex> URI.new("//elixir-lang.org/") {:ok, %URI{ fragment: nil, host: "elixir-lang.org", path: "/", port: nil, query: nil, scheme: nil, userinfo: nil }} iex> URI.new("/foo/bar") {:ok, %URI{ fragment: nil, host: nil, path: "/foo/bar", port: nil, query: nil, scheme: nil, userinfo: nil }} iex> URI.new("foo/bar") {:ok, %URI{ fragment: nil, host: nil, path: "foo/bar", port: nil, query: nil, scheme: nil, userinfo: nil }} iex> URI.new("//[fe80::]/") {:ok, %URI{ fragment: nil, host: "fe80::", path: "/", port: nil, query: nil, scheme: nil, userinfo: nil }} iex> URI.new("https:?query") {:ok, %URI{ fragment: nil, host: nil, path: nil, port: 443, query: "query", scheme: "https", userinfo: nil }} iex> URI.new("/invalid_greater_than_in_path/>") {:error, ">"} Giving an existing URI simply returns it wrapped in a tuple: iex> {:ok, uri} = URI.new("https://elixir-lang.org/") iex> URI.new(uri) {:ok, %URI{ fragment: nil, host: "elixir-lang.org", path: "/", port: 443, query: nil, scheme: "https", userinfo: nil }} ### URI.new!/1 (function) Similar to `new/1` but raises `URI.Error` if an invalid string is given. ### Examples - URI.new!/1 (function) iex> URI.new!("https://elixir-lang.org/") %URI{ fragment: nil, host: "elixir-lang.org", path: "/", port: 443, query: nil, scheme: "https", userinfo: nil } iex> URI.new!("/invalid_greater_than_in_path/>") ** (URI.Error) cannot parse due to reason invalid_uri: ">" Giving an existing URI simply returns it: iex> uri = URI.new!("https://elixir-lang.org/") iex> URI.new!(uri) %URI{ fragment: nil, host: "elixir-lang.org", path: "/", port: 443, query: nil, scheme: "https", userinfo: nil } ### URI.parse/1 (function) Parses a URI into its components, without further validation. This function can parse both absolute and relative URLs. You can check if a URI is absolute or relative by checking if the `scheme` field is nil or not. Furthermore, this function expects both absolute and relative URIs to be well-formed and does not perform any validation. See the "Examples" section below. Use `new/1` if you want to validate the URI fields after parsing. When a URI is given without a port, the value returned by `URI.default_port/1` for the URI's scheme is used for the `:port` field. The scheme is also normalized to lowercase. If a `%URI{}` struct is given to this function, this function returns it unmodified. > #### `:authority` field {: .info} > > This function sets the deprecated field `:authority` for backwards-compatibility reasons. ### Examples - URI.parse/1 (function) iex> URI.parse("https://elixir-lang.org/") %URI{ authority: "elixir-lang.org", fragment: nil, host: "elixir-lang.org", path: "/", port: 443, query: nil, scheme: "https", userinfo: nil } iex> URI.parse("//elixir-lang.org/") %URI{ authority: "elixir-lang.org", fragment: nil, host: "elixir-lang.org", path: "/", port: nil, query: nil, scheme: nil, userinfo: nil } iex> URI.parse("/foo/bar") %URI{ fragment: nil, host: nil, path: "/foo/bar", port: nil, query: nil, scheme: nil, userinfo: nil } iex> URI.parse("foo/bar") %URI{ fragment: nil, host: nil, path: "foo/bar", port: nil, query: nil, scheme: nil, userinfo: nil } In contrast to `URI.new/1`, this function will parse poorly-formed URIs, for example: iex> URI.parse("/invalid_greater_than_in_path/>") %URI{ fragment: nil, host: nil, path: "/invalid_greater_than_in_path/>", port: nil, query: nil, scheme: nil, userinfo: nil } Another example is a URI with brackets in query strings. It is accepted by `parse/1`, it is commonly accepted by browsers, but it will be refused by `new/1`: iex> URI.parse("/?foo[bar]=baz") %URI{ fragment: nil, host: nil, path: "/", port: nil, query: "foo[bar]=baz", scheme: nil, userinfo: nil } ### URI.query_decoder/2 (function) Returns a stream of two-element tuples representing key-value pairs in the given `query`. Key and value in each tuple will be binaries and will be percent-unescaped. You can specify one of the following `encoding` options: * `:www_form` - (default, since v1.12.0) keys and values are decoded as per `decode_www_form/1`. This is the format typically used by browsers on query strings and form data. It decodes "+" as " ". * `:rfc3986` - (since v1.12.0) keys and values are decoded as per `decode/1`. The result is the same as `:www_form` except for leaving "+" as is in line with [RFC 3986](https://tools.ietf.org/html/rfc3986). Encoding defaults to `:www_form` for backward compatibility. ### Examples - URI.query_decoder/2 (function) iex> URI.query_decoder("foo=1&bar=2") |> Enum.to_list() [{"foo", "1"}, {"bar", "2"}] iex> URI.query_decoder("food=bread%26butter&drinks=tap%20water+please") |> Enum.to_list() [{"food", "bread&butter"}, {"drinks", "tap water please"}] iex> URI.query_decoder("food=bread%26butter&drinks=tap%20water+please", :rfc3986) |> Enum.to_list() [{"food", "bread&butter"}, {"drinks", "tap water+please"}] ### URI.to_string/1 (function) Returns the string representation of the given [URI struct](`t:t/0`). ### Examples - URI.to_string/1 (function) iex> uri = URI.parse("http://google.com") iex> URI.to_string(uri) "http://google.com" iex> uri = URI.parse("foo://bar.baz") iex> URI.to_string(uri) "foo://bar.baz" ### URI.t/0 (type) ### Version (module) Functions for parsing and matching versions against requirements. A version is a string in a specific format or a `Version` generated after parsing via `Version.parse/1`. Although Elixir projects are not required to follow SemVer, they must follow the format outlined on [SemVer 2.0 schema](https://semver.org/). ### Versions - Version (module) In a nutshell, a version is represented by three numbers: MAJOR.MINOR.PATCH Pre-releases are supported by optionally appending a hyphen and a series of period-separated identifiers immediately following the patch version. Identifiers consist of only ASCII alphanumeric characters and hyphens (`[0-9A-Za-z-]`): "1.0.0-alpha.3" Build information can be added by appending a plus sign and a series of dot-separated identifiers immediately following the patch or pre-release version. Identifiers consist of only ASCII alphanumeric characters and hyphens (`[0-9A-Za-z-]`): "1.0.0-alpha.3+20130417140000.amd64" ### Requirements - Version (module) Requirements allow you to specify which versions of a given dependency you are willing to work against. Requirements support the common comparison operators such as `>`, `>=`, `<`, `<=`, and `==` that work as one would expect, and additionally the special operator `~>` described in detail further below. # Only version 2.0.0 "== 2.0.0" # Anything later than 2.0.0 "> 2.0.0" Requirements also support `and` and `or` for complex conditions: # 2.0.0 and later until 2.1.0 ">= 2.0.0 and < 2.1.0" Since the example above is such a common requirement, it can be expressed as: "~> 2.0.0" `~>` will never include pre-release versions of its upper bound, regardless of the usage of the `:allow_pre` option, or whether the operand is a pre-release version. It can also be used to set an upper bound on only the major version part. See the table below for `~>` requirements and their corresponding translations. `~>` | Translation :------------- | :--------------------- `~> 2.0.0` | `>= 2.0.0 and < 2.1.0` `~> 2.1.2` | `>= 2.1.2 and < 2.2.0` `~> 2.1.3-dev` | `>= 2.1.3-dev and < 2.2.0` `~> 2.0` | `>= 2.0.0 and < 3.0.0` `~> 2.1` | `>= 2.1.0 and < 3.0.0` The requirement operand after the `~>` is allowed to omit the patch version, allowing us to express `~> 2.1` or `~> 2.1-dev`, something that wouldn't be allowed when using the common comparison operators. When the `:allow_pre` option is set `false` in `Version.match?/3`, the requirement will not match a pre-release version unless the operand is a pre-release version. The default is to always allow pre-releases but note that in Hex `:allow_pre` is set to `false`. See the table below for examples. Requirement | Version | `:allow_pre` | Matches :------------- | :---------- | :---------------- | :------ `~> 2.0` | `2.1.0` | `true` or `false` | `true` `~> 2.0` | `3.0.0` | `true` or `false` | `false` `~> 2.0.0` | `2.0.5` | `true` or `false` | `true` `~> 2.0.0` | `2.1.0` | `true` or `false` | `false` `~> 2.1.2` | `2.1.6-dev` | `true` | `true` `~> 2.1.2` | `2.1.6-dev` | `false` | `false` `~> 2.1-dev` | `2.2.0-dev` | `true` or `false` | `true` `~> 2.1.2-dev` | `2.1.6-dev` | `true` or `false` | `true` `>= 2.1.0` | `2.2.0-dev` | `true` | `true` `>= 2.1.0` | `2.2.0-dev` | `false` | `false` `>= 2.1.0-dev` | `2.2.6-dev` | `true` or `false` | `true` ### Version.__struct__/0 (function) The Version struct. It contains the fields `:major`, `:minor`, `:patch`, `:pre`, and `:build` according to SemVer 2.0, where `:pre` is a list. You can read those fields but you should not create a new `Version` directly via the struct syntax. Instead use the functions in this module. ### Version.compare/2 (function) Compares two versions. Returns `:gt` if the first version is greater than the second one, and `:lt` for vice versa. If the two versions are equal, `:eq` is returned. Pre-releases are strictly less than their corresponding release versions. Patch segments are compared lexicographically if they are alphanumeric, and numerically otherwise. Build segments are ignored: if two versions differ only in their build segment they are considered to be equal. Raises a `Version.InvalidVersionError` exception if any of the two given versions are not parsable. If given an already parsed version this function won't raise. ### Examples - Version.compare/2 (function) iex> Version.compare("2.0.1-alpha1", "2.0.0") :gt iex> Version.compare("1.0.0-beta", "1.0.0-rc1") :lt iex> Version.compare("1.0.0-10", "1.0.0-2") :gt iex> Version.compare("2.0.1+build0", "2.0.1") :eq iex> Version.compare("invalid", "2.0.1") ** (Version.InvalidVersionError) invalid version: "invalid" ### Version.compile_requirement/1 (function) Compiles a requirement to an internal representation that may optimize matching. The internal representation is opaque. ### Version.match?/3 (function) Checks if the given version matches the specification. Returns `true` if `version` satisfies `requirement`, `false` otherwise. Raises a `Version.InvalidRequirementError` exception if `requirement` is not parsable, or a `Version.InvalidVersionError` exception if `version` is not parsable. If given an already parsed version and requirement this function won't raise. ### Options - Version.match?/3 (function) * `:allow_pre` (boolean) - when `false`, pre-release versions will not match unless the operand is a pre-release version. Defaults to `true`. For examples, please refer to the table above under the "Requirements" section. ### Examples - Version.match?/3 (function) iex> Version.match?("2.0.0", "> 1.0.0") true iex> Version.match?("2.0.0", "== 1.0.0") false iex> Version.match?("2.1.6-dev", "~> 2.1.2") true iex> Version.match?("2.1.6-dev", "~> 2.1.2", allow_pre: false) false iex> Version.match?("foo", "== 1.0.0") ** (Version.InvalidVersionError) invalid version: "foo" iex> Version.match?("2.0.0", "== == 1.0.0") ** (Version.InvalidRequirementError) invalid requirement: "== == 1.0.0" ### Version.parse/1 (function) Parses a version string into a `Version` struct. ### Examples - Version.parse/1 (function) iex> Version.parse("2.0.1-alpha1") {:ok, %Version{major: 2, minor: 0, patch: 1, pre: ["alpha1"]}} iex> Version.parse("2.0-alpha1") :error ### Version.parse!/1 (function) Parses a version string into a `Version`. If `string` is an invalid version, a `Version.InvalidVersionError` is raised. ### Examples - Version.parse!/1 (function) iex> Version.parse!("2.0.1-alpha1") %Version{major: 2, minor: 0, patch: 1, pre: ["alpha1"]} iex> Version.parse!("2.0-alpha1") ** (Version.InvalidVersionError) invalid version: "2.0-alpha1" ### Version.parse_requirement/1 (function) Parses a version requirement string into a `Version.Requirement` struct. ### Examples - Version.parse_requirement/1 (function) iex> {:ok, requirement} = Version.parse_requirement("== 2.0.1") iex> requirement Version.parse_requirement!("== 2.0.1") iex> Version.parse_requirement("== == 2.0.1") :error ### Version.parse_requirement!/1 (function) Parses a version requirement string into a `Version.Requirement` struct. If `string` is an invalid requirement, a `Version.InvalidRequirementError` is raised. # Examples iex> Version.parse_requirement!("== 2.0.1") Version.parse_requirement!("== 2.0.1") iex> Version.parse_requirement!("== == 2.0.1") ** (Version.InvalidRequirementError) invalid requirement: "== == 2.0.1" ### Version.to_string/1 (function) Converts the given version to a string. ### Examples - Version.to_string/1 (function) iex> Version.to_string(%Version{major: 1, minor: 2, patch: 3}) "1.2.3" iex> Version.to_string(Version.parse!("1.14.0-rc.0+build0")) "1.14.0-rc.0+build0" ### Version.build/0 (type) ### Version.major/0 (type) ### Version.minor/0 (type) ### Version.patch/0 (type) ### Version.pre/0 (type) ### Version.requirement/0 (type) ### Version.t/0 (type) ### Version.version/0 (type) ### Version.Requirement (module) A struct that holds version requirement information. The struct fields are private and should not be accessed. See the "Requirements" section in the `Version` module for more information. ### Access (behaviour) Key-based access to data structures. The `Access` module defines a behaviour for dynamically accessing keys of any type in a data structure via the `data[key]` syntax. `Access` supports keyword lists (`Keyword`) and maps (`Map`) out of the box. Keywords supports only atoms keys, keys for maps can be of any type. Both return `nil` if the key does not exist: iex> keywords = [a: 1, b: 2] iex> keywords[:a] 1 iex> keywords[:c] nil iex> map = %{a: 1, b: 2} iex> map[:a] 1 iex> star_ratings = %{1.0 => "★", 1.5 => "★☆", 2.0 => "★★"} iex> star_ratings[1.5] "★☆" This syntax is very convenient as it can be nested arbitrarily: iex> keywords = [a: 1, b: 2] iex> keywords[:c][:unknown] nil This works because accessing anything on a `nil` value, returns `nil` itself: iex> nil[:a] nil ### Maps and structs - Access (behaviour) While the access syntax is allowed in maps via `map[key]`, if your map is made of predefined atom keys, you should prefer to access those atom keys with `map.key` instead of `map[key]`, as `map.key` will raise if the key is missing (which is not supposed to happen if the keys are predefined) or if `map` is `nil`. Similarly, since structs are maps and structs have predefined keys, they only allow the `struct.key` syntax and they do not allow the `struct[key]` access syntax. In other words, the `map[key]` syntax is loose, returning `nil` for missing keys, while the `map.key` syntax is strict, raising for both nil values and missing keys. To bridge this gap, Elixir provides the `get_in/1` and `get_in/2` functions, which are capable of traversing nested data structures, even in the presence of `nil`s: iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_in(users["john"].age) 27 iex> get_in(users["unknown"].age) nil Notice how, even if no user was found, `get_in/1` returned `nil`. Outside of `get_in/1`, trying to access the field `.age` on `nil` would raise. The `get_in/2` function takes one step further by allowing different accessors to be mixed in. For example, given a user map with the `:name` and `:languages` keys, here is how to access the name of all programming languages: iex> languages = [ ...> %{name: "elixir", type: :functional}, ...> %{name: "c", type: :procedural} ...> ] iex> user = %{name: "john", languages: languages} iex> get_in(user, [:languages, Access.all(), :name]) ["elixir", "c"] This module provides convenience functions for traversing other structures, like tuples and lists. As we will see next, they can even be used to update nested data structures. If you want to learn more about the dual nature of maps in Elixir, as they can be either for structured data or as a key-value store, see the `Map` module. ### Updating nested data structures - Access (behaviour) The access syntax can also be used with the `Kernel.put_in/2`, `Kernel.update_in/2`, `Kernel.get_and_update_in/2`, and `Kernel.pop_in/1` macros to further manipulate values in nested data structures: iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> put_in(users["john"].age, 28) %{"john" => %{age: 28}, "meg" => %{age: 23}} As shown in the previous section, you can also use the `Kernel.put_in/3`, `Kernel.update_in/3`, `Kernel.pop_in/2`, and `Kernel.get_and_update_in/3` functions to provide nested custom accessors. For instance, given a user map with the `:name` and `:languages` keys, here is how to deeply traverse the map and convert all language names to uppercase: iex> languages = [ ...> %{name: "elixir", type: :functional}, ...> %{name: "c", type: :procedural} ...> ] iex> user = %{name: "john", languages: languages} iex> update_in(user, [:languages, Access.all(), :name], &String.upcase/1) %{ name: "john", languages: [ %{name: "ELIXIR", type: :functional}, %{name: "C", type: :procedural} ] } See the functions `key/1`, `key!/1`, `elem/1`, and `all/0` for some of the available accessors. ### Access.all/0 (function) Returns a function that accesses all the elements in a list. The returned function is typically passed as an accessor to `Kernel.get_in/2`, `Kernel.get_and_update_in/3`, and friends. ### Examples - Access.all/0 (function) iex> list = [%{name: "john"}, %{name: "mary"}] iex> get_in(list, [Access.all(), :name]) ["john", "mary"] iex> get_and_update_in(list, [Access.all(), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {["john", "mary"], [%{name: "JOHN"}, %{name: "MARY"}]} iex> pop_in(list, [Access.all(), :name]) {["john", "mary"], [%{}, %{}]} Here is an example that traverses the list dropping even numbers and multiplying odd numbers by 2: iex> require Integer iex> get_and_update_in([1, 2, 3, 4, 5], [Access.all()], fn num -> ...> if Integer.is_even(num), do: :pop, else: {num, num * 2} ...> end) {[1, 2, 3, 4, 5], [2, 6, 10]} An error is raised if the accessed structure is not a list: iex> get_in(%{}, [Access.all()]) ** (RuntimeError) Access.all/0 expected a list, got: %{} ### Access.at/1 (function) Returns a function that accesses the element at `index` (zero based) of a list. Keep in mind that index lookups in lists take linear time: the larger the list, the longer it will take to access its index. Therefore index-based operations are generally avoided in favor of other functions in the `Enum` module. The returned function is typically passed as an accessor to `Kernel.get_in/2`, `Kernel.get_and_update_in/3`, and friends. ### Examples - Access.at/1 (function) iex> list = [%{name: "john"}, %{name: "mary"}] iex> get_in(list, [Access.at(1), :name]) "mary" iex> get_in(list, [Access.at(-1), :name]) "mary" iex> get_and_update_in(list, [Access.at(0), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {"john", [%{name: "JOHN"}, %{name: "mary"}]} iex> get_and_update_in(list, [Access.at(-1), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {"mary", [%{name: "john"}, %{name: "MARY"}]} `at/1` can also be used to pop elements out of a list or a key inside of a list: iex> list = [%{name: "john"}, %{name: "mary"}] iex> pop_in(list, [Access.at(0)]) {%{name: "john"}, [%{name: "mary"}]} iex> pop_in(list, [Access.at(0), :name]) {"john", [%{}, %{name: "mary"}]} When the index is out of bounds, `nil` is returned and the update function is never called: iex> list = [%{name: "john"}, %{name: "mary"}] iex> get_in(list, [Access.at(10), :name]) nil iex> get_and_update_in(list, [Access.at(10), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {nil, [%{name: "john"}, %{name: "mary"}]} An error is raised if the accessed structure is not a list: iex> get_in(%{}, [Access.at(1)]) ** (RuntimeError) Access.at/1 expected a list, got: %{} ### Access.at!/1 (function) Same as `at/1` except that it raises `Enum.OutOfBoundsError` if the given index is out of bounds. ### Examples - Access.at!/1 (function) iex> get_in([:a, :b, :c], [Access.at!(2)]) :c iex> get_in([:a, :b, :c], [Access.at!(3)]) ** (Enum.OutOfBoundsError) out of bounds error ### Access.elem/1 (function) Returns a function that accesses the element at the given index in a tuple. The returned function is typically passed as an accessor to `Kernel.get_in/2`, `Kernel.get_and_update_in/3`, and friends. The returned function raises if `index` is out of bounds. Note that popping elements out of tuples is not possible and raises an error. ### Examples - Access.elem/1 (function) iex> map = %{user: {"john", 27}} iex> get_in(map, [:user, Access.elem(0)]) "john" iex> get_and_update_in(map, [:user, Access.elem(0)], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {"john", %{user: {"JOHN", 27}}} iex> pop_in(map, [:user, Access.elem(0)]) ** (RuntimeError) cannot pop data from a tuple An error is raised if the accessed structure is not a tuple: iex> get_in(%{}, [Access.elem(0)]) ** (RuntimeError) Access.elem/1 expected a tuple, got: %{} ### Access.fetch/2 (function) Fetches the value for the given key in a container (a map, keyword list, or struct that implements the `Access` behaviour). Returns `{:ok, value}` where `value` is the value under `key` if there is such a key, or `:error` if `key` is not found. ### Examples - Access.fetch/2 (function) iex> Access.fetch(%{name: "meg", age: 26}, :name) {:ok, "meg"} iex> Access.fetch([ordered: true, on_timeout: :exit], :timeout) :error ### Access.fetch/2 (callback) Invoked in order to access the value stored under `key` in the given term `term`. This function should return `{:ok, value}` where `value` is the value under `key` if the key exists in the term, or `:error` if the key does not exist in the term. Many of the functions defined in the `Access` module internally call this function. This function is also used when the square-brackets access syntax (`structure[key]`) is used: the `fetch/2` callback implemented by the module that defines the `structure` struct is invoked and if it returns `{:ok, value}` then `value` is returned, or if it returns `:error` then `nil` is returned. See the `Map.fetch/2` and `Keyword.fetch/2` implementations for examples of how to implement this callback. ### Access.fetch!/2 (function) Same as `fetch/2` but returns the value directly, or raises a `KeyError` exception if `key` is not found. ### Examples - Access.fetch!/2 (function) iex> Access.fetch!(%{name: "meg", age: 26}, :name) "meg" ### Access.filter/1 (function) Returns a function that accesses all elements of a list that match the provided predicate. The returned function is typically passed as an accessor to `Kernel.get_in/2`, `Kernel.get_and_update_in/3`, and friends. ### Examples - Access.filter/1 (function) iex> list = [%{name: "john", salary: 10}, %{name: "francine", salary: 30}] iex> get_in(list, [Access.filter(&(&1.salary > 20)), :name]) ["francine"] iex> get_and_update_in(list, [Access.filter(&(&1.salary <= 20)), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {["john"], [%{name: "JOHN", salary: 10}, %{name: "francine", salary: 30}]} `filter/1` can also be used to pop elements out of a list or a key inside of a list: iex> list = [%{name: "john", salary: 10}, %{name: "francine", salary: 30}] iex> pop_in(list, [Access.filter(&(&1.salary >= 20))]) {[%{name: "francine", salary: 30}], [%{name: "john", salary: 10}]} iex> pop_in(list, [Access.filter(&(&1.salary >= 20)), :name]) {["francine"], [%{name: "john", salary: 10}, %{salary: 30}]} When no match is found, an empty list is returned and the update function is never called iex> list = [%{name: "john", salary: 10}, %{name: "francine", salary: 30}] iex> get_in(list, [Access.filter(&(&1.salary >= 50)), :name]) [] iex> get_and_update_in(list, [Access.filter(&(&1.salary >= 50)), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {[], [%{name: "john", salary: 10}, %{name: "francine", salary: 30}]} An error is raised if the predicate is not a function or is of the incorrect arity: iex> get_in([], [Access.filter(5)]) ** (FunctionClauseError) no function clause matching in Access.filter/1 An error is raised if the accessed structure is not a list: iex> get_in(%{}, [Access.filter(fn a -> a == 10 end)]) ** (RuntimeError) Access.filter/1 expected a list, got: %{} ### Access.find/1 (function) Returns a function that accesses the first element of a list that matches the provided predicate. The returned function is typically passed as an accessor to `Kernel.get_in/2`, `Kernel.get_and_update_in/3`, and friends. ### Examples - Access.find/1 (function) iex> list = [%{name: "john", salary: 10}, %{name: "francine", salary: 30}] iex> get_in(list, [Access.find(&(&1.salary > 20)), :name]) "francine" iex> get_and_update_in(list, [Access.find(&(&1.salary <= 40)), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {"john", [%{name: "JOHN", salary: 10}, %{name: "francine", salary: 30}]} `find/1` can also be used to pop the first found element out of a list or a key inside of a list: iex> list = [%{name: "john", salary: 10}, %{name: "francine", salary: 30}] iex> pop_in(list, [Access.find(&(&1.salary <= 40))]) {%{name: "john", salary: 10}, [%{name: "francine", salary: 30}]} When no match is found, nil is returned and the update function is never called iex> list = [%{name: "john", salary: 10}, %{name: "francine", salary: 30}] iex> get_in(list, [Access.find(&(&1.salary >= 50)), :name]) nil iex> get_and_update_in(list, [Access.find(&(&1.salary >= 50)), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {nil, [%{name: "john", salary: 10}, %{name: "francine", salary: 30}]} An error is raised if the predicate is not a function or is of the incorrect arity: iex> get_in([], [Access.find(5)]) ** (FunctionClauseError) no function clause matching in Access.find/1 An error is raised if the accessed structure is not a list: iex> get_in(%{}, [Access.find(fn a -> a == 10 end)]) ** (RuntimeError) Access.find/1 expected a list, got: %{} ### Access.get/3 (function) Gets the value for the given key in a container (a map, keyword list, or struct that implements the `Access` behaviour). Returns the value under `key` if there is such a key, or `default` if `key` is not found. ### Examples - Access.get/3 (function) iex> Access.get(%{name: "john"}, :name, "default name") "john" iex> Access.get(%{name: "john"}, :age, 25) 25 iex> Access.get([ordered: true], :timeout) nil ### Access.get_and_update/3 (function) Gets and updates the given key in a `container` (a map, a keyword list, a struct that implements the `Access` behaviour). The `fun` argument receives the value of `key` (or `nil` if `key` is not present in `container`) and must return a two-element tuple `{current_value, new_value}`: the "get" value `current_value` (the retrieved value, which can be operated on before being returned) and the new value to be stored under `key` (`new_value`). `fun` may also return `:pop`, which means the current value should be removed from the container and returned. The returned value is a two-element tuple with the "get" value returned by `fun` and a new container with the updated value under `key`. ### Examples - Access.get_and_update/3 (function) iex> Access.get_and_update([a: 1], :a, fn current_value -> ...> {current_value, current_value + 1} ...> end) {1, [a: 2]} ### Access.get_and_update/3 (callback) Invoked in order to access the value under `key` and update it at the same time. The implementation of this callback should invoke `fun` with the value under `key` in the passed structure `data`, or with `nil` if `key` is not present in it. This function must return either `{current_value, new_value}` or `:pop`. If the passed function returns `{current_value, new_value}`, the return value of this callback should be `{current_value, new_data}`, where: * `current_value` is the retrieved value (which can be operated on before being returned) * `new_value` is the new value to be stored under `key` * `new_data` is `data` after updating the value of `key` with `new_value`. If the passed function returns `:pop`, the return value of this callback must be `{value, new_data}` where `value` is the value under `key` (or `nil` if not present) and `new_data` is `data` without `key`. See the implementations of `Map.get_and_update/3` or `Keyword.get_and_update/3` for more examples. ### Access.key/2 (function) Returns a function that accesses the given key in a map/struct. The returned function is typically passed as an accessor to `Kernel.get_in/2`, `Kernel.get_and_update_in/3`, and friends. The returned function uses the default value if the key does not exist. This can be used to specify defaults and safely traverse missing keys: iex> get_in(%{}, [Access.key(:user, %{}), Access.key(:name, "meg")]) "meg" Such is also useful when using update functions, allowing us to introduce values as we traverse the data structure for updates: iex> put_in(%{}, [Access.key(:user, %{}), Access.key(:name)], "Mary") %{user: %{name: "Mary"}} ### Examples - Access.key/2 (function) iex> map = %{user: %{name: "john"}} iex> get_in(map, [Access.key(:unknown, %{}), Access.key(:name, "john")]) "john" iex> get_and_update_in(map, [Access.key(:user), Access.key(:name)], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {"john", %{user: %{name: "JOHN"}}} iex> pop_in(map, [Access.key(:user), Access.key(:name)]) {"john", %{user: %{}}} An error is raised if the accessed structure is not a map or a struct: iex> get_in([], [Access.key(:foo)]) ** (BadMapError) expected a map, got: [] ### Access.key!/1 (function) Returns a function that accesses the given key in a map/struct. The returned function is typically passed as an accessor to `Kernel.get_in/2`, `Kernel.get_and_update_in/3`, and friends. Similar to `key/2`, but the returned function raises if the key does not exist. ### Examples - Access.key!/1 (function) iex> map = %{user: %{name: "john"}} iex> get_in(map, [Access.key!(:user), Access.key!(:name)]) "john" iex> get_and_update_in(map, [Access.key!(:user), Access.key!(:name)], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {"john", %{user: %{name: "JOHN"}}} iex> pop_in(map, [Access.key!(:user), Access.key!(:name)]) {"john", %{user: %{}}} iex> get_in(map, [Access.key!(:user), Access.key!(:unknown)]) ** (KeyError) key :unknown not found in: %{name: "john"} The examples above could be partially written as: iex> map = %{user: %{name: "john"}} iex> map.user.name "john" iex> get_and_update_in(map.user.name, fn prev -> ...> {prev, String.upcase(prev)} ...> end) {"john", %{user: %{name: "JOHN"}}} However, it is not possible to remove fields using the dot notation, as it is implied those fields must also be present. In any case, `Access.key!/1` is useful when the key is not known in advance and must be accessed dynamically. An error is raised if the accessed structure is not a map/struct: iex> get_in([], [Access.key!(:foo)]) ** (RuntimeError) Access.key!/1 expected a map/struct, got: [] ### Access.pop/2 (function) Removes the entry with a given key from a container (a map, keyword list, or struct that implements the `Access` behaviour). Returns a tuple containing the value associated with the key and the updated container. `nil` is returned for the value if the key isn't in the container. ### Examples - Access.pop/2 (function) With a map: iex> Access.pop(%{name: "Elixir", creator: "Valim"}, :name) {"Elixir", %{creator: "Valim"}} A keyword list: iex> Access.pop([name: "Elixir", creator: "Valim"], :name) {"Elixir", [creator: "Valim"]} An unknown key: iex> Access.pop(%{name: "Elixir", creator: "Valim"}, :year) {nil, %{creator: "Valim", name: "Elixir"}} ### Access.pop/2 (callback) Invoked to "pop" the value under `key` out of the given data structure. When `key` exists in the given structure `data`, the implementation should return a `{value, new_data}` tuple where `value` is the value that was under `key` and `new_data` is `term` without `key`. When `key` is not present in the given structure, a tuple `{value, data}` should be returned, where `value` is implementation-defined. See the implementations for `Map.pop/3` or `Keyword.pop/3` for more examples. ### Access.slice/1 (function) Returns a function that accesses all items of a list that are within the provided range. The range will be normalized following the same rules from `Enum.slice/2`. The returned function is typically passed as an accessor to `Kernel.get_in/2`, `Kernel.get_and_update_in/3`, and friends. ### Examples - Access.slice/1 (function) iex> list = [%{name: "john", salary: 10}, %{name: "francine", salary: 30}, %{name: "vitor", salary: 25}] iex> get_in(list, [Access.slice(1..2), :name]) ["francine", "vitor"] iex> get_and_update_in(list, [Access.slice(1..3//2), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {["francine"], [%{name: "john", salary: 10}, %{name: "FRANCINE", salary: 30}, %{name: "vitor", salary: 25}]} `slice/1` can also be used to pop elements out of a list or a key inside of a list: iex> list = [%{name: "john", salary: 10}, %{name: "francine", salary: 30}, %{name: "vitor", salary: 25}] iex> pop_in(list, [Access.slice(-2..-1)]) {[%{name: "francine", salary: 30}, %{name: "vitor", salary: 25}], [%{name: "john", salary: 10}]} iex> pop_in(list, [Access.slice(-2..-1), :name]) {["francine", "vitor"], [%{name: "john", salary: 10}, %{salary: 30}, %{salary: 25}]} When no match is found, an empty list is returned and the update function is never called iex> list = [%{name: "john", salary: 10}, %{name: "francine", salary: 30}, %{name: "vitor", salary: 25}] iex> get_in(list, [Access.slice(5..10//2), :name]) [] iex> get_and_update_in(list, [Access.slice(5..10//2), :name], fn prev -> ...> {prev, String.upcase(prev)} ...> end) {[], [%{name: "john", salary: 10}, %{name: "francine", salary: 30}, %{name: "vitor", salary: 25}]} An error is raised if the accessed structure is not a list: iex> get_in(%{}, [Access.slice(2..10//3)]) ** (ArgumentError) Access.slice/1 expected a list, got: %{} An error is raised if the step of the range is negative: iex> get_in([], [Access.slice(2..10//-1)]) ** (ArgumentError) Access.slice/1 does not accept ranges with negative steps, got: 2..10//-1 ### Access.access_fun/2 (type) ### Access.container/0 (type) ### Access.get_and_update_fun/2 (type) ### Access.get_fun/1 (type) ### Access.key/0 (type) ### Access.nil_container/0 (type) ### Access.t/0 (type) ### Access.value/0 (type) ### Date.Range (module) Returns an inclusive range between dates. Ranges must be created with the `Date.range/2` or `Date.range/3` function. The following fields are public: * `:first` - the initial date on the range * `:last` - the last date on the range * `:step` - (since v1.12.0) the step The remaining fields are private and should not be accessed. ### Date.Range.t/0 (type) ### Enum (module) Functions for working with collections (known as enumerables). In Elixir, an enumerable is any data type that implements the `Enumerable` protocol. `List`s (`[1, 2, 3]`), `Map`s (`%{foo: 1, bar: 2}`) and `Range`s (`1..3`) are common data types used as enumerables: iex> Enum.map([1, 2, 3], fn x -> x * 2 end) [2, 4, 6] iex> Enum.sum([1, 2, 3]) 6 iex> Enum.map(1..3, fn x -> x * 2 end) [2, 4, 6] iex> Enum.sum(1..3) 6 iex> map = %{"a" => 1, "b" => 2} iex> Enum.map(map, fn {k, v} -> {k, v * 2} end) [{"a", 2}, {"b", 4}] Many other enumerables exist in the language, such as `MapSet`s and the data type returned by `File.stream!/3` which allows a file to be traversed as if it was an enumerable. For a general overview of all functions in the `Enum` module, see [the `Enum` cheatsheet](enum-cheat.cheatmd). The functions in this module work in linear time. This means that, the time it takes to perform an operation grows at the same rate as the length of the enumerable. This is expected on operations such as `Enum.map/2`. After all, if we want to traverse every element on a list, the longer the list, the more elements we need to traverse, and the longer it will take. This linear behavior should also be expected on operations like `count/1`, `member?/2`, `at/2` and similar. While Elixir does allow data types to provide performant variants for such operations, you should not expect it to always be available, since the `Enum` module is meant to work with a large variety of data types and not all data types can provide optimized behavior. Finally, note the functions in the `Enum` module are eager: they will traverse the enumerable as soon as they are invoked. This is particularly dangerous when working with infinite enumerables. In such cases, you should use the `Stream` module, which allows you to lazily express computations, without traversing collections, and work with possibly infinite collections. See the `Stream` module for examples and documentation. ### Enum.all?/1 (function) Returns `true` if all elements in `enumerable` are truthy. When an element has a falsy value (`false` or `nil`) iteration stops immediately and `false` is returned. In all other cases `true` is returned. ### Examples - Enum.all?/1 (function) iex> Enum.all?([1, 2, 3]) true iex> Enum.all?([1, nil, 3]) false iex> Enum.all?([]) true ### Enum.all?/2 (function) Returns `true` if `fun.(element)` is truthy for all elements in `enumerable`. Iterates over `enumerable` and invokes `fun` on each element. If `fun` ever returns a falsy value (`false` or `nil`), iteration stops immediately and `false` is returned. Otherwise, `true` is returned. ### Examples - Enum.all?/2 (function) iex> Enum.all?([2, 4, 6], fn x -> rem(x, 2) == 0 end) true iex> Enum.all?([2, 3, 4], fn x -> rem(x, 2) == 0 end) false iex> Enum.all?([], fn _ -> nil end) true As the last example shows, `Enum.all?/2` returns `true` if `enumerable` is empty, regardless of `fun`. In an empty enumerable there is no element for which `fun` returns a falsy value, so the result must be `true`. This is a well-defined logical argument for empty collections. ### Enum.any?/1 (function) Returns `true` if at least one element in `enumerable` is truthy. When an element has a truthy value (neither `false` nor `nil`) iteration stops immediately and `true` is returned. In all other cases `false` is returned. ### Examples - Enum.any?/1 (function) iex> Enum.any?([false, false, false]) false iex> Enum.any?([false, true, false]) true iex> Enum.any?([]) false ### Enum.any?/2 (function) Returns `true` if `fun.(element)` is truthy for at least one element in `enumerable`. Iterates over the `enumerable` and invokes `fun` on each element. When an invocation of `fun` returns a truthy value (neither `false` nor `nil`) iteration stops immediately and `true` is returned. In all other cases `false` is returned. ### Examples - Enum.any?/2 (function) iex> Enum.any?([2, 4, 6], fn x -> rem(x, 2) == 1 end) false iex> Enum.any?([2, 3, 4], fn x -> rem(x, 2) == 1 end) true iex> Enum.any?([], fn x -> x > 0 end) false ### Enum.at/3 (function) Finds the element at the given `index` (zero-based). Returns `default` if `index` is out of bounds. A negative `index` can be passed, which means the `enumerable` is enumerated once and the `index` is counted from the end (for example, `-1` finds the last element). ### Examples - Enum.at/3 (function) iex> Enum.at([2, 4, 6], 0) 2 iex> Enum.at([2, 4, 6], 2) 6 iex> Enum.at([2, 4, 6], 4) nil iex> Enum.at([2, 4, 6], 4, :none) :none ### Enum.chunk_by/2 (function) Splits enumerable on every element for which `fun` returns a new value. Returns a list of lists. ### Examples - Enum.chunk_by/2 (function) iex> Enum.chunk_by([1, 2, 2, 3, 4, 4, 6, 7, 7], &(rem(&1, 2) == 1)) [[1], [2, 2], [3], [4, 4, 6], [7, 7]] ### Enum.chunk_every/2 (function) Shortcut to `chunk_every(enumerable, count, count)`. ### Enum.chunk_every/4 (function) Returns list of lists containing `count` elements each, where each new chunk starts `step` elements into the `enumerable`. `step` is optional and, if not passed, defaults to `count`, i.e. chunks do not overlap. Chunking will stop as soon as the collection ends or when we emit an incomplete chunk. If the last chunk does not have `count` elements to fill the chunk, elements are taken from `leftover` to fill in the chunk. If `leftover` does not have enough elements to fill the chunk, then a partial chunk is returned with less than `count` elements. If `:discard` is given in `leftover`, the last chunk is discarded unless it has exactly `count` elements. ### Examples - Enum.chunk_every/4 (function) iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 2) [[1, 2], [3, 4], [5, 6]] iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, :discard) [[1, 2, 3], [3, 4, 5]] iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, [7]) [[1, 2, 3], [3, 4, 5], [5, 6, 7]] iex> Enum.chunk_every([1, 2, 3, 4], 3, 3, []) [[1, 2, 3], [4]] iex> Enum.chunk_every([1, 2, 3, 4], 10) [[1, 2, 3, 4]] iex> Enum.chunk_every([1, 2, 3, 4, 5], 2, 3, []) [[1, 2], [4, 5]] iex> Enum.chunk_every([1, 2, 3, 4], 3, 3, Stream.cycle([0])) [[1, 2, 3], [4, 0, 0]] ### Enum.chunk_while/4 (function) Chunks the `enumerable` with fine grained control when every chunk is emitted. `chunk_fun` receives the current element and the accumulator and must return: * `{:cont, chunk, acc}` to emit a chunk and continue with the accumulator * `{:cont, acc}` to not emit any chunk and continue with the accumulator * `{:halt, acc}` to halt chunking over the `enumerable`. `after_fun` is invoked with the final accumulator when iteration is finished (or `halt`ed) to handle any trailing elements that were returned as part of an accumulator, but were not emitted as a chunk by `chunk_fun`. It must return: * `{:cont, chunk, acc}` to emit a chunk. The chunk will be appended to the list of already emitted chunks. * `{:cont, acc}` to not emit a chunk The `acc` in `after_fun` is required in order to mirror the tuple format from `chunk_fun` but it will be discarded since the traversal is complete. Returns a list of emitted chunks. ### Examples - Enum.chunk_while/4 (function) iex> chunk_fun = fn element, acc -> ...> if rem(element, 2) == 0 do ...> {:cont, Enum.reverse([element | acc]), []} ...> else ...> {:cont, [element | acc]} ...> end ...> end iex> after_fun = fn ...> [] -> {:cont, []} ...> acc -> {:cont, Enum.reverse(acc), []} ...> end iex> Enum.chunk_while(1..10, [], chunk_fun, after_fun) [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] iex> Enum.chunk_while([1, 2, 3, 5, 7], [], chunk_fun, after_fun) [[1, 2], [3, 5, 7]] ### Enum.concat/1 (function) Given an enumerable of enumerables, concatenates the `enumerables` into a single list. ### Examples - Enum.concat/1 (function) iex> Enum.concat([1..3, 4..6, 7..9]) [1, 2, 3, 4, 5, 6, 7, 8, 9] iex> Enum.concat([[1, [2], 3], [4], [5, 6]]) [1, [2], 3, 4, 5, 6] ### Enum.concat/2 (function) Concatenates the enumerable on the `right` with the enumerable on the `left`. This function produces the same result as the `++/2` operator for lists. ### Examples - Enum.concat/2 (function) iex> Enum.concat(1..3, 4..6) [1, 2, 3, 4, 5, 6] iex> Enum.concat([1, 2, 3], [4, 5, 6]) [1, 2, 3, 4, 5, 6] ### Enum.count/1 (function) Returns the size of the `enumerable`. ### Examples - Enum.count/1 (function) iex> Enum.count([1, 2, 3]) 3 ### Enum.count/2 (function) Returns the count of elements in the `enumerable` for which `fun` returns a truthy value. ### Examples - Enum.count/2 (function) iex> Enum.count([1, 2, 3, 4, 5], fn x -> rem(x, 2) == 0 end) 2 ### Enum.count_until/2 (function) Counts the enumerable stopping at `limit`. This is useful for checking certain properties of the count of an enumerable without having to actually count the entire enumerable. For example, if you wanted to check that the count was exactly, at least, or more than a value. If the enumerable implements `c:Enumerable.count/1`, the enumerable is not traversed and we return the lower of the two numbers. To force enumeration, use `count_until/3` with `fn _ -> true end` as the second argument. ### Examples - Enum.count_until/2 (function) iex> Enum.count_until(1..20, 5) 5 iex> Enum.count_until(1..20, 50) 20 iex> Enum.count_until(1..10, 10) == 10 # At least 10 true iex> Enum.count_until(1..11, 10 + 1) > 10 # More than 10 true iex> Enum.count_until(1..5, 10) < 10 # Less than 10 true iex> Enum.count_until(1..10, 10 + 1) == 10 # Exactly ten true ### Enum.count_until/3 (function) Counts the elements in the enumerable for which `fun` returns a truthy value, stopping at `limit`. See `count/2` and `count_until/2` for more information. ### Examples - Enum.count_until/3 (function) iex> Enum.count_until(1..20, fn x -> rem(x, 2) == 0 end, 7) 7 iex> Enum.count_until(1..20, fn x -> rem(x, 2) == 0 end, 11) 10 ### Enum.dedup/1 (function) Enumerates the `enumerable`, returning a list where all consecutive duplicate elements are collapsed to a single element. Elements are compared using `===/2`. If you want to remove all duplicate elements, regardless of order, see `uniq/1`. ### Examples - Enum.dedup/1 (function) iex> Enum.dedup([1, 2, 3, 3, 2, 1]) [1, 2, 3, 2, 1] iex> Enum.dedup([1, 1, 2, 2.0, :three, :three]) [1, 2, 2.0, :three] ### Enum.dedup_by/2 (function) Enumerates the `enumerable`, returning a list where all consecutive duplicate elements are collapsed to a single element. The function `fun` maps every element to a term which is used to determine if two elements are duplicates. ### Examples - Enum.dedup_by/2 (function) iex> Enum.dedup_by([{1, :a}, {2, :b}, {2, :c}, {1, :a}], fn {x, _} -> x end) [{1, :a}, {2, :b}, {1, :a}] iex> Enum.dedup_by([5, 1, 2, 3, 2, 1], fn x -> x > 2 end) [5, 1, 3, 2] ### Enum.drop/2 (function) Drops the `amount` of elements from the `enumerable`. If a negative `amount` is given, the `amount` of last values will be dropped. The `enumerable` will be enumerated once to retrieve the proper index and the remaining calculation is performed from the end. ### Examples - Enum.drop/2 (function) iex> Enum.drop([1, 2, 3], 2) [3] iex> Enum.drop([1, 2, 3], 10) [] iex> Enum.drop([1, 2, 3], 0) [1, 2, 3] iex> Enum.drop([1, 2, 3], -1) [1, 2] ### Enum.drop_every/2 (function) Returns a list of every `nth` element in the `enumerable` dropped, starting with the first element. The first element is always dropped, unless `nth` is 0. The second argument specifying every `nth` element must be a non-negative integer. ### Examples - Enum.drop_every/2 (function) iex> Enum.drop_every(1..10, 2) [2, 4, 6, 8, 10] iex> Enum.drop_every(1..10, 0) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] iex> Enum.drop_every([1, 2, 3], 1) [] ### Enum.drop_while/2 (function) Drops elements at the beginning of the `enumerable` while `fun` returns a truthy value. ### Examples - Enum.drop_while/2 (function) iex> Enum.drop_while([1, 2, 3, 2, 1], fn x -> x < 3 end) [3, 2, 1] ### Enum.each/2 (function) Invokes the given `fun` for each element in the `enumerable`. Returns `:ok`. ### Examples - Enum.each/2 (function) Enum.each(["some", "example"], fn x -> IO.puts(x) end) "some" "example" #=> :ok ### Enum.empty?/1 (function) Determines if the `enumerable` is empty. Returns `true` if `enumerable` is empty, otherwise `false`. ### Examples - Enum.empty?/1 (function) iex> Enum.empty?([]) true iex> Enum.empty?([1, 2, 3]) false ### Enum.fetch/2 (function) Finds the element at the given `index` (zero-based). Returns `{:ok, element}` if found, otherwise `:error`. A negative `index` can be passed, which means the `enumerable` is enumerated once and the `index` is counted from the end (for example, `-1` fetches the last element). ### Examples - Enum.fetch/2 (function) iex> Enum.fetch([2, 4, 6], 0) {:ok, 2} iex> Enum.fetch([2, 4, 6], -3) {:ok, 2} iex> Enum.fetch([2, 4, 6], 2) {:ok, 6} iex> Enum.fetch([2, 4, 6], 4) :error ### Enum.fetch!/2 (function) Finds the element at the given `index` (zero-based). Raises `OutOfBoundsError` if the given `index` is outside the range of the `enumerable`. ### Examples - Enum.fetch!/2 (function) iex> Enum.fetch!([2, 4, 6], 0) 2 iex> Enum.fetch!([2, 4, 6], 2) 6 iex> Enum.fetch!([2, 4, 6], 4) ** (Enum.OutOfBoundsError) out of bounds error ### Enum.filter/2 (function) Filters the `enumerable`, i.e. returns only those elements for which `fun` returns a truthy value. See also `reject/2` which discards all elements where the function returns a truthy value. ### Examples - Enum.filter/2 (function) iex> Enum.filter([1, 2, 3], fn x -> rem(x, 2) == 0 end) [2] iex> Enum.filter(["apple", "pear", "banana"], fn fruit -> String.contains?(fruit, "a") end) ["apple", "pear", "banana"] iex> Enum.filter([4, 21, 24, 904], fn seconds -> seconds > 1000 end) [] Keep in mind that `filter` is not capable of filtering and transforming an element at the same time. If you would like to do so, consider using `flat_map/2`. For example, if you want to convert all strings that represent an integer and discard the invalid one in one pass: strings = ["1234", "abc", "12ab"] Enum.flat_map(strings, fn string -> case Integer.parse(string) do # transform to integer {int, _rest} -> [int] # skip the value :error -> [] end end) ### Enum.find/3 (function) Returns the first element for which `fun` returns a truthy value. If no such element is found, returns `default`. ### Examples - Enum.find/3 (function) iex> Enum.find([2, 3, 4], fn x -> rem(x, 2) == 1 end) 3 iex> Enum.find([2, 4, 6], fn x -> rem(x, 2) == 1 end) nil iex> Enum.find([2, 4, 6], 0, fn x -> rem(x, 2) == 1 end) 0 ### Enum.find_index/2 (function) Similar to `find/3`, but returns the index (zero-based) of the element instead of the element itself. ### Examples - Enum.find_index/2 (function) iex> Enum.find_index([2, 4, 6], fn x -> rem(x, 2) == 1 end) nil iex> Enum.find_index([2, 3, 4], fn x -> rem(x, 2) == 1 end) 1 ### Enum.find_value/3 (function) Similar to `find/3`, but returns the value of the function invocation instead of the element itself. The return value is considered to be found when the result is truthy (neither `nil` nor `false`). ### Examples - Enum.find_value/3 (function) iex> Enum.find_value([2, 3, 4], fn x -> ...> if x > 2, do: x * x ...> end) 9 iex> Enum.find_value([2, 4, 6], fn x -> rem(x, 2) == 1 end) nil iex> Enum.find_value([2, 3, 4], fn x -> rem(x, 2) == 1 end) true iex> Enum.find_value([1, 2, 3], "no bools!", &is_boolean/1) "no bools!" ### Enum.flat_map/2 (function) Maps the given `fun` over `enumerable` and flattens the result. This function returns a new enumerable built by appending the result of invoking `fun` on each element of `enumerable` together; conceptually, this is similar to a combination of `map/2` and `concat/1`. ### Examples - Enum.flat_map/2 (function) iex> Enum.flat_map([:a, :b, :c], fn x -> [x, x] end) [:a, :a, :b, :b, :c, :c] iex> Enum.flat_map([{1, 3}, {4, 6}], fn {x, y} -> x..y end) [1, 2, 3, 4, 5, 6] iex> Enum.flat_map([:a, :b, :c], fn x -> [[x]] end) [[:a], [:b], [:c]] This is frequently used to to transform and filter in one pass, returning empty lists to exclude results: iex> Enum.flat_map([4, 0, 2, 0], fn x -> ...> if x != 0, do: [1 / x], else: [] ...> end) [0.25, 0.5] ### Enum.flat_map_reduce/3 (function) Maps and reduces an `enumerable`, flattening the given results (only one level deep). It expects an accumulator and a function that receives each enumerable element, and must return a tuple containing a new enumerable (often a list) with the new accumulator or a tuple with `:halt` as first element and the accumulator as second. ### Examples - Enum.flat_map_reduce/3 (function) iex> enumerable = 1..100 iex> n = 3 iex> Enum.flat_map_reduce(enumerable, 0, fn x, acc -> ...> if acc end) {[1, 2, 3], 3} iex> Enum.flat_map_reduce(1..5, 0, fn x, acc -> {[[x]], acc + x} end) {[[1], [2], [3], [4], [5]], 15} ### Enum.frequencies/1 (function) Returns a map with keys as unique elements of `enumerable` and values as the count of every element. ### Examples - Enum.frequencies/1 (function) iex> Enum.frequencies(~w{ant buffalo ant ant buffalo dingo}) %{"ant" => 3, "buffalo" => 2, "dingo" => 1} ### Enum.frequencies_by/2 (function) Returns a map with keys as unique elements given by `key_fun` and values as the count of every element. ### Examples - Enum.frequencies_by/2 (function) iex> Enum.frequencies_by(~w{aa aA bb cc}, &String.downcase/1) %{"aa" => 2, "bb" => 1, "cc" => 1} iex> Enum.frequencies_by(~w{aaa aA bbb cc c}, &String.length/1) %{3 => 2, 2 => 2, 1 => 1} ### Enum.group_by/3 (function) Splits the `enumerable` into groups based on `key_fun`. The result is a map where each key is given by `key_fun` and each value is a list of elements given by `value_fun`. The order of elements within each list is preserved from the `enumerable`. However, like all maps, the resulting map is unordered. ### Examples - Enum.group_by/3 (function) iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1) %{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]} iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1, &String.first/1) %{3 => ["a", "c"], 5 => ["d"], 7 => ["b"]} The key can be any Elixir value. For example, you may use a tuple to group by multiple keys: iex> collection = [ ...> %{id: 1, lang: "Elixir", seq: 1}, ...> %{id: 1, lang: "Java", seq: 1}, ...> %{id: 1, lang: "Ruby", seq: 2}, ...> %{id: 2, lang: "Python", seq: 1}, ...> %{id: 2, lang: "C#", seq: 2}, ...> %{id: 2, lang: "Haskell", seq: 2}, ...> ] iex> Enum.group_by(collection, &{&1.id, &1.seq}) %{ {1, 1} => [%{id: 1, lang: "Elixir", seq: 1}, %{id: 1, lang: "Java", seq: 1}], {1, 2} => [%{id: 1, lang: "Ruby", seq: 2}], {2, 1} => [%{id: 2, lang: "Python", seq: 1}], {2, 2} => [%{id: 2, lang: "C#", seq: 2}, %{id: 2, lang: "Haskell", seq: 2}] } iex> Enum.group_by(collection, &{&1.id, &1.seq}, &{&1.id, &1.lang}) %{ {1, 1} => [{1, "Elixir"}, {1, "Java"}], {1, 2} => [{1, "Ruby"}], {2, 1} => [{2, "Python"}], {2, 2} => [{2, "C#"}, {2, "Haskell"}] } ### Enum.intersperse/2 (function) Intersperses `separator` between each element of the enumeration. ### Examples - Enum.intersperse/2 (function) iex> Enum.intersperse([1, 2, 3], 0) [1, 0, 2, 0, 3] iex> Enum.intersperse([1], 0) [1] iex> Enum.intersperse([], 0) [] ### Enum.into/2 (function) Inserts the given `enumerable` into a `collectable`. Note that passing a non-empty list as the `collectable` is deprecated. If you're collecting into a non-empty keyword list, consider using `Keyword.merge(collectable, Enum.to_list(enumerable))`. If you're collecting into a non-empty list, consider something like `Enum.to_list(enumerable) ++ collectable`. ### Examples - Enum.into/2 (function) iex> Enum.into([1, 2], []) [1, 2] iex> Enum.into([a: 1, b: 2], %{}) %{a: 1, b: 2} iex> Enum.into(%{a: 1}, %{b: 2}) %{a: 1, b: 2} iex> Enum.into([a: 1, a: 2], %{}) %{a: 2} iex> Enum.into([a: 2], %{a: 1, b: 3}) %{a: 2, b: 3} ### Enum.into/3 (function) Inserts the given `enumerable` into a `collectable` according to the transformation function. ### Examples - Enum.into/3 (function) iex> Enum.into([1, 2, 3], [], fn x -> x * 3 end) [3, 6, 9] iex> Enum.into(%{a: 1, b: 2}, %{c: 3}, fn {k, v} -> {k, v * 2} end) %{a: 2, b: 4, c: 3} ### Enum.join/2 (function) Joins the given `enumerable` into a string using `joiner` as a separator. If `joiner` is not passed at all, it defaults to an empty string. All elements in the `enumerable` must be convertible to a string or be a binary, otherwise an error is raised. ### Examples - Enum.join/2 (function) iex> Enum.join([1, 2, 3]) "123" iex> Enum.join([1, 2, 3], " = ") "1 = 2 = 3" iex> Enum.join([["a", "b"], ["c", "d", "e", ["f", "g"]], "h", "i"], " ") "ab cdefg h i" ### Enum.map/2 (function) Returns a list where each element is the result of invoking `fun` on each corresponding element of `enumerable`. For maps, the function expects a key-value tuple. ### Examples - Enum.map/2 (function) iex> Enum.map([1, 2, 3], fn x -> x * 2 end) [2, 4, 6] iex> Enum.map([a: 1, b: 2], fn {k, v} -> {k, -v} end) [a: -1, b: -2] ### Enum.map_every/3 (function) Returns a list of results of invoking `fun` on every `nth` element of `enumerable`, starting with the first element. The first element is always passed to the given function, unless `nth` is `0`. The second argument specifying every `nth` element must be a non-negative integer. If `nth` is `0`, then `enumerable` is directly converted to a list, without `fun` being ever applied. ### Examples - Enum.map_every/3 (function) iex> Enum.map_every(1..10, 2, fn x -> x + 1000 end) [1001, 2, 1003, 4, 1005, 6, 1007, 8, 1009, 10] iex> Enum.map_every(1..10, 3, fn x -> x + 1000 end) [1001, 2, 3, 1004, 5, 6, 1007, 8, 9, 1010] iex> Enum.map_every(1..5, 0, fn x -> x + 1000 end) [1, 2, 3, 4, 5] iex> Enum.map_every([1, 2, 3], 1, fn x -> x + 1000 end) [1001, 1002, 1003] ### Enum.map_intersperse/3 (function) Maps and intersperses the given enumerable in one pass. ### Examples - Enum.map_intersperse/3 (function) iex> Enum.map_intersperse([1, 2, 3], :a, &(&1 * 2)) [2, :a, 4, :a, 6] ### Enum.map_join/3 (function) Maps and joins the given `enumerable` in one pass. If `joiner` is not passed at all, it defaults to an empty string. All elements returned from invoking the `mapper` must be convertible to a string, otherwise an error is raised. ### Examples - Enum.map_join/3 (function) iex> Enum.map_join([1, 2, 3], &(&1 * 2)) "246" iex> Enum.map_join([1, 2, 3], " = ", &(&1 * 2)) "2 = 4 = 6" ### Enum.map_reduce/3 (function) Invokes the given function to each element in the `enumerable` to reduce it to a single element, while keeping an accumulator. Returns a tuple where the first element is the mapped enumerable and the second one is the final accumulator. The function, `fun`, receives two arguments: the first one is the element, and the second one is the accumulator. `fun` must return a tuple with two elements in the form of `{result, accumulator}`. For maps, the first tuple element must be a `{key, value}` tuple. ### Examples - Enum.map_reduce/3 (function) iex> Enum.map_reduce([1, 2, 3], 0, fn x, acc -> {x * 2, x + acc} end) {[2, 4, 6], 6} ### Enum.max/3 (function) Returns the maximal element in the `enumerable` according to Erlang's term ordering. By default, the comparison is done with the `>=` sorter function. If multiple elements are considered maximal, the first one that was found is returned. If you want the last element considered maximal to be returned, the sorter function should not return true for equal elements. If the enumerable is empty, the provided `empty_fallback` is called. The default `empty_fallback` raises `Enum.EmptyError`. ### Examples - Enum.max/3 (function) iex> Enum.max([1, 2, 3]) 3 The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. For example: iex> Enum.max([~D[2017-03-31], ~D[2017-04-01]]) ~D[2017-03-31] In the example above, `max/2` returned March 31st instead of April 1st because the structural comparison compares the day before the year. For this reason, most structs provide a "compare" function, such as `Date.compare/2`, which receives two structs and returns `:lt` (less-than), `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the sorting function, Elixir will automatically use the `compare/2` function of said module: iex> Enum.max([~D[2017-03-31], ~D[2017-04-01]], Date) ~D[2017-04-01] Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback: iex> Enum.max([], &>=/2, fn -> 0 end) 0 ### Enum.max_by/4 (function) Returns the maximal element in the `enumerable` as calculated by the given `fun`. By default, the comparison is done with the `>=` sorter function. If multiple elements are considered maximal, the first one that was found is returned. If you want the last element considered maximal to be returned, the sorter function should not return true for equal elements. Calls the provided `empty_fallback` function and returns its value if `enumerable` is empty. The default `empty_fallback` raises `Enum.EmptyError`. ### Examples - Enum.max_by/4 (function) iex> Enum.max_by(["a", "aa", "aaa"], fn x -> String.length(x) end) "aaa" iex> Enum.max_by(["a", "aa", "aaa", "b", "bbb"], &String.length/1) "aaa" The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. Therefore, if you want to compare structs, most structs provide a "compare" function, such as `Date.compare/2`, which receives two structs and returns `:lt` (less-than), `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the sorting function, Elixir will automatically use the `compare/2` function of said module: iex> users = [ ...> %{name: "Ellis", birthday: ~D[1943-05-11]}, ...> %{name: "Lovelace", birthday: ~D[1815-12-10]}, ...> %{name: "Turing", birthday: ~D[1912-06-23]} ...> ] iex> Enum.max_by(users, &(&1.birthday), Date) %{name: "Ellis", birthday: ~D[1943-05-11]} Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback: iex> Enum.max_by([], &String.length/1, fn -> nil end) nil ### Enum.member?/2 (function) Checks if `element` exists within the `enumerable`. Membership is tested with the match (`===/2`) operator. ### Examples - Enum.member?/2 (function) iex> Enum.member?(1..10, 5) true iex> Enum.member?(1..10, 5.0) false iex> Enum.member?([1.0, 2.0, 3.0], 2) false iex> Enum.member?([1.0, 2.0, 3.0], 2.000) true iex> Enum.member?([:a, :b, :c], :d) false When called outside guards, the [`in`](`in/2`) and [`not in`](`in/2`) operators work by using this function. ### Enum.min/3 (function) Returns the minimal element in the `enumerable` according to Erlang's term ordering. By default, the comparison is done with the `<=` sorter function. If multiple elements are considered minimal, the first one that was found is returned. If you want the last element considered minimal to be returned, the sorter function should not return true for equal elements. If the enumerable is empty, the provided `empty_fallback` is called. The default `empty_fallback` raises `Enum.EmptyError`. ### Examples - Enum.min/3 (function) iex> Enum.min([1, 2, 3]) 1 The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. For example: iex> Enum.min([~D[2017-03-31], ~D[2017-04-01]]) ~D[2017-04-01] In the example above, `min/2` returned April 1st instead of March 31st because the structural comparison compares the day before the year. For this reason, most structs provide a "compare" function, such as `Date.compare/2`, which receives two structs and returns `:lt` (less-than), `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the sorting function, Elixir will automatically use the `compare/2` function of said module: iex> Enum.min([~D[2017-03-31], ~D[2017-04-01]], Date) ~D[2017-03-31] Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback: iex> Enum.min([], fn -> 0 end) 0 ### Enum.min_by/4 (function) Returns the minimal element in the `enumerable` as calculated by the given `fun`. By default, the comparison is done with the `<=` sorter function. If multiple elements are considered minimal, the first one that was found is returned. If you want the last element considered minimal to be returned, the sorter function should not return true for equal elements. Calls the provided `empty_fallback` function and returns its value if `enumerable` is empty. The default `empty_fallback` raises `Enum.EmptyError`. ### Examples - Enum.min_by/4 (function) iex> Enum.min_by(["a", "aa", "aaa"], fn x -> String.length(x) end) "a" iex> Enum.min_by(["a", "aa", "aaa", "b", "bbb"], &String.length/1) "a" The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. Therefore, if you want to compare structs, most structs provide a "compare" function, such as `Date.compare/2`, which receives two structs and returns `:lt` (less-than), `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the sorting function, Elixir will automatically use the `compare/2` function of said module: iex> users = [ ...> %{name: "Ellis", birthday: ~D[1943-05-11]}, ...> %{name: "Lovelace", birthday: ~D[1815-12-10]}, ...> %{name: "Turing", birthday: ~D[1912-06-23]} ...> ] iex> Enum.min_by(users, &(&1.birthday), Date) %{name: "Lovelace", birthday: ~D[1815-12-10]} Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback: iex> Enum.min_by([], &String.length/1, fn -> nil end) nil ### Enum.min_max/2 (function) Returns a tuple with the minimal and the maximal elements in the enumerable according to Erlang's term ordering. If multiple elements are considered maximal or minimal, the first one that was found is returned. Calls the provided `empty_fallback` function and returns its value if `enumerable` is empty. The default `empty_fallback` raises `Enum.EmptyError`. ### Examples - Enum.min_max/2 (function) iex> Enum.min_max([2, 3, 1]) {1, 3} iex> Enum.min_max([], fn -> {nil, nil} end) {nil, nil} ### Enum.min_max_by/4 (function) Returns a tuple with the minimal and the maximal elements in the enumerable as calculated by the given function. If multiple elements are considered maximal or minimal, the first one that was found is returned. ### Examples - Enum.min_max_by/4 (function) iex> Enum.min_max_by(["aaa", "bb", "c"], fn x -> String.length(x) end) {"c", "aaa"} iex> Enum.min_max_by(["aaa", "a", "bb", "c", "ccc"], &String.length/1) {"a", "aaa"} iex> Enum.min_max_by([], &String.length/1, fn -> {nil, nil} end) {nil, nil} The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. Therefore, if you want to compare structs, most structs provide a "compare" function, such as `Date.compare/2`, which receives two structs and returns `:lt` (less-than), `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the sorting function, Elixir will automatically use the `compare/2` function of said module: iex> users = [ ...> %{name: "Ellis", birthday: ~D[1943-05-11]}, ...> %{name: "Lovelace", birthday: ~D[1815-12-10]}, ...> %{name: "Turing", birthday: ~D[1912-06-23]} ...> ] iex> Enum.min_max_by(users, &(&1.birthday), Date) { %{name: "Lovelace", birthday: ~D[1815-12-10]}, %{name: "Ellis", birthday: ~D[1943-05-11]} } Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback: iex> Enum.min_max_by([], &String.length/1, fn -> nil end) nil ### Enum.product/1 (function) Returns the product of all elements. Raises `ArithmeticError` if `enumerable` contains a non-numeric value. If you need to apply a transformation first, consider using `Enum.product_by/2` instead. ### Examples - Enum.product/1 (function) iex> Enum.product([]) 1 iex> Enum.product([2, 3, 4]) 24 iex> Enum.product([2.0, 3.0, 4.0]) 24.0 ### Enum.product_by/2 (function) Maps and computes the product of the given `enumerable` in one pass. Raises `ArithmeticError` if `mapper` returns a non-numeric value. ### Examples - Enum.product_by/2 (function) iex> Enum.product_by([%{count: 2}, %{count: 4}, %{count: 3}], fn x -> x.count end) 24 iex> Enum.product_by(1..3, fn x -> x ** 2 end) 36 iex> Enum.product_by([], fn x -> x.count end) 1 Filtering can be achieved by returning `1` to ignore elements: iex> Enum.product_by([2, -1, 3], fn x -> if x > 0, do: x, else: 1 end) 6 ### Enum.random/1 (function) Returns a random element of an `enumerable`. Raises `Enum.EmptyError` if `enumerable` is empty. This function uses Erlang's [`:rand` module](`:rand`) to calculate the random value. Check its documentation for setting a different random algorithm or a different seed. If a range is passed into the function, this function will pick a random value between the range limits, without traversing the whole range (thus executing in constant time and constant memory). ### Examples - Enum.random/1 (function) The examples below use the `:exsss` pseudorandom algorithm since it's the default from Erlang/OTP 22: # Although not necessary, let's seed the random algorithm iex> :rand.seed(:exsss, {100, 101, 102}) iex> Enum.random([1, 2, 3]) 2 iex> Enum.random([1, 2, 3]) 1 iex> Enum.random(1..1_000) 309 ### Implementation - Enum.random/1 (function) The random functions in this module implement reservoir sampling, which allows them to sample infinite collections. In particular, we implement Algorithm L, as described in by Kim-Hung Li in "Reservoir-Sampling Algorithms of Time Complexity O(n(1+log(N/n)))". ### Enum.reduce/2 (function) Invokes `fun` for each element in the `enumerable` with the accumulator. Raises `Enum.EmptyError` if `enumerable` is empty. The first element of the `enumerable` is used as the initial value of the accumulator. Then, the function is invoked with the next element and the accumulator. The result returned by the function is used as the accumulator for the next iteration, recursively. When the `enumerable` is done, the last accumulator is returned. Since the first element of the enumerable is used as the initial value of the accumulator, `fun` will only be executed `n - 1` times where `n` is the length of the enumerable. This function won't call the specified function for enumerables that are one-element long. If you wish to use another value for the accumulator, use `Enum.reduce/3`. ### Examples - Enum.reduce/2 (function) iex> Enum.reduce([1, 2, 3, 4], fn x, acc -> x * acc end) 24 ### Enum.reduce/3 (function) Invokes `fun` for each element in the `enumerable` with the accumulator. The initial value of the accumulator is `acc`. The function is invoked for each element in the enumerable with the accumulator. The result returned by the function is used as the accumulator for the next iteration. The function returns the last accumulator. ### Examples - Enum.reduce/3 (function) iex> Enum.reduce([1, 2, 3], 0, fn x, acc -> x + acc end) 6 iex> Enum.reduce(%{a: 2, b: 3, c: 4}, 0, fn {_key, val}, acc -> acc + val end) 9 ### Reduce as a building block - Enum.reduce/3 (function) Reduce (sometimes called `fold`) is a basic building block in functional programming. Almost all of the functions in the `Enum` module can be implemented on top of reduce. Those functions often rely on other operations, such as `Enum.reverse/1`, which are optimized by the runtime. For example, we could implement `map/2` in terms of `reduce/3` as follows: def my_map(enumerable, fun) do enumerable |> Enum.reduce([], fn x, acc -> [fun.(x) | acc] end) |> Enum.reverse() end In the example above, `Enum.reduce/3` accumulates the result of each call to `fun` into a list in reverse order, which is correctly ordered at the end by calling `Enum.reverse/1`. Implementing functions like `map/2`, `filter/2` and others are a good exercise for understanding the power behind `Enum.reduce/3`. When an operation cannot be expressed by any of the functions in the `Enum` module, developers will most likely resort to `reduce/3`. ### Enum.reduce_while/3 (function) Reduces `enumerable` until `fun` returns `{:halt, term}`. The return value for `fun` is expected to be * `{:cont, acc}` to continue the reduction with `acc` as the new accumulator or * `{:halt, acc}` to halt the reduction If `fun` returns `{:halt, acc}` the reduction is halted and the function returns `acc`. Otherwise, if the enumerable is exhausted, the function returns the accumulator of the last `{:cont, acc}`. ### Examples - Enum.reduce_while/3 (function) iex> Enum.reduce_while(1..100, 0, fn x, acc -> ...> if x < 5 do ...> {:cont, acc + x} ...> else ...> {:halt, acc} ...> end ...> end) 10 iex> Enum.reduce_while(1..100, 0, fn x, acc -> ...> if x > 0 do ...> {:cont, acc + x} ...> else ...> {:halt, acc} ...> end ...> end) 5050 ### Enum.reject/2 (function) Returns a list of elements in `enumerable` excluding those for which the function `fun` returns a truthy value. See also `filter/2`. ### Examples - Enum.reject/2 (function) iex> Enum.reject([1, 2, 3], fn x -> rem(x, 2) == 0 end) [1, 3] ### Enum.reverse/1 (function) Returns a list of elements in `enumerable` in reverse order. ### Examples - Enum.reverse/1 (function) iex> Enum.reverse([1, 2, 3]) [3, 2, 1] ### Enum.reverse/2 (function) Reverses the elements in `enumerable`, appends the `tail`, and returns it as a list. This is an optimization for `enumerable |> Enum.reverse() |> Enum.concat(tail)`. ### Examples - Enum.reverse/2 (function) iex> Enum.reverse([1, 2, 3], [4, 5, 6]) [3, 2, 1, 4, 5, 6] ### Enum.reverse_slice/3 (function) Reverses the `enumerable` in the range from initial `start_index` through `count` elements. If `count` is greater than the size of the rest of the `enumerable`, then this function will reverse the rest of the enumerable. ### Examples - Enum.reverse_slice/3 (function) iex> Enum.reverse_slice([1, 2, 3, 4, 5, 6], 2, 4) [1, 2, 6, 5, 4, 3] ### Enum.scan/2 (function) Applies the given function to each element in the `enumerable`, storing the result in a list and passing it as the accumulator for the next computation. Uses the first element in the `enumerable` as the starting value. ### Examples - Enum.scan/2 (function) iex> Enum.scan(1..5, &(&1 + &2)) [1, 3, 6, 10, 15] ### Enum.scan/3 (function) Applies the given function to each element in the `enumerable`, storing the result in a list and passing it as the accumulator for the next computation. Uses the given `acc` as the starting value. ### Examples - Enum.scan/3 (function) iex> Enum.scan(1..5, 0, &(&1 + &2)) [1, 3, 6, 10, 15] ### Enum.shuffle/1 (function) Returns a list with the elements of `enumerable` shuffled. This function uses Erlang's [`:rand` module](`:rand`) to calculate the random value. Check its documentation for setting a different random algorithm or a different seed. ### Examples - Enum.shuffle/1 (function) The examples below use the `:exsss` pseudorandom algorithm since it's the default from Erlang/OTP 22: # Although not necessary, let's seed the random algorithm iex> :rand.seed(:exsss, {11, 22, 33}) iex> Enum.shuffle([1, 2, 3]) [2, 1, 3] iex> Enum.shuffle([1, 2, 3]) [2, 3, 1] ### Enum.slice/2 (function) Returns a subset list of the given `enumerable` by `index_range`. `index_range` must be a `Range`. Given an `enumerable`, it drops elements before `index_range.first` (zero-base), then it takes elements until element `index_range.last` (inclusively). Indexes are normalized, meaning that negative indexes will be counted from the end (for example, `-1` means the last element of the `enumerable`). If `index_range.last` is out of bounds, then it is assigned as the index of the last element. If the normalized `index_range.first` is out of bounds of the given `enumerable`, or this one is greater than the normalized `index_range.last`, then `[]` is returned. If a step `n` (other than `1`) is used in `index_range`, then it takes every `n`th element from `index_range.first` to `index_range.last` (according to the same rules described above). ### Examples - Enum.slice/2 (function) iex> Enum.slice([1, 2, 3, 4, 5], 1..3) [2, 3, 4] iex> Enum.slice([1, 2, 3, 4, 5], 3..10) [4, 5] # Last three elements (negative indexes) iex> Enum.slice([1, 2, 3, 4, 5], -3..-1) [3, 4, 5] For ranges where `start > stop`, you need to explicit mark them as increasing: iex> Enum.slice([1, 2, 3, 4, 5], 1..-2//1) [2, 3, 4] The step can be any positive number. For example, to get every 2 elements of the collection: iex> Enum.slice([1, 2, 3, 4, 5], 0..-1//2) [1, 3, 5] To get every third element of the first ten elements: iex> integers = Enum.to_list(1..20) iex> Enum.slice(integers, 0..9//3) [1, 4, 7, 10] If the first position is after the end of the enumerable or after the last position of the range, it returns an empty list: iex> Enum.slice([1, 2, 3, 4, 5], 6..10) [] # first is greater than last iex> Enum.slice([1, 2, 3, 4, 5], 6..5//1) [] ### Enum.slice/3 (function) Returns a subset list of the given `enumerable`, from `start_index` (zero-based) with `amount` number of elements if available. Given an `enumerable`, it drops elements right before element `start_index`; then, it takes `amount` of elements, returning as many elements as possible if there are not enough elements. A negative `start_index` can be passed, which means the `enumerable` is enumerated once and the index is counted from the end (for example, `-1` starts slicing from the last element). It returns `[]` if `amount` is `0` or if `start_index` is out of bounds. ### Examples - Enum.slice/3 (function) iex> Enum.slice(1..100, 5, 10) [6, 7, 8, 9, 10, 11, 12, 13, 14, 15] # amount to take is greater than the number of elements iex> Enum.slice(1..10, 5, 100) [6, 7, 8, 9, 10] iex> Enum.slice(1..10, 5, 0) [] # using a negative start index iex> Enum.slice(1..10, -6, 3) [5, 6, 7] iex> Enum.slice(1..10, -11, 5) [1, 2, 3, 4, 5] # out of bound start index iex> Enum.slice(1..10, 10, 5) [] ### Enum.slide/3 (function) Slides a single or multiple elements given by `range_or_single_index` from `enumerable` to `insertion_index`. The semantics of the range to be moved match the semantics of `Enum.slice/2`. Specifically, that means: * Indices are normalized, meaning that negative indexes will be counted from the end (for example, -1 means the last element of the enumerable). This will result in *two* traversals of your enumerable on types like lists that don't provide a constant-time count. * If the normalized index range's `last` is out of bounds, the range is truncated to the last element. * If the normalized index range's `first` is out of bounds, the selected range for sliding will be empty, so you'll get back your input list. * Decreasing ranges (such as `5..0//1`) also select an empty range to be moved, so you'll get back your input list. * Ranges with any step but 1 will raise an error. ### Examples - Enum.slide/3 (function) # Slide a single element iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 5, 1) [:a, :f, :b, :c, :d, :e, :g] # Slide a range of elements towards the head of the list iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3..5, 1) [:a, :d, :e, :f, :b, :c, :g] # Slide a range of elements towards the tail of the list iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 1..3, 5) [:a, :e, :f, :b, :c, :d, :g] # Slide with negative indices (counting from the end) iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3..-1//1, 2) [:a, :b, :d, :e, :f, :g, :c] iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], -4..-2, 1) [:a, :d, :e, :f, :b, :c, :g] # Insert at negative indices (counting from the end) iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3, -1) [:a, :b, :c, :e, :f, :g, :d] ### Enum.sort/1 (function) Sorts the `enumerable` according to Erlang's term ordering. This function uses the merge sort algorithm. Do not use this function to sort structs, see `sort/2` for more information. ### Examples - Enum.sort/1 (function) iex> Enum.sort([3, 2, 1]) [1, 2, 3] ### Enum.sort/2 (function) Sorts the `enumerable` by the given function. This function uses the merge sort algorithm. The given function should compare two arguments, and return `true` if the first argument precedes or is in the same place as the second one. ### Examples - Enum.sort/2 (function) iex> Enum.sort([1, 2, 3], &(&1 >= &2)) [3, 2, 1] The sorting algorithm will be stable as long as the given function returns `true` for values considered equal: iex> Enum.sort(["some", "kind", "of", "monster"], &(byte_size(&1) <= byte_size(&2))) ["of", "some", "kind", "monster"] If the function does not return `true` for equal values, the sorting is not stable and the order of equal terms may be shuffled. For example: iex> Enum.sort(["some", "kind", "of", "monster"], &(byte_size(&1) < byte_size(&2))) ["of", "kind", "some", "monster"] ### Ascending and descending (since v1.10.0) - Enum.sort/2 (function) `sort/2` allows a developer to pass `:asc` or `:desc` as the sorter, which is a convenience for [`&<=/2`](`<=/2`) and [`&>=/2`](`>=/2`) respectively. iex> Enum.sort([2, 3, 1], :asc) [1, 2, 3] iex> Enum.sort([2, 3, 1], :desc) [3, 2, 1] ### Sorting structs - Enum.sort/2 (function) Do not use `/2`, `>=/2` and friends when sorting structs. That's because the built-in operators above perform structural comparison and not a semantic one. Imagine we sort the following list of dates: iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] iex> Enum.sort(dates) [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] Note that the returned result is incorrect, because `sort/1` by default uses `<=/2`, which will compare their structure. When comparing structures, the fields are compared in alphabetical order, which means the dates above will be compared by `day`, `month` and then `year`, which is the opposite of what we want. For this reason, most structs provide a "compare" function, such as `Date.compare/2`, which receives two structs and returns `:lt` (less-than), `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the sorting function, Elixir will automatically use the `compare/2` function of said module: iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] iex> Enum.sort(dates, Date) [~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]] To retrieve all dates in descending order, you can wrap the module in a tuple with `:asc` or `:desc` as first element: iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] iex> Enum.sort(dates, {:asc, Date}) [~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]] iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] iex> Enum.sort(dates, {:desc, Date}) [~D[2020-03-02], ~D[2019-06-06], ~D[2019-01-01]] ### Enum.sort_by/3 (function) Sorts the mapped results of the `enumerable` according to the provided `sorter` function. This function maps each element of the `enumerable` using the provided `mapper` function. The enumerable is then sorted by the mapped elements using the `sorter`, which defaults to `:asc` and sorts the elements ascendingly. `sort_by/3` differs from `sort/2` in that it only calculates the comparison value for each element in the enumerable once instead of once for each element in each comparison. If the same function is being called on both elements, it's more efficient to use `sort_by/3`. ### Ascending and descending (since v1.10.0) - Enum.sort_by/3 (function) `sort_by/3` allows a developer to pass `:asc` or `:desc` as the sorter, which is a convenience for [`&<=/2`](`<=/2`) and [`&>=/2`](`>=/2`) respectively: iex> Enum.sort_by([2, 3, 1], &(&1), :asc) [1, 2, 3] iex> Enum.sort_by([2, 3, 1], &(&1), :desc) [3, 2, 1] ### Examples - Enum.sort_by/3 (function) Using the default `sorter` of `:asc` : iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1) ["of", "some", "kind", "monster"] Sorting by multiple properties - first by size, then by first letter (this takes advantage of the fact that tuples are compared element-by-element): iex> Enum.sort_by(["some", "kind", "of", "monster"], &{byte_size(&1), String.first(&1)}) ["of", "kind", "some", "monster"] Similar to `sort/2`, you can pass a custom sorter: iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1, :desc) ["monster", "some", "kind", "of"] As in `sort/2`, avoid using the default sorting function to sort structs, as by default it performs structural comparison instead of a semantic one. In such cases, you shall pass a sorting function as third element or any module that implements a `compare/2` function. For example, to sort users by their birthday in both ascending and descending order respectively: iex> users = [ ...> %{name: "Ellis", birthday: ~D[1943-05-11]}, ...> %{name: "Lovelace", birthday: ~D[1815-12-10]}, ...> %{name: "Turing", birthday: ~D[1912-06-23]} ...> ] iex> Enum.sort_by(users, &(&1.birthday), Date) [ %{name: "Lovelace", birthday: ~D[1815-12-10]}, %{name: "Turing", birthday: ~D[1912-06-23]}, %{name: "Ellis", birthday: ~D[1943-05-11]} ] iex> Enum.sort_by(users, &(&1.birthday), {:desc, Date}) [ %{name: "Ellis", birthday: ~D[1943-05-11]}, %{name: "Turing", birthday: ~D[1912-06-23]}, %{name: "Lovelace", birthday: ~D[1815-12-10]} ] ### Performance characteristics - Enum.sort_by/3 (function) As detailed in the initial section, `sort_by/3` calculates the comparison value for each element in the enumerable once instead of once for each element in each comparison. This implies `sort_by/3` must do an initial pass on the data to compute those values. However, if those values are cheap to compute, for example, you have already extracted the field you want to sort by into a tuple, then those extra passes become overhead. In such cases, consider using `List.keysort/3` instead. Let's see an example. Imagine you have a list of products and you have a list of IDs. You want to keep all products that are in the given IDs and return their names sorted by their price. You could write it like this: for( product <- products, product.id in ids, do: product ) |> Enum.sort_by(& &1.price) |> Enum.map(& &1.name) However, you could also write it like this: for( product <- products, product.id in ids, do: {product.name, product.price} ) |> List.keysort(1) |> Enum.map(&elem(&1, 0)) Using `List.keysort/3` will be a better choice for performance sensitive code as it avoids additional traversals. ### Enum.split/2 (function) Splits the `enumerable` into two enumerables, leaving `count` elements in the first one. If `count` is a negative number, it starts counting from the back to the beginning of the `enumerable`. Be aware that a negative `count` implies the `enumerable` will be enumerated twice: once to calculate the position, and a second time to do the actual splitting. ### Examples - Enum.split/2 (function) iex> Enum.split([1, 2, 3], 2) {[1, 2], [3]} iex> Enum.split([1, 2, 3], 10) {[1, 2, 3], []} iex> Enum.split([1, 2, 3], 0) {[], [1, 2, 3]} iex> Enum.split([1, 2, 3], -1) {[1, 2], [3]} iex> Enum.split([1, 2, 3], -5) {[], [1, 2, 3]} ### Enum.split_while/2 (function) Splits enumerable in two at the position of the element for which `fun` returns a falsy value (`false` or `nil`) for the first time. It returns a two-element tuple with two lists of elements. The element that triggered the split is part of the second list. ### Examples - Enum.split_while/2 (function) iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 3 end) {[1, 2], [3, 4]} iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 0 end) {[], [1, 2, 3, 4]} iex> Enum.split_while([1, 2, 3, 4], fn x -> x > 0 end) {[1, 2, 3, 4], []} ### Enum.split_with/2 (function) Splits the `enumerable` in two lists according to the given function `fun`. Splits the given `enumerable` in two lists by calling `fun` with each element in the `enumerable` as its only argument. Returns a tuple with the first list containing all the elements in `enumerable` for which applying `fun` returned a truthy value, and a second list with all the elements for which applying `fun` returned a falsy value (`false` or `nil`). The elements in both the returned lists are in the same relative order as they were in the original enumerable (if such enumerable was ordered, like a list). See the examples below. ### Examples - Enum.split_with/2 (function) iex> Enum.split_with([5, 4, 3, 2, 1, 0], fn x -> rem(x, 2) == 0 end) {[4, 2, 0], [5, 3, 1]} iex> Enum.split_with([a: 1, b: -2, c: 1, d: -3], fn {_k, v} -> v < 0 end) {[b: -2, d: -3], [a: 1, c: 1]} iex> Enum.split_with([a: 1, b: -2, c: 1, d: -3], fn {_k, v} -> v > 50 end) {[], [a: 1, b: -2, c: 1, d: -3]} iex> Enum.split_with([], fn {_k, v} -> v > 50 end) {[], []} ### Enum.sum/1 (function) Returns the sum of all elements. Raises `ArithmeticError` if `enumerable` contains a non-numeric value. If you need to apply a transformation first, consider using `Enum.sum_by/2` instead. ### Examples - Enum.sum/1 (function) iex> Enum.sum([1, 2, 3]) 6 iex> Enum.sum(1..10) 55 iex> Enum.sum(1..10//2) 25 ### Enum.sum_by/2 (function) Maps and sums the given `enumerable` in one pass. Raises `ArithmeticError` if `mapper` returns a non-numeric value. ### Examples - Enum.sum_by/2 (function) iex> Enum.sum_by([%{count: 1}, %{count: 2}, %{count: 3}], fn x -> x.count end) 6 iex> Enum.sum_by(1..3, fn x -> x ** 2 end) 14 iex> Enum.sum_by([], fn x -> x.count end) 0 Filtering can be achieved by returning `0` to ignore elements: iex> Enum.sum_by([1, -2, 3], fn x -> if x > 0, do: x, else: 0 end) 4 ### Enum.take/2 (function) Takes an `amount` of elements from the beginning or the end of the `enumerable`. If a positive `amount` is given, it takes the `amount` elements from the beginning of the `enumerable`. If a negative `amount` is given, the `amount` of elements will be taken from the end. The `enumerable` will be enumerated once to retrieve the proper index and the remaining calculation is performed from the end. If amount is `0`, it returns `[]`. ### Examples - Enum.take/2 (function) iex> Enum.take([1, 2, 3], 2) [1, 2] iex> Enum.take([1, 2, 3], 10) [1, 2, 3] iex> Enum.take([1, 2, 3], 0) [] iex> Enum.take([1, 2, 3], -1) [3] ### Enum.take_every/2 (function) Returns a list of every `nth` element in the `enumerable`, starting with the first element. The first element is always included, unless `nth` is 0. The second argument specifying every `nth` element must be a non-negative integer. ### Examples - Enum.take_every/2 (function) iex> Enum.take_every(1..10, 2) [1, 3, 5, 7, 9] iex> Enum.take_every(1..10, 0) [] iex> Enum.take_every([1, 2, 3], 1) [1, 2, 3] ### Enum.take_random/2 (function) Takes `count` random elements from `enumerable`. Note that this function will traverse the whole `enumerable` to get the random sublist. See `random/1` for notes on implementation and random seed. ### Examples - Enum.take_random/2 (function) # Although not necessary, let's seed the random algorithm iex> :rand.seed(:exsss, {1, 2, 3}) iex> Enum.take_random(1..10, 2) [6, 1] iex> Enum.take_random(?a..?z, 5) ~c"bkzmt" ### Enum.take_while/2 (function) Takes the elements from the beginning of the `enumerable` while `fun` returns a truthy value. ### Examples - Enum.take_while/2 (function) iex> Enum.take_while([1, 2, 3], fn x -> x < 3 end) [1, 2] ### Enum.to_list/1 (function) Converts `enumerable` to a list. ### Examples - Enum.to_list/1 (function) iex> Enum.to_list(1..3) [1, 2, 3] ### Enum.uniq/1 (function) Enumerates the `enumerable`, removing all duplicate elements. ### Examples - Enum.uniq/1 (function) iex> Enum.uniq([1, 2, 3, 3, 2, 1]) [1, 2, 3] ### Enum.uniq_by/2 (function) Enumerates the `enumerable`, by removing the elements for which function `fun` returned duplicate elements. The function `fun` maps every element to a term. Two elements are considered duplicates if the return value of `fun` is equal for both of them. The first occurrence of each element is kept. ### Example - Enum.uniq_by/2 (function) iex> Enum.uniq_by([{1, :x}, {2, :y}, {1, :z}], fn {x, _} -> x end) [{1, :x}, {2, :y}] iex> Enum.uniq_by([a: {:tea, 2}, b: {:tea, 2}, c: {:coffee, 1}], fn {_, y} -> y end) [a: {:tea, 2}, c: {:coffee, 1}] ### Enum.unzip/1 (function) Opposite of `zip/2`. Extracts two-element tuples from the given `enumerable` and groups them together. It takes an `enumerable` with elements being two-element tuples and returns a tuple with two lists, each of which is formed by the first and second element of each tuple, respectively. This function fails unless `enumerable` is or can be converted into a list of tuples with *exactly* two elements in each tuple. ### Examples - Enum.unzip/1 (function) iex> Enum.unzip([{:a, 1}, {:b, 2}, {:c, 3}]) {[:a, :b, :c], [1, 2, 3]} ### Enum.with_index/2 (function) Returns the `enumerable` with each element wrapped in a tuple alongside its index or according to a given function. If an integer offset is given as `fun_or_offset`, it will index from the given offset instead of from zero. If a function is given as `fun_or_offset`, it will index by invoking the function for each element and index (zero-based) of the enumerable. ### Examples - Enum.with_index/2 (function) iex> Enum.with_index([:a, :b, :c]) [a: 0, b: 1, c: 2] iex> Enum.with_index([:a, :b, :c], 3) [a: 3, b: 4, c: 5] iex> Enum.with_index([:a, :b, :c], fn element, index -> {index, element} end) [{0, :a}, {1, :b}, {2, :c}] ### Enum.zip/1 (function) Zips corresponding elements from a finite collection of enumerables into a list of tuples. The zipping finishes as soon as any enumerable in the given collection completes. ### Examples - Enum.zip/1 (function) iex> Enum.zip([[1, 2, 3], [:a, :b, :c], ["foo", "bar", "baz"]]) [{1, :a, "foo"}, {2, :b, "bar"}, {3, :c, "baz"}] iex> Enum.zip([[1, 2, 3, 4, 5], [:a, :b, :c]]) [{1, :a}, {2, :b}, {3, :c}] ### Enum.zip/2 (function) Zips corresponding elements from two enumerables into a list of tuples. Because a list of two-element tuples with atoms as the first tuple element is a keyword list (`Keyword`), zipping a first list of atoms with a second list of any kind creates a keyword list. The zipping finishes as soon as either enumerable completes. ### Examples - Enum.zip/2 (function) iex> Enum.zip([1, 2, 3], [:a, :b, :c]) [{1, :a}, {2, :b}, {3, :c}] iex> Enum.zip([:a, :b, :c], [1, 2, 3]) [a: 1, b: 2, c: 3] iex> Enum.zip([1, 2, 3, 4, 5], [:a, :b, :c]) [{1, :a}, {2, :b}, {3, :c}] ### Enum.zip_reduce/3 (function) Reduces over all of the given enumerables, halting as soon as any enumerable is empty. The reducer will receive 2 args: a list of elements (one from each enum) and the accumulator. In practice, the behavior provided by this function can be achieved with: Enum.reduce(Stream.zip(enums), acc, reducer) But `zip_reduce/3` exists for convenience purposes. ### Examples - Enum.zip_reduce/3 (function) iex> enums = [[1, 1], [2, 2], [3, 3]] ...> Enum.zip_reduce(enums, [], fn elements, acc -> ...> [List.to_tuple(elements) | acc] ...> end) [{1, 2, 3}, {1, 2, 3}] iex> enums = [[1, 2], [a: 3, b: 4], [5, 6]] ...> Enum.zip_reduce(enums, [], fn elements, acc -> ...> [List.to_tuple(elements) | acc] ...> end) [{2, {:b, 4}, 6}, {1, {:a, 3}, 5}] ### Enum.zip_reduce/4 (function) Reduces over two enumerables halting as soon as either enumerable is empty. In practice, the behavior provided by this function can be achieved with: Enum.reduce(Stream.zip(left, right), acc, reducer) But `zip_reduce/4` exists for convenience purposes. ### Examples - Enum.zip_reduce/4 (function) iex> Enum.zip_reduce([1, 2], [3, 4], 0, fn x, y, acc -> x + y + acc end) 10 iex> Enum.zip_reduce([1, 2], [3, 4], [], fn x, y, acc -> [x + y | acc] end) [6, 4] ### Enum.zip_with/2 (function) Zips corresponding elements from a finite collection of enumerables into list, transforming them with the `zip_fun` function as it goes. The first element from each of the enums in `enumerables` will be put into a list which is then passed to the one-arity `zip_fun` function. Then, the second elements from each of the enums are put into a list and passed to `zip_fun`, and so on until any one of the enums in `enumerables` runs out of elements. Returns a list with all the results of calling `zip_fun`. ### Examples - Enum.zip_with/2 (function) iex> Enum.zip_with([[1, 2], [3, 4], [5, 6]], fn [x, y, z] -> x + y + z end) [9, 12] iex> Enum.zip_with([[1, 2], [3, 4]], fn [x, y] -> x + y end) [4, 6] ### Enum.zip_with/3 (function) Zips corresponding elements from two enumerables into a list, transforming them with the `zip_fun` function as it goes. The corresponding elements from each collection are passed to the provided two-arity `zip_fun` function in turn. Returns a list that contains the result of calling `zip_fun` for each pair of elements. The zipping finishes as soon as either enumerable runs out of elements. ### Zipping Maps - Enum.zip_with/3 (function) It's important to remember that zipping inherently relies on order. If you zip two lists you get the element at the index from each list in turn. If we zip two maps together it's tempting to think that you will get the given key in the left map and the matching key in the right map, but there is no such guarantee because map keys are not ordered! Consider the following: left = %{:a => 1, 1 => 3} right = %{:a => 1, :b => :c} Enum.zip(left, right) # [{{1, 3}, {:a, 1}}, {{:a, 1}, {:b, :c}}] As you can see `:a` does not get paired with `:a`. If this is what you want, you should use `Map.merge/3`. ### Examples - Enum.zip_with/3 (function) iex> Enum.zip_with([1, 2], [3, 4], fn x, y -> x + y end) [4, 6] iex> Enum.zip_with([1, 2], [3, 4, 5, 6], fn x, y -> x + y end) [4, 6] iex> Enum.zip_with([1, 2, 5, 6], [3, 4], fn x, y -> x + y end) [4, 6] ### Enum.acc/0 (type) ### Enum.default/0 (type) ### Enum.element/0 (type) ### Enum.index/0 (type) Zero-based index. It can also be a negative integer. ### Enum.t/0 (type) ### Keyword (module) A keyword list is a list that consists exclusively of two-element tuples. The first element of these tuples is known as the *key*, and it must be an atom. The second element, known as the *value*, can be any term. Keywords are mostly used to work with optional values. For a general introduction to keywords and how they compare with maps, see our [Keyword and Maps](keywords-and-maps.md) guide. ### Examples - Keyword (module) For example, the following is a keyword list: [{:exit_on_close, true}, {:active, :once}, {:packet_size, 1024}] Elixir provides a special and more concise syntax for keyword lists: [exit_on_close: true, active: :once, packet_size: 1024] The two syntaxes return the exact same value. A *key* can be any atom, consisting of Unicode letters, numbers, an underscore or the `@` sign. If the *key* should have any other characters, such as spaces, you can wrap it in quotes: iex> ["exit on close": true] ["exit on close": true] Wrapping an atom in quotes does not make it a string. Keyword list *keys* are always atoms. Quotes should only be used when necessary or Elixir will issue a warning. ### Duplicate keys and ordering - Keyword (module) A keyword may have duplicate keys so it is not strictly a key-value data type. However, most of the functions in this module work on a key-value structure and behave similar to the functions you would find in the `Map` module. For example, `Keyword.get/3` will get the first entry matching the given key, regardless if duplicate entries exist. Similarly, `Keyword.put/3` and `Keyword.delete/2` ensure all duplicate entries for a given key are removed when invoked. Note, however, that keyword list operations need to traverse the whole list in order to find keys, so these operations are slower than their map counterparts. A handful of functions exist to handle duplicate keys, for example, `get_values/2` returns all values for a given key and `delete_first/2` deletes just the first entry of the existing ones. Even though lists preserve the existing order, the functions in `Keyword` do not guarantee any ordering. For example, if you invoke `Keyword.put(opts, new_key, new_value)`, there is no guarantee for where `new_key` will be added to (the front, the end or anywhere else). Given ordering is not guaranteed, it is not recommended to pattern match on keyword lists either. For example, a function such as: def my_function([some_key: value, another_key: another_value]) will match my_function([some_key: :foo, another_key: :bar]) but it won't match my_function([another_key: :bar, some_key: :foo]) Most of the functions in this module work in linear time. This means that the time it takes to perform an operation grows at the same rate as the length of the list. ### Call syntax - Keyword (module) When keyword lists are passed as the last argument to a function, the square brackets around the keyword list can be omitted. For example, the keyword list syntax: String.split("1-0", "-", [trim: true, parts: 2]) can be written without the enclosing brackets whenever it is the last argument of a function call: String.split("1-0", "-", trim: true, parts: 2) Since tuples, lists and maps are treated similarly to function arguments in Elixir syntax, this property is also available to them: iex> {1, 2, foo: :bar} {1, 2, [{:foo, :bar}]} iex> [1, 2, foo: :bar] [1, 2, {:foo, :bar}] iex> %{1 => 2, foo: :bar} %{1 => 2, :foo => :bar} ### Keyword.delete/2 (function) Deletes the entries in the keyword list under a specific `key`. If the `key` does not exist, it returns the keyword list unchanged. Use `delete_first/2` to delete just the first entry in case of duplicate keys. ### Examples - Keyword.delete/2 (function) iex> Keyword.delete([a: 1, b: 2], :a) [b: 2] iex> Keyword.delete([a: 1, b: 2, a: 3], :a) [b: 2] iex> Keyword.delete([b: 2], :a) [b: 2] ### Keyword.delete_first/2 (function) Deletes the first entry in the keyword list under a specific `key`. If the `key` does not exist, it returns the keyword list unchanged. ### Examples - Keyword.delete_first/2 (function) iex> Keyword.delete_first([a: 1, b: 2, a: 3], :a) [b: 2, a: 3] iex> Keyword.delete_first([b: 2], :a) [b: 2] ### Keyword.drop/2 (function) Drops the given `keys` from the keyword list. Removes duplicate keys from the new keyword list. ### Examples - Keyword.drop/2 (function) iex> Keyword.drop([a: 1, a: 2], [:a]) [] iex> Keyword.drop([a: 1, b: 2, c: 3], [:b, :d]) [a: 1, c: 3] iex> Keyword.drop([a: 1, b: 2, b: 3, c: 3, a: 5], [:b, :d]) [a: 1, c: 3, a: 5] ### Keyword.equal?/2 (function) Checks if two keywords are equal. Considers two keywords to be equal if they contain the same keys and those keys contain the same values. ### Examples - Keyword.equal?/2 (function) iex> Keyword.equal?([a: 1, b: 2], [b: 2, a: 1]) true iex> Keyword.equal?([a: 1, b: 2], [b: 1, a: 2]) false iex> Keyword.equal?([a: 1, b: 2, a: 3], [b: 2, a: 3, a: 1]) true Comparison between values is done with `===/3`, which means integers are not equivalent to floats: iex> Keyword.equal?([a: 1.0], [a: 1]) false ### Keyword.fetch/2 (function) Fetches the value for a specific `key` and returns it in a tuple. If the `key` does not exist, it returns `:error`. ### Examples - Keyword.fetch/2 (function) iex> Keyword.fetch([a: 1], :a) {:ok, 1} iex> Keyword.fetch([a: 1], :b) :error ### Keyword.fetch!/2 (function) Fetches the value for specific `key`. If the `key` does not exist, it raises a `KeyError`. ### Examples - Keyword.fetch!/2 (function) iex> Keyword.fetch!([a: 1], :a) 1 iex> Keyword.fetch!([a: 1], :b) ** (KeyError) key :b not found in: [a: 1] ### Keyword.filter/2 (function) Returns a keyword list containing only the entries from `keywords` for which the function `fun` returns a truthy value. See also `reject/2` which discards all entries where the function returns a truthy value. ### Examples - Keyword.filter/2 (function) iex> Keyword.filter([one: 1, two: 2, three: 3], fn {_key, val} -> rem(val, 2) == 1 end) [one: 1, three: 3] ### Keyword.from_keys/2 (function) Builds a keyword from the given `keys` and the fixed `value`. ### Examples - Keyword.from_keys/2 (function) iex> Keyword.from_keys([:foo, :bar, :baz], :atom) [foo: :atom, bar: :atom, baz: :atom] iex> Keyword.from_keys([], :atom) [] ### Keyword.get/3 (function) Gets the value under the given `key`. Returns the default value if `key` does not exist (`nil` if no default value is provided). If duplicate entries exist, it returns the first one. Use `get_values/2` to retrieve all entries. ### Examples - Keyword.get/3 (function) iex> Keyword.get([], :a) nil iex> Keyword.get([a: 1], :a) 1 iex> Keyword.get([a: 1], :b) nil iex> Keyword.get([a: 1], :b, 3) 3 With duplicate keys: iex> Keyword.get([a: 1, a: 2], :a, 3) 1 iex> Keyword.get([a: 1, a: 2], :b, 3) 3 ### Keyword.get_and_update/3 (function) Gets the value from `key` and updates it, all in one pass. The `fun` argument receives the value of `key` (or `nil` if `key` is not present) and must return a two-element tuple: the current value (the retrieved value, which can be operated on before being returned) and the new value to be stored under `key`. The `fun` may also return `:pop`, implying the current value shall be removed from the keyword list and returned. Returns a tuple that contains the current value returned by `fun` and a new keyword list with the updated value under `key`. ### Examples - Keyword.get_and_update/3 (function) iex> Keyword.get_and_update([a: 1], :a, fn current_value -> ...> {current_value, "new value!"} ...> end) {1, [a: "new value!"]} iex> Keyword.get_and_update([a: 1], :b, fn current_value -> ...> {current_value, "new value!"} ...> end) {nil, [b: "new value!", a: 1]} iex> Keyword.get_and_update([a: 2], :a, fn number -> ...> {2 * number, 3 * number} ...> end) {4, [a: 6]} iex> Keyword.get_and_update([a: 1], :a, fn _ -> :pop end) {1, []} iex> Keyword.get_and_update([a: 1], :b, fn _ -> :pop end) {nil, [a: 1]} ### Keyword.get_and_update!/3 (function) Gets the value under `key` and updates it. Raises if there is no `key`. The `fun` argument receives the value under `key` and must return a two-element tuple: the current value (the retrieved value, which can be operated on before being returned) and the new value to be stored under `key`. Returns a tuple that contains the current value returned by `fun` and a new keyword list with the updated value under `key`. ### Examples - Keyword.get_and_update!/3 (function) iex> Keyword.get_and_update!([a: 1], :a, fn current_value -> ...> {current_value, "new value!"} ...> end) {1, [a: "new value!"]} iex> Keyword.get_and_update!([a: 1], :b, fn current_value -> ...> {current_value, "new value!"} ...> end) ** (KeyError) key :b not found in: [a: 1] iex> Keyword.get_and_update!([a: 1], :a, fn _ -> ...> :pop ...> end) {1, []} ### Keyword.get_lazy/3 (function) Gets the value under the given `key`. If `key` does not exist, lazily evaluates `fun` and returns its result. This is useful if the default value is very expensive to calculate or generally difficult to set up and tear down again. If duplicate entries exist, it returns the first one. Use `get_values/2` to retrieve all entries. ### Examples - Keyword.get_lazy/3 (function) iex> keyword = [a: 1] iex> fun = fn -> ...> # some expensive operation here ...> 13 ...> end iex> Keyword.get_lazy(keyword, :a, fun) 1 iex> Keyword.get_lazy(keyword, :b, fun) 13 ### Keyword.get_values/2 (function) Gets all values under a specific `key`. ### Examples - Keyword.get_values/2 (function) iex> Keyword.get_values([], :a) [] iex> Keyword.get_values([a: 1], :a) [1] iex> Keyword.get_values([a: 1, a: 2], :a) [1, 2] ### Keyword.has_key?/2 (function) Returns whether a given `key` exists in the given `keywords`. ### Examples - Keyword.has_key?/2 (function) iex> Keyword.has_key?([a: 1], :a) true iex> Keyword.has_key?([a: 1], :b) false ### Keyword.intersect/3 (function) Intersects two keyword lists, returning a keyword with the common keys. By default, it returns the values of the intersected keys in `keyword2`. The keys are returned in the order found in `keyword1`. ### Examples - Keyword.intersect/3 (function) iex> Keyword.intersect([a: 1, b: 2], [b: "b", c: "c"]) [b: "b"] iex> Keyword.intersect([a: 1, b: 2], [b: 2, c: 3], fn _k, v1, v2 -> ...> v1 + v2 ...> end) [b: 4] ### Keyword.keys/1 (function) Returns all keys from the keyword list. Keeps duplicate keys in the resulting list of keys. ### Examples - Keyword.keys/1 (function) iex> Keyword.keys(a: 1, b: 2) [:a, :b] iex> Keyword.keys(a: 1, b: 2, a: 3) [:a, :b, :a] iex> Keyword.keys([{:a, 1}, {"b", 2}, {:c, 3}]) ** (ArgumentError) expected a keyword list, but an entry in the list is not a two-element tuple with an atom as its first element, got: {"b", 2} ### Keyword.keyword?/1 (function) Returns `true` if `term` is a keyword list, otherwise `false`. When `term` is a list it is traversed to the end. ### Examples - Keyword.keyword?/1 (function) iex> Keyword.keyword?([]) true iex> Keyword.keyword?(a: 1) true iex> Keyword.keyword?([{Foo, 1}]) true iex> Keyword.keyword?([{}]) false iex> Keyword.keyword?([:key]) false iex> Keyword.keyword?(%{}) false ### Keyword.merge/2 (function) Merges two keyword lists into one. Adds all keys, including duplicate keys, given in `keywords2` to `keywords1`, overriding any existing ones. There are no guarantees about the order of the keys in the returned keyword. ### Examples - Keyword.merge/2 (function) iex> Keyword.merge([a: 1, b: 2], [a: 3, d: 4]) [b: 2, a: 3, d: 4] iex> Keyword.merge([a: 1, b: 2], [a: 3, d: 4, a: 5]) [b: 2, a: 3, d: 4, a: 5] iex> Keyword.merge([a: 1], [2, 3]) ** (ArgumentError) expected a keyword list as the second argument, got: [2, 3] ### Keyword.merge/3 (function) Merges two keyword lists into one. Adds all keys, including duplicate keys, given in `keywords2` to `keywords1`. Invokes the given function to solve conflicts. If `keywords2` has duplicate keys, it invokes the given function for each matching pair in `keywords1`. There are no guarantees about the order of the keys in the returned keyword. ### Examples - Keyword.merge/3 (function) iex> Keyword.merge([a: 1, b: 2], [a: 3, d: 4], fn _k, v1, v2 -> ...> v1 + v2 ...> end) [b: 2, a: 4, d: 4] iex> Keyword.merge([a: 1, b: 2], [a: 3, d: 4, a: 5], fn :a, v1, v2 -> ...> v1 + v2 ...> end) [b: 2, a: 4, d: 4, a: 5] iex> Keyword.merge([a: 1, b: 2, a: 3], [a: 3, d: 4, a: 5], fn :a, v1, v2 -> ...> v1 + v2 ...> end) [b: 2, a: 4, d: 4, a: 8] iex> Keyword.merge([a: 1, b: 2], [:a, :b], fn :a, v1, v2 -> ...> v1 + v2 ...> end) ** (ArgumentError) expected a keyword list as the second argument, got: [:a, :b] ### Keyword.new/0 (function) Returns an empty keyword list, i.e. an empty list. ### Examples - Keyword.new/0 (function) iex> Keyword.new() [] ### Keyword.new/1 (function) Creates a keyword list from an enumerable. Removes duplicate entries and the last one prevails. Unlike `Enum.into(enumerable, [])`, `Keyword.new(enumerable)` guarantees the keys are unique. ### Examples - Keyword.new/1 (function) iex> Keyword.new([{:b, 1}, {:a, 2}]) [b: 1, a: 2] iex> Keyword.new([{:a, 1}, {:a, 2}, {:a, 3}]) [a: 3] ### Keyword.new/2 (function) Creates a keyword list from an enumerable via the transformation function. Removes duplicate entries and the last one prevails. Unlike `Enum.into(enumerable, [], fun)`, `Keyword.new(enumerable, fun)` guarantees the keys are unique. ### Examples - Keyword.new/2 (function) iex> Keyword.new([:a, :b], fn x -> {x, x} end) [a: :a, b: :b] ### Keyword.pop/3 (function) Returns the first value for `key` and removes all associated entries in the keyword list. It returns a tuple where the first element is the first value for `key` and the second element is a keyword list with all entries associated with `key` removed. If the `key` is not present in the keyword list, it returns `{default, keyword_list}`. If you don't want to remove all the entries associated with `key` use `pop_first/3` instead, which will remove only the first entry. ### Examples - Keyword.pop/3 (function) iex> Keyword.pop([a: 1], :a) {1, []} iex> Keyword.pop([a: 1], :b) {nil, [a: 1]} iex> Keyword.pop([a: 1], :b, 3) {3, [a: 1]} iex> Keyword.pop([a: 1, a: 2], :a) {1, []} ### Keyword.pop!/2 (function) Returns the first value for `key` and removes all associated entries in the keyword list, raising if `key` is not present. This function behaves like `pop/3`, but raises in case the `key` is not present in the given `keywords`. ### Examples - Keyword.pop!/2 (function) iex> Keyword.pop!([a: 1], :a) {1, []} iex> Keyword.pop!([a: 1, a: 2], :a) {1, []} iex> Keyword.pop!([a: 1], :b) ** (KeyError) key :b not found in: [a: 1] ### Keyword.pop_first/3 (function) Returns and removes the first value associated with `key` in the keyword list. Keeps duplicate keys in the resulting keyword list. ### Examples - Keyword.pop_first/3 (function) iex> Keyword.pop_first([a: 1], :a) {1, []} iex> Keyword.pop_first([a: 1], :b) {nil, [a: 1]} iex> Keyword.pop_first([a: 1], :b, 3) {3, [a: 1]} iex> Keyword.pop_first([a: 1, a: 2], :a) {1, [a: 2]} ### Keyword.pop_lazy/3 (function) Lazily returns and removes all values associated with `key` in the keyword list. This is useful if the default value is very expensive to calculate or generally difficult to set up and tear down again. Removes all duplicate keys. See `pop_first/3` for removing only the first entry. ### Examples - Keyword.pop_lazy/3 (function) iex> keyword = [a: 1] iex> fun = fn -> ...> # some expensive operation here ...> 13 ...> end iex> Keyword.pop_lazy(keyword, :a, fun) {1, []} iex> Keyword.pop_lazy(keyword, :b, fun) {13, [a: 1]} ### Keyword.pop_values/2 (function) Returns all values for `key` and removes all associated entries in the keyword list. It returns a tuple where the first element is a list of values for `key` and the second element is a keyword list with all entries associated with `key` removed. If the `key` is not present in the keyword list, it returns `{[], keyword_list}`. If you don't want to remove all the entries associated with `key` use `pop_first/3` instead, which will remove only the first entry. ### Examples - Keyword.pop_values/2 (function) iex> Keyword.pop_values([a: 1], :a) {[1], []} iex> Keyword.pop_values([a: 1], :b) {[], [a: 1]} iex> Keyword.pop_values([a: 1, a: 2], :a) {[1, 2], []} ### Keyword.put/3 (function) Puts the given `value` under the specified `key`. If a value under `key` already exists, it overrides the value and removes all duplicate entries. ### Examples - Keyword.put/3 (function) iex> Keyword.put([a: 1], :b, 2) [b: 2, a: 1] iex> Keyword.put([a: 1, b: 2], :a, 3) [a: 3, b: 2] iex> Keyword.put([a: 1, b: 2, a: 4], :a, 3) [a: 3, b: 2] ### Keyword.put_new/3 (function) Puts the given `value` under `key`, unless the entry `key` already exists. ### Examples - Keyword.put_new/3 (function) iex> Keyword.put_new([a: 1], :b, 2) [b: 2, a: 1] iex> Keyword.put_new([a: 1, b: 2], :a, 3) [a: 1, b: 2] ### Keyword.put_new_lazy/3 (function) Evaluates `fun` and puts the result under `key` in keyword list unless `key` is already present. This is useful if the value is very expensive to calculate or generally difficult to set up and tear down again. ### Examples - Keyword.put_new_lazy/3 (function) iex> keyword = [a: 1] iex> fun = fn -> ...> # some expensive operation here ...> 13 ...> end iex> Keyword.put_new_lazy(keyword, :a, fun) [a: 1] iex> Keyword.put_new_lazy(keyword, :b, fun) [b: 13, a: 1] ### Keyword.reject/2 (function) Returns a keyword list excluding the entries from `keywords` for which the function `fun` returns a truthy value. See also `filter/2`. ### Examples - Keyword.reject/2 (function) iex> Keyword.reject([one: 1, two: 2, three: 3], fn {_key, val} -> rem(val, 2) == 1 end) [two: 2] ### Keyword.replace/3 (function) Puts a value under `key` only if the `key` already exists in `keywords`. In case a key exists multiple times in the keyword list, it removes later occurrences. ### Examples - Keyword.replace/3 (function) iex> Keyword.replace([a: 1, b: 2, a: 4], :a, 3) [a: 3, b: 2] iex> Keyword.replace([a: 1], :b, 2) [a: 1] ### Keyword.replace!/3 (function) Puts a value under `key` only if the `key` already exists in `keywords`. If `key` is not present in `keywords`, it raises a `KeyError`. ### Examples - Keyword.replace!/3 (function) iex> Keyword.replace!([a: 1, b: 2, a: 3], :a, :new) [a: :new, b: 2] iex> Keyword.replace!([a: 1, b: 2, c: 3, b: 4], :b, :new) [a: 1, b: :new, c: 3] iex> Keyword.replace!([a: 1], :b, 2) ** (KeyError) key :b not found in: [a: 1] ### Keyword.replace_lazy/3 (function) Replaces the value under `key` using the given function only if `key` already exists in `keywords`. In comparison to `replace/3`, this can be useful when it's expensive to calculate the value. If `key` does not exist, the original keyword list is returned unchanged. ### Examples - Keyword.replace_lazy/3 (function) iex> Keyword.replace_lazy([a: 1, b: 2], :a, fn v -> v * 4 end) [a: 4, b: 2] iex> Keyword.replace_lazy([a: 2, b: 2, a: 1], :a, fn v -> v * 4 end) [a: 8, b: 2] iex> Keyword.replace_lazy([a: 1, b: 2], :c, fn v -> v * 4 end) [a: 1, b: 2] ### Keyword.split/2 (function) Takes all entries corresponding to the given `keys` and extracts them into a separate keyword list. Returns a tuple with the new list and the old list with removed keys. Ignores keys for which there are no entries in the keyword list. Entries with duplicate keys end up in the same keyword list. ### Examples - Keyword.split/2 (function) iex> Keyword.split([a: 1, b: 2, c: 3], [:a, :c, :e]) {[a: 1, c: 3], [b: 2]} iex> Keyword.split([a: 1, b: 2, c: 3, a: 4], [:a, :c, :e]) {[a: 1, c: 3, a: 4], [b: 2]} ### Keyword.split_with/2 (function) Splits the `keywords` into two keyword lists according to the given function `fun`. The provided `fun` receives each `{key, value}` pair in the `keywords` as its only argument. Returns a tuple with the first keyword list containing all the elements in `keywords` for which applying `fun` returned a truthy value, and a second keyword list with all the elements for which applying `fun` returned a falsy value (`false` or `nil`). ### Examples - Keyword.split_with/2 (function) iex> Keyword.split_with([a: 1, b: 2, c: 3], fn {_k, v} -> rem(v, 2) == 0 end) {[b: 2], [a: 1, c: 3]} iex> Keyword.split_with([a: 1, b: 2, c: 3, b: 4], fn {_k, v} -> rem(v, 2) == 0 end) {[b: 2, b: 4], [a: 1, c: 3]} iex> Keyword.split_with([a: 1, b: 2, c: 3, b: 4], fn {k, v} -> k in [:a, :c] and rem(v, 2) == 0 end) {[], [a: 1, b: 2, c: 3, b: 4]} iex> Keyword.split_with([], fn {_k, v} -> rem(v, 2) == 0 end) {[], []} ### Keyword.take/2 (function) Takes all entries corresponding to the given `keys` and returns them as a new keyword list. Preserves duplicate keys in the new keyword list. ### Examples - Keyword.take/2 (function) iex> Keyword.take([a: 1, b: 2, c: 3], [:a, :c, :e]) [a: 1, c: 3] iex> Keyword.take([a: 1, b: 2, c: 3, a: 5], [:a, :c, :e]) [a: 1, c: 3, a: 5] ### Keyword.to_list/1 (function) Returns the keyword list itself. ### Examples - Keyword.to_list/1 (function) iex> Keyword.to_list(a: 1) [a: 1] ### Keyword.update/4 (function) Updates the value under `key` in `keywords` using the given function. If the `key` does not exist, it inserts the given `default` value. Does not pass the `default` value through the update function. Removes all duplicate keys and only updates the first one. ### Examples - Keyword.update/4 (function) iex> Keyword.update([a: 1], :a, 13, fn existing_value -> existing_value * 2 end) [a: 2] iex> Keyword.update([a: 1, a: 2], :a, 13, fn existing_value -> existing_value * 2 end) [a: 2] iex> Keyword.update([a: 1], :b, 11, fn existing_value -> existing_value * 2 end) [a: 1, b: 11] ### Keyword.update!/3 (function) Updates the value under `key` using the given function. Raises `KeyError` if the `key` does not exist. Removes all duplicate keys and only updates the first one. ### Examples - Keyword.update!/3 (function) iex> Keyword.update!([a: 1, b: 2, a: 3], :a, &(&1 * 2)) [a: 2, b: 2] iex> Keyword.update!([a: 1, b: 2, c: 3], :b, &(&1 * 2)) [a: 1, b: 4, c: 3] iex> Keyword.update!([a: 1], :b, &(&1 * 2)) ** (KeyError) key :b not found in: [a: 1] ### Keyword.validate/2 (function) Ensures the given `keyword` has only the keys given in `values`. The second argument must be a list of atoms, specifying a given key, or tuples specifying a key and a default value. If the keyword list has only the given keys, it returns `{:ok, keyword}` with default values applied. Otherwise it returns `{:error, invalid_keys}` with invalid keys. See also: `validate!/2`. ### Examples - Keyword.validate/2 (function) iex> {:ok, result} = Keyword.validate([], [one: 1, two: 2]) iex> Enum.sort(result) [one: 1, two: 2] iex> {:ok, result} = Keyword.validate([two: 3], [one: 1, two: 2]) iex> Enum.sort(result) [one: 1, two: 3] If atoms are given, they are supported as keys but do not provide a default value: iex> {:ok, result} = Keyword.validate([], [:one, two: 2]) iex> Enum.sort(result) [two: 2] iex> {:ok, result} = Keyword.validate([one: 1], [:one, two: 2]) iex> Enum.sort(result) [one: 1, two: 2] Passing unknown keys returns an error: iex> Keyword.validate([three: 3, four: 4], [one: 1, two: 2]) {:error, [:four, :three]} Passing the same key multiple times also errors: iex> Keyword.validate([one: 1, two: 2, one: 1], [:one, :two]) {:error, [:one]} ### Keyword.validate!/2 (function) Similar to `validate/2` but returns the keyword or raises an error. ### Examples - Keyword.validate!/2 (function) iex> Keyword.validate!([], [one: 1, two: 2]) |> Enum.sort() [one: 1, two: 2] iex> Keyword.validate!([two: 3], [one: 1, two: 2]) |> Enum.sort() [one: 1, two: 3] If atoms are given, they are supported as keys but do not provide a default value: iex> Keyword.validate!([], [:one, two: 2]) |> Enum.sort() [two: 2] iex> Keyword.validate!([one: 1], [:one, two: 2]) |> Enum.sort() [one: 1, two: 2] Passing unknown keys raises an error: iex> Keyword.validate!([three: 3], [one: 1, two: 2]) ** (ArgumentError) unknown keys [:three] in [three: 3], the allowed keys are: [:one, :two] Passing the same key multiple times also errors: iex> Keyword.validate!([one: 1, two: 2, one: 1], [:one, :two]) ** (ArgumentError) duplicate keys [:one] in [one: 1, two: 2, one: 1] ### Keyword.values/1 (function) Returns all values from the keyword list. Keeps values from duplicate keys in the resulting list of values. ### Examples - Keyword.values/1 (function) iex> Keyword.values(a: 1, b: 2) [1, 2] iex> Keyword.values(a: 1, b: 2, a: 3) [1, 2, 3] ### Keyword.default/0 (type) ### Keyword.key/0 (type) ### Keyword.t/0 (type) ### Keyword.t/1 (type) ### Keyword.value/0 (type) ### List (module) Linked lists hold zero, one, or more elements in the chosen order. Lists in Elixir are specified between square brackets: iex> [1, "two", 3, :four] [1, "two", 3, :four] Two lists can be concatenated and subtracted using the `++/2` and `--/2` operators: iex> [1, 2, 3] ++ [4, 5, 6] [1, 2, 3, 4, 5, 6] iex> [1, true, 2, false, 3, true] -- [true, false] [1, 2, 3, true] An element can be prepended to a list using `|`: iex> new = 0 iex> list = [1, 2, 3] iex> [new | list] [0, 1, 2, 3] Lists in Elixir are effectively linked lists, which means they are internally represented in pairs containing the head and the tail of a list: iex> [head | tail] = [1, 2, 3] iex> head 1 iex> tail [2, 3] Similarly, we could write the list `[1, 2, 3]` using only such pairs (called cons cells): iex> [1 | [2 | [3 | []]]] [1, 2, 3] Some lists, called improper lists, do not have an empty list as the second element in the last cons cell: iex> [1 | [2 | [3 | 4]]] [1, 2, 3 | 4] Although improper lists are generally avoided, they are used in some special circumstances like iodata and chardata entities (see the `IO` module). Due to their cons cell based representation, prepending an element to a list is always fast (constant time), while appending becomes slower as the list grows in size (linear time): iex> list = [1, 2, 3] iex> [0 | list] # fast [0, 1, 2, 3] iex> list ++ [4] # slow [1, 2, 3, 4] Most of the functions in this module work in linear time. This means that the time it takes to perform an operation grows at the same rate as the length of the list. For example `length/1` and `last/1` will run in linear time because they need to iterate through every element of the list, but `first/1` will run in constant time because it only needs the first element. Lists also implement the `Enumerable` protocol, so many functions to work with lists are found in the `Enum` module. Additionally, the following functions and operators for lists are found in `Kernel`: * `++/2` * `--/2` * `hd/1` * `tl/1` * `in/2` * `length/1` ### Charlists - List (module) If a list is made of non-negative integers, where each integer represents a Unicode code point, the list can also be called a charlist. These integers must: * be within the range `0..0x10FFFF` (`0..1_114_111`); * and be out of the range `0xD800..0xDFFF` (`55_296..57_343`), which is reserved in Unicode for UTF-16 surrogate pairs. Elixir uses the [`~c` sigil](`sigil_c/2`) to define charlists: iex> ~c"héllo" [104, 233, 108, 108, 111] In particular, charlists will be printed back by default with the `~c` sigil if they contain only printable ASCII characters: iex> ~c"abc" ~c"abc" Even though the representation changed, the raw data does remain a list of integers, which can be handled as such: iex> inspect(~c"abc", charlists: :as_list) "[97, 98, 99]" iex> Enum.map(~c"abc", fn num -> 1000 + num end) [1097, 1098, 1099] You can use the `IEx.Helpers.i/1` helper to get a condensed rundown on charlists in IEx when you encounter them, which shows you the type, description and also the raw representation in one single summary. The rationale behind this behavior is to better support Erlang libraries which may return text as charlists instead of Elixir strings. In Erlang, charlists are the default way of handling strings, while in Elixir it's binaries. One example of such functions is `Application.loaded_applications/0`: Application.loaded_applications() #=> [ #=> {:stdlib, ~c"ERTS CXC 138 10", ~c"2.6"}, #=> {:compiler, ~c"ERTS CXC 138 10", ~c"6.0.1"}, #=> {:elixir, ~c"elixir", ~c"1.0.0"}, #=> {:kernel, ~c"ERTS CXC 138 10", ~c"4.1"}, #=> {:logger, ~c"logger", ~c"1.0.0"} #=> ] A list can be checked if it is made of only printable ASCII characters with `ascii_printable?/2`. Improper lists are never deemed as charlists. ### List.ascii_printable?/2 (function) Checks if `list` is a charlist made only of printable ASCII characters. Takes an optional `limit` as a second argument. `ascii_printable?/2` only checks the printability of the list up to the `limit`. A printable charlist in Elixir contains only the printable characters in the standard seven-bit ASCII character encoding, which are characters ranging from 32 to 126 in decimal notation, plus the following control characters: * `?\a` - Bell * `?\b` - Backspace * `?\t` - Horizontal tab * `?\n` - Line feed * `?\v` - Vertical tab * `?\f` - Form feed * `?\r` - Carriage return * `?\e` - Escape For more information read the [Character groups](https://en.wikipedia.org/wiki/ASCII#Character_groups) section in the Wikipedia article of the [ASCII](https://en.wikipedia.org/wiki/ASCII) standard. ### Examples - List.ascii_printable?/2 (function) iex> List.ascii_printable?(~c"abc") true iex> List.ascii_printable?(~c"abc" ++ [0]) false iex> List.ascii_printable?(~c"abc" ++ [0], 2) true Improper lists are not printable, even if made only of ASCII characters: iex> List.ascii_printable?(~c"abc" ++ ?d) false ### List.delete/2 (function) Deletes the given `element` from the `list`. Returns a new list without the element. If the `element` occurs more than once in the `list`, just the first occurrence is removed. ### Examples - List.delete/2 (function) iex> List.delete([:a, :b, :c], :a) [:b, :c] iex> List.delete([:a, :b, :c], :d) [:a, :b, :c] iex> List.delete([:a, :b, :b, :c], :b) [:a, :b, :c] iex> List.delete([], :b) [] ### List.delete_at/2 (function) Produces a new list by removing the value at the specified `index`. Negative indices indicate an offset from the end of the `list`. If `index` is out of bounds, the original `list` is returned. ### Examples - List.delete_at/2 (function) iex> List.delete_at([1, 2, 3], 0) [2, 3] iex> List.delete_at([1, 2, 3], 10) [1, 2, 3] iex> List.delete_at([1, 2, 3], -1) [1, 2] ### List.duplicate/2 (function) Duplicates the given element `n` times in a list. `n` is an integer greater than or equal to `0`. If `n` is `0`, an empty list is returned. ### Examples - List.duplicate/2 (function) iex> List.duplicate("hello", 0) [] iex> List.duplicate("hi", 1) ["hi"] iex> List.duplicate("bye", 2) ["bye", "bye"] iex> List.duplicate([1, 2], 3) [[1, 2], [1, 2], [1, 2]] ### List.ends_with?/2 (function) Returns `true` if `list` ends with the given `suffix` list, otherwise returns `false`. If `suffix` is an empty list, it returns `true`. ### Examples - List.ends_with?/2 (function) iex> List.ends_with?([1, 2, 3], [2, 3]) true iex> List.ends_with?([1, 2], [1, 2, 3]) false iex> List.ends_with?([:alpha], []) true iex> List.ends_with?([], [:alpha]) false ### List.first/2 (function) Returns the first element in `list` or `default` if `list` is empty. `first/2` has been introduced in Elixir v1.12.0, while `first/1` has been available since v1.0.0. ### Examples - List.first/2 (function) iex> List.first([]) nil iex> List.first([], 1) 1 iex> List.first([1]) 1 iex> List.first([1, 2, 3]) 1 ### List.flatten/1 (function) Flattens the given `list` of nested lists. Empty list elements are discarded. ### Examples - List.flatten/1 (function) iex> List.flatten([1, [[2], 3]]) [1, 2, 3] iex> List.flatten([[], [[], []]]) [] ### List.flatten/2 (function) Flattens the given `list` of nested lists. The list `tail` will be added at the end of the flattened list. Empty list elements from `list` are discarded, but not the ones from `tail`. ### Examples - List.flatten/2 (function) iex> List.flatten([1, [[2], 3]], [4, 5]) [1, 2, 3, 4, 5] iex> List.flatten([1, [], 2], [3, [], 4]) [1, 2, 3, [], 4] ### List.foldl/3 (function) Folds (reduces) the given list from the left with a function. Requires an accumulator, which can be any value. ### Examples - List.foldl/3 (function) iex> List.foldl([5, 5], 10, fn x, acc -> x + acc end) 20 iex> List.foldl([1, 2, 3, 4], 0, fn x, acc -> x - acc end) 2 iex> List.foldl([1, 2, 3], {0, 0}, fn x, {a1, a2} -> {a1 + x, a2 - x} end) {6, -6} ### List.foldr/3 (function) Folds (reduces) the given list from the right with a function. Requires an accumulator, which can be any value. ### Examples - List.foldr/3 (function) iex> List.foldr([1, 2, 3, 4], 0, fn x, acc -> x - acc end) -2 iex> List.foldr([1, 2, 3, 4], %{sum: 0, product: 1}, fn x, %{sum: a1, product: a2} -> %{sum: a1 + x, product: a2 * x} end) %{product: 24, sum: 10} ### List.improper?/1 (function) Returns `true` if `list` is an improper list. Otherwise returns `false`. ### Examples - List.improper?/1 (function) iex> List.improper?([1, 2 | 3]) true iex> List.improper?([1, 2, 3]) false ### List.insert_at/3 (function) Returns a list with `value` inserted at the specified `index`. Note that `index` is capped at the list length. Negative indices indicate an offset from the end of the `list`. ### Examples - List.insert_at/3 (function) iex> List.insert_at([1, 2, 3, 4], 2, 0) [1, 2, 0, 3, 4] iex> List.insert_at([1, 2, 3], 10, 0) [1, 2, 3, 0] iex> List.insert_at([1, 2, 3], -1, 0) [1, 2, 3, 0] iex> List.insert_at([1, 2, 3], -10, 0) [0, 1, 2, 3] ### List.keydelete/3 (function) Receives a `list` of tuples and deletes the first tuple where the element at `position` matches the given `key`. Returns the new list. ### Examples - List.keydelete/3 (function) iex> List.keydelete([a: 1, b: 2], :a, 0) [b: 2] iex> List.keydelete([a: 1, b: 2], 2, 1) [a: 1] iex> List.keydelete([a: 1, b: 2], :c, 0) [a: 1, b: 2] This function works for any list of tuples: iex> List.keydelete([{22, "SSH"}, {80, "HTTP"}], 80, 0) [{22, "SSH"}] ### List.keyfind/4 (function) Receives a list of tuples and returns the first tuple where the element at `position` in the tuple matches the given `key`. If no matching tuple is found, `default` is returned. ### Examples - List.keyfind/4 (function) iex> List.keyfind([a: 1, b: 2], :a, 0) {:a, 1} iex> List.keyfind([a: 1, b: 2], 2, 1) {:b, 2} iex> List.keyfind([a: 1, b: 2], :c, 0) nil This function works for any list of tuples: iex> List.keyfind([{22, "SSH"}, {80, "HTTP"}], 22, 0) {22, "SSH"} ### List.keyfind!/3 (function) Receives a list of tuples and returns the first tuple where the element at `position` in the tuple matches the given `key`. If no matching tuple is found, an error is raised. ### Examples - List.keyfind!/3 (function) iex> List.keyfind!([a: 1, b: 2], :a, 0) {:a, 1} iex> List.keyfind!([a: 1, b: 2], 2, 1) {:b, 2} iex> List.keyfind!([a: 1, b: 2], :c, 0) ** (KeyError) key :c at position 0 not found in: [a: 1, b: 2] This function works for any list of tuples: iex> List.keyfind!([{22, "SSH"}, {80, "HTTP"}], 22, 0) {22, "SSH"} ### List.keymember?/3 (function) Receives a list of tuples and returns `true` if there is a tuple where the element at `position` in the tuple matches the given `key`. ### Examples - List.keymember?/3 (function) iex> List.keymember?([a: 1, b: 2], :a, 0) true iex> List.keymember?([a: 1, b: 2], 2, 1) true iex> List.keymember?([a: 1, b: 2], :c, 0) false This function works for any list of tuples: iex> List.keymember?([{22, "SSH"}, {80, "HTTP"}], 22, 0) true ### List.keyreplace/4 (function) Receives a list of tuples and if the identified element by `key` at `position` exists, it is replaced with `new_tuple`. ### Examples - List.keyreplace/4 (function) iex> List.keyreplace([a: 1, b: 2], :a, 0, {:a, 3}) [a: 3, b: 2] iex> List.keyreplace([a: 1, b: 2], :a, 1, {:a, 3}) [a: 1, b: 2] This function works for any list of tuples: iex> List.keyreplace([{22, "SSH"}, {80, "HTTP"}], 22, 0, {22, "Secure Shell"}) [{22, "Secure Shell"}, {80, "HTTP"}] ### List.keysort/3 (function) Receives a list of tuples and sorts the elements at `position` of the tuples. The sort is stable. A `sorter` argument is available since Elixir v1.14.0. Similar to `Enum.sort/2`, the sorter can be an anonymous function, the atoms `:asc` or `:desc`, or module that implements a compare function. ### Examples - List.keysort/3 (function) iex> List.keysort([a: 5, b: 1, c: 3], 1) [b: 1, c: 3, a: 5] iex> List.keysort([a: 5, c: 1, b: 3], 0) [a: 5, b: 3, c: 1] To sort in descending order: iex> List.keysort([a: 5, c: 1, b: 3], 0, :desc) [c: 1, b: 3, a: 5] As in `Enum.sort/2`, avoid using the default sorting function to sort structs, as by default it performs structural comparison instead of a semantic one. In such cases, you shall pass a sorting function as third element or any module that implements a `compare/2` function. For example, if you have tuples with user names and their birthday, and you want to sort on their birthday, in both ascending and descending order, you should do: iex> users = [ ...> {"Ellis", ~D[1943-05-11]}, ...> {"Lovelace", ~D[1815-12-10]}, ...> {"Turing", ~D[1912-06-23]} ...> ] iex> List.keysort(users, 1, Date) [ {"Lovelace", ~D[1815-12-10]}, {"Turing", ~D[1912-06-23]}, {"Ellis", ~D[1943-05-11]} ] iex> List.keysort(users, 1, {:desc, Date}) [ {"Ellis", ~D[1943-05-11]}, {"Turing", ~D[1912-06-23]}, {"Lovelace", ~D[1815-12-10]} ] ### List.keystore/4 (function) Receives a `list` of tuples and replaces the element identified by `key` at `position` with `new_tuple`. If the element does not exist, it is added to the end of the `list`. ### Examples - List.keystore/4 (function) iex> List.keystore([a: 1, b: 2], :a, 0, {:a, 3}) [a: 3, b: 2] iex> List.keystore([a: 1, b: 2], :c, 0, {:c, 3}) [a: 1, b: 2, c: 3] This function works for any list of tuples: iex> List.keystore([{22, "SSH"}], 80, 0, {80, "HTTP"}) [{22, "SSH"}, {80, "HTTP"}] ### List.keytake/3 (function) Receives a `list` of tuples and returns the first tuple where the element at `position` in the tuple matches the given `key`, as well as the `list` without found tuple. If such a tuple is not found, `nil` will be returned. ### Examples - List.keytake/3 (function) iex> List.keytake([a: 1, b: 2], :a, 0) {{:a, 1}, [b: 2]} iex> List.keytake([a: 1, b: 2], 2, 1) {{:b, 2}, [a: 1]} iex> List.keytake([a: 1, b: 2], :c, 0) nil This function works for any list of tuples: iex> List.keytake([{22, "SSH"}, {80, "HTTP"}], 80, 0) {{80, "HTTP"}, [{22, "SSH"}]} ### List.last/2 (function) Returns the last element in `list` or `default` if `list` is empty. `last/2` has been introduced in Elixir v1.12.0, while `last/1` has been available since v1.0.0. ### Examples - List.last/2 (function) iex> List.last([]) nil iex> List.last([], 1) 1 iex> List.last([1]) 1 iex> List.last([1, 2, 3]) 3 ### List.myers_difference/2 (function) Returns a keyword list that represents an *edit script*. The algorithm is outlined in the "An O(ND) Difference Algorithm and Its Variations" paper by E. Myers. An *edit script* is a keyword list. Each key describes the "editing action" to take in order to bring `list1` closer to being equal to `list2`; a key can be `:eq`, `:ins`, or `:del`. Each value is a sublist of either `list1` or `list2` that should be inserted (if the corresponding key is `:ins`), deleted (if the corresponding key is `:del`), or left alone (if the corresponding key is `:eq`) in `list1` in order to be closer to `list2`. See `myers_difference/3` if you want to handle nesting in the diff scripts. ### Examples - List.myers_difference/2 (function) iex> List.myers_difference([1, 4, 2, 3], [1, 2, 3, 4]) [eq: [1], del: [4], eq: [2, 3], ins: [4]] ### List.myers_difference/3 (function) Returns a keyword list that represents an *edit script* with nested diffs. This is an extension of `myers_difference/2` where a `diff_script` function can be given in case it is desired to compute nested differences. The function may return a list with the inner edit script or `nil` in case there is no such script. The returned inner edit script will be under the `:diff` key. ### Examples - List.myers_difference/3 (function) iex> List.myers_difference(["a", "db", "c"], ["a", "bc"], &String.myers_difference/2) [eq: ["a"], diff: [del: "d", eq: "b", ins: "c"], del: ["c"]] ### List.pop_at/3 (function) Returns and removes the value at the specified `index` in the `list`. Negative indices indicate an offset from the end of the `list`. If `index` is out of bounds, the original `list` is returned. ### Examples - List.pop_at/3 (function) iex> List.pop_at([1, 2, 3], 0) {1, [2, 3]} iex> List.pop_at([1, 2, 3], 5) {nil, [1, 2, 3]} iex> List.pop_at([1, 2, 3], 5, 10) {10, [1, 2, 3]} iex> List.pop_at([1, 2, 3], -1) {3, [1, 2]} ### List.replace_at/3 (function) Returns a list with a replaced value at the specified `index`. Negative indices indicate an offset from the end of the `list`. If `index` is out of bounds, the original `list` is returned. ### Examples - List.replace_at/3 (function) iex> List.replace_at([1, 2, 3], 0, 0) [0, 2, 3] iex> List.replace_at([1, 2, 3], 10, 0) [1, 2, 3] iex> List.replace_at([1, 2, 3], -1, 0) [1, 2, 0] iex> List.replace_at([1, 2, 3], -10, 0) [1, 2, 3] ### List.starts_with?/2 (function) Returns `true` if `list` starts with the given `prefix` list, otherwise returns `false`. If `prefix` is an empty list, it returns `true`. ### Examples - List.starts_with?/2 (function) iex> List.starts_with?([1, 2, 3], [1, 2]) true iex> List.starts_with?([1, 2], [1, 2, 3]) false iex> List.starts_with?([:alpha], []) true iex> List.starts_with?([], [:alpha]) false ### List.to_atom/1 (function) Converts a charlist to an atom. Elixir supports conversions from charlists which contain any Unicode code point. Inlined by the compiler. ### Examples - List.to_atom/1 (function) iex> List.to_atom(~c"Elixir") :Elixir iex> List.to_atom(~c"🌢 Elixir") :"🌢 Elixir" ### List.to_charlist/1 (function) Converts a list of integers representing Unicode code points, lists or strings into a charlist. Note that this function expects a list of integers representing Unicode code points. If you have a list of bytes, you must instead use the [`:binary` module](`:binary`). ### Examples - List.to_charlist/1 (function) iex> ~c"æß" = List.to_charlist([0x00E6, 0x00DF]) [230, 223] iex> List.to_charlist([0x0061, "bc"]) ~c"abc" iex> List.to_charlist([0x0064, "ee", [~c"p"]]) ~c"deep" ### List.to_existing_atom/1 (function) Converts a charlist to an existing atom. Elixir supports conversions from charlists which contain any Unicode code point. Raises an `ArgumentError` if the atom does not exist. Inlined by the compiler. > #### Atoms and modules {: .info} > > Since Elixir is a compiled language, the atoms defined in a module > will only exist after said module is loaded, which typically happens > whenever a function in the module is executed. Therefore, it is > generally recommended to call `List.to_existing_atom/1` only to > convert atoms defined within the module making the function call > to `to_existing_atom/1`. ### Examples - List.to_existing_atom/1 (function) iex> _ = :my_atom iex> List.to_existing_atom(~c"my_atom") :my_atom iex> _ = :"🌢 Elixir" iex> List.to_existing_atom(~c"🌢 Elixir") :"🌢 Elixir" ### List.to_float/1 (function) Returns the float whose text representation is `charlist`. Inlined by the compiler. ### Examples - List.to_float/1 (function) iex> List.to_float(~c"2.2017764e+0") 2.2017764 ### List.to_integer/1 (function) Returns an integer whose text representation is `charlist`. Inlined by the compiler. ### Examples - List.to_integer/1 (function) iex> List.to_integer(~c"123") 123 ### List.to_integer/2 (function) Returns an integer whose text representation is `charlist` in base `base`. Inlined by the compiler. The base needs to be between `2` and `36`. ### Examples - List.to_integer/2 (function) iex> List.to_integer(~c"3FF", 16) 1023 ### List.to_string/1 (function) Converts a list of integers representing code points, lists or strings into a string. To be converted to a string, a list must either be empty or only contain the following elements: * strings * integers representing Unicode code points * a list containing one of these three elements Note that this function expects a list of integers representing Unicode code points. If you have a list of bytes, you must instead use the [`:binary` module](`:binary`). ### Examples - List.to_string/1 (function) iex> List.to_string([0x00E6, 0x00DF]) "æß" iex> List.to_string([0x0061, "bc"]) "abc" iex> List.to_string([0x0064, "ee", [~c"p"]]) "deep" iex> List.to_string([]) "" ### List.to_tuple/1 (function) Converts a list to a tuple. Inlined by the compiler. ### Examples - List.to_tuple/1 (function) iex> List.to_tuple([:share, [:elixir, 163]]) {:share, [:elixir, 163]} ### List.update_at/3 (function) Returns a list with an updated value at the specified `index`. Negative indices indicate an offset from the end of the `list`. If `index` is out of bounds, the original `list` is returned. ### Examples - List.update_at/3 (function) iex> List.update_at([1, 2, 3], 0, &(&1 + 10)) [11, 2, 3] iex> List.update_at([1, 2, 3], 10, &(&1 + 10)) [1, 2, 3] iex> List.update_at([1, 2, 3], -1, &(&1 + 10)) [1, 2, 13] iex> List.update_at([1, 2, 3], -10, &(&1 + 10)) [1, 2, 3] ### List.wrap/1 (function) Wraps `term` in a list if this is not list. If `term` is already a list, it returns the list. If `term` is `nil`, it returns an empty list. ### Examples - List.wrap/1 (function) iex> List.wrap("hello") ["hello"] iex> List.wrap([1, 2, 3]) [1, 2, 3] iex> List.wrap(nil) [] ### List.zip/1 (function) ### Map (module) Maps are the "go to" key-value data structure in Elixir. Maps can be created with the `%{}` syntax, and key-value pairs can be expressed as `key => value`: iex> %{} %{} iex> %{"one" => :two, 3 => "four"} %{3 => "four", "one" => :two} Key-value pairs in a map do not follow any order (that's why the printed map in the example above has a different order than the map that was created). Maps do not impose any restriction on the key type: anything can be a key in a map. As a key-value structure, maps do not allow duplicate keys. Keys are compared using the exact-equality operator (`===/2`). If colliding keys are defined in a map literal, the last one prevails. When the key in a key-value pair is an atom, the `key: value` shorthand syntax can be used (as in many other special forms): iex> %{a: 1, b: 2} %{a: 1, b: 2} If you want to mix the shorthand syntax with `=>`, the shorthand syntax must come at the end: iex> %{"hello" => "world", a: 1, b: 2} %{:a => 1, :b => 2, "hello" => "world"} Keys in maps can be accessed through some of the functions in this module (such as `Map.get/3` or `Map.fetch/2`) or through the `map[]` syntax provided by the `Access` module: iex> map = %{a: 1, b: 2} iex> Map.fetch(map, :a) {:ok, 1} iex> map[:b] 2 iex> map["non_existing_key"] nil To access atom keys, one may also use the `map.key` notation. Note that `map.key` will raise a `KeyError` if the `map` doesn't contain the key `:key`, compared to `map[:key]`, that would return `nil`. map = %{foo: "bar", baz: "bong"} map.foo #=> "bar" map.non_existing_key ** (KeyError) key :non_existing_key not found in: %{baz: "bong", foo: "bar"} > #### Avoid parentheses {: .warning} > > Do not add parentheses when accessing fields, such as in `data.key()`. > If parentheses are used, Elixir will expect `data` to be an atom representing > a module and attempt to call the *function* `key/0` in it. The two syntaxes for accessing keys reveal the dual nature of maps. The `map[key]` syntax is used for dynamically created maps that may have any key, of any type. `map.key` is used with maps that hold a predetermined set of atoms keys, which are expected to always be present. Structs, defined via `defstruct/1`, are one example of such "static maps", where the keys can also be checked during compile time. Maps can be pattern matched on. When a map is on the left-hand side of a pattern match, it will match if the map on the right-hand side contains the keys on the left-hand side and their values match the ones on the left-hand side. This means that an empty map matches every map. iex> %{} = %{foo: "bar"} %{foo: "bar"} iex> %{a: a} = %{:a => 1, "b" => 2, [:c, :e, :e] => 3} iex> a 1 But this will raise a `MatchError` exception: %{:c => 3} = %{:a => 1, 2 => :b} Variables can be used as map keys both when writing map literals as well as when matching: iex> n = 1 1 iex> %{n => :one} %{1 => :one} iex> %{^n => :one} = %{1 => :one, 2 => :two, 3 => :three} %{1 => :one, 2 => :two, 3 => :three} Maps also support a specific update syntax to update the value stored under *existing* keys. You can update using the atom keys syntax: iex> map = %{one: 1, two: 2} iex> %{map | one: "one"} %{one: "one", two: 2} Or any other keys: iex> other_map = %{"three" => 3, "four" => 4, "five" => 5} iex> %{other_map | "three" => "three", "four" => "four"} %{"five" => 5, "four" => "four", "three" => "three"} When a key that does not exist in the map is updated a `KeyError` exception will be raised: %{map | three: 3} The functions in this module that need to find a specific key work in logarithmic time. This means that the time it takes to find keys grows as the map grows, but it's not directly proportional to the map size. In comparison to finding an element in a list, it performs better because lists have a linear time complexity. Some functions, such as `keys/1` and `values/1`, run in linear time because they need to get to every element in the map. Maps also implement the `Enumerable` protocol, so many functions to work with maps are found in the `Enum` module. Additionally, the following functions for maps are found in `Kernel`: * `map_size/1` ### Map.delete/2 (function) Deletes the entry in `map` for a specific `key`. If the `key` does not exist, returns `map` unchanged. Inlined by the compiler. ### Examples - Map.delete/2 (function) iex> Map.delete(%{a: 1, b: 2}, :a) %{b: 2} iex> Map.delete(%{b: 2}, :a) %{b: 2} ### Map.drop/2 (function) Drops the given `keys` from `map`. If `keys` contains keys that are not in `map`, they're simply ignored. ### Examples - Map.drop/2 (function) iex> Map.drop(%{a: 1, b: 2, c: 3}, [:b, :d]) %{a: 1, c: 3} ### Map.equal?/2 (function) Checks if two maps are equal. Two maps are considered to be equal if they contain the same keys and those keys contain the same values. Note this function exists for completeness so the `Map` and `Keyword` modules provide similar APIs. In practice, developers often compare maps using `==/2` or `===/2` directly. ### Examples - Map.equal?/2 (function) iex> Map.equal?(%{a: 1, b: 2}, %{b: 2, a: 1}) true iex> Map.equal?(%{a: 1, b: 2}, %{b: 1, a: 2}) false Comparison between keys and values is done with `===/3`, which means integers are not equivalent to floats: iex> Map.equal?(%{a: 1.0}, %{a: 1}) false ### Map.fetch/2 (function) Fetches the value for a specific `key` in the given `map`. If `map` contains the given `key` then its value is returned in the shape of `{:ok, value}`. If `map` doesn't contain `key`, `:error` is returned. Inlined by the compiler. ### Examples - Map.fetch/2 (function) iex> Map.fetch(%{a: 1}, :a) {:ok, 1} iex> Map.fetch(%{a: 1}, :b) :error ### Map.fetch!/2 (function) Fetches the value for a specific `key` in the given `map`, erroring out if `map` doesn't contain `key`. If `map` contains `key`, the corresponding value is returned. If `map` doesn't contain `key`, a `KeyError` exception is raised. Inlined by the compiler. ### Examples - Map.fetch!/2 (function) iex> Map.fetch!(%{a: 1}, :a) 1 ### Map.filter/2 (function) Returns a map containing only those pairs from `map` for which `fun` returns a truthy value. `fun` receives the key and value of each of the elements in the map as a key-value pair. See also `reject/2` which discards all elements where the function returns a truthy value. > #### Performance considerations {: .tip} > > If you find yourself doing multiple calls to `Map.filter/2` > and `Map.reject/2` in a pipeline, it is likely more efficient > to use `Enum.map/2` and `Enum.filter/2` instead and convert to > a map at the end using `Map.new/1`. ### Examples - Map.filter/2 (function) iex> Map.filter(%{one: 1, two: 2, three: 3}, fn {_key, val} -> rem(val, 2) == 1 end) %{one: 1, three: 3} ### Map.from_keys/2 (function) Builds a map from the given `keys` and the fixed `value`. Inlined by the compiler. ### Examples - Map.from_keys/2 (function) iex> Map.from_keys([1, 2, 3], :number) %{1 => :number, 2 => :number, 3 => :number} ### Map.from_struct/1 (function) Converts a `struct` to map. It accepts a struct and simply removes the `__struct__` field from the given struct. ### Example - Map.from_struct/1 (function) defmodule User do defstruct [:name] end Map.from_struct(%User{name: "john"}) #=> %{name: "john"} ### Map.get/3 (function) Gets the value for a specific `key` in `map`. If `key` is present in `map` then its value `value` is returned. Otherwise, `default` is returned. If `default` is not provided, `nil` is used. ### Examples - Map.get/3 (function) iex> Map.get(%{}, :a) nil iex> Map.get(%{a: 1}, :a) 1 iex> Map.get(%{a: 1}, :b) nil iex> Map.get(%{a: 1}, :b, 3) 3 iex> Map.get(%{a: nil}, :a, 1) nil ### Map.get_and_update/3 (function) Gets the value from `key` and updates it, all in one pass. `fun` is called with the current value under `key` in `map` (or `nil` if `key` is not present in `map`) and must return a two-element tuple: the current value (the retrieved value, which can be operated on before being returned) and the new value to be stored under `key` in the resulting new map. `fun` may also return `:pop`, which means the current value shall be removed from `map` and returned (making this function behave like `Map.pop(map, key)`). The returned value is a two-element tuple with the current value returned by `fun` and a new map with the updated value under `key`. ### Examples - Map.get_and_update/3 (function) iex> Map.get_and_update(%{a: 1}, :a, fn current_value -> ...> {current_value, "new value!"} ...> end) {1, %{a: "new value!"}} iex> Map.get_and_update(%{a: 1}, :b, fn current_value -> ...> {current_value, "new value!"} ...> end) {nil, %{a: 1, b: "new value!"}} iex> Map.get_and_update(%{a: 1}, :a, fn _ -> :pop end) {1, %{}} iex> Map.get_and_update(%{a: 1}, :b, fn _ -> :pop end) {nil, %{a: 1}} ### Map.get_and_update!/3 (function) Gets the value from `key` and updates it, all in one pass. Raises if there is no `key`. Behaves exactly like `get_and_update/3`, but raises a `KeyError` exception if `key` is not present in `map`. ### Examples - Map.get_and_update!/3 (function) iex> Map.get_and_update!(%{a: 1}, :a, fn current_value -> ...> {current_value, "new value!"} ...> end) {1, %{a: "new value!"}} iex> Map.get_and_update!(%{a: 1}, :b, fn current_value -> ...> {current_value, "new value!"} ...> end) ** (KeyError) key :b not found in: %{a: 1} iex> Map.get_and_update!(%{a: 1}, :a, fn _ -> ...> :pop ...> end) {1, %{}} ### Map.get_lazy/3 (function) Gets the value for a specific `key` in `map`. If `key` is present in `map` then its value `value` is returned. Otherwise, `fun` is evaluated and its result is returned. This is useful if the default value is very expensive to calculate or generally difficult to setup and teardown again. ### Examples - Map.get_lazy/3 (function) iex> map = %{a: 1} iex> fun = fn -> ...> # some expensive operation here ...> 13 ...> end iex> Map.get_lazy(map, :a, fun) 1 iex> Map.get_lazy(map, :b, fun) 13 ### Map.has_key?/2 (function) Returns whether the given `key` exists in the given `map`. Inlined by the compiler. ### Examples - Map.has_key?/2 (function) iex> Map.has_key?(%{a: 1}, :a) true iex> Map.has_key?(%{a: 1}, :b) false ### Map.intersect/2 (function) Intersects two maps, returning a map with the common keys. The values in the returned map are the values of the intersected keys in `map2`. Inlined by the compiler. ### Examples - Map.intersect/2 (function) iex> Map.intersect(%{a: 1, b: 2}, %{b: "b", c: "c"}) %{b: "b"} ### Map.intersect/3 (function) Intersects two maps, returning a map with the common keys and resolving conflicts through a function. The given function will be invoked when there are duplicate keys; its arguments are `key` (the duplicate key), `value1` (the value of `key` in `map1`), and `value2` (the value of `key` in `map2`). The value returned by `fun` is used as the value under `key` in the resulting map. ### Examples - Map.intersect/3 (function) iex> Map.intersect(%{a: 1, b: 2}, %{b: 2, c: 3}, fn _k, v1, v2 -> ...> v1 + v2 ...> end) %{b: 4} ### Map.keys/1 (function) Returns all keys from `map`. Inlined by the compiler. ### Examples - Map.keys/1 (function) Map.keys(%{a: 1, b: 2}) [:a, :b] ### Map.merge/2 (function) Merges two maps into one. All keys in `map2` will be added to `map1`, overriding any existing one (i.e., the keys in `map2` "have precedence" over the ones in `map1`). If you have a struct and you would like to merge a set of keys into the struct, do not use this function, as it would merge all keys on the right side into the struct, even if the key is not part of the struct. Instead, use `struct/2`. Inlined by the compiler. ### Examples - Map.merge/2 (function) iex> Map.merge(%{a: 1, b: 2}, %{a: 3, d: 4}) %{a: 3, b: 2, d: 4} ### Map.merge/3 (function) Merges two maps into one, resolving conflicts through the given `fun`. All keys in `map2` will be added to `map1`. The given function will be invoked when there are duplicate keys; its arguments are `key` (the duplicate key), `value1` (the value of `key` in `map1`), and `value2` (the value of `key` in `map2`). The value returned by `fun` is used as the value under `key` in the resulting map. ### Examples - Map.merge/3 (function) iex> Map.merge(%{a: 1, b: 2}, %{a: 3, d: 4}, fn _k, v1, v2 -> ...> v1 + v2 ...> end) %{a: 4, b: 2, d: 4} ### Map.new/0 (function) Returns a new empty map. ### Examples - Map.new/0 (function) iex> Map.new() %{} ### Map.new/1 (function) Creates a map from an `enumerable`. Duplicated keys are removed; the latest one prevails. ### Examples - Map.new/1 (function) iex> Map.new([{:b, 1}, {:a, 2}]) %{a: 2, b: 1} iex> Map.new(a: 1, a: 2, a: 3) %{a: 3} ### Map.new/2 (function) Creates a map from an `enumerable` via the given transformation function. Duplicated keys are removed; the latest one prevails. ### Examples - Map.new/2 (function) iex> Map.new([:a, :b], fn x -> {x, x} end) %{a: :a, b: :b} iex> Map.new(%{a: 2, b: 3, c: 4}, fn {key, val} -> {key, val * 2} end) %{a: 4, b: 6, c: 8} ### Map.pop/3 (function) Removes the value associated with `key` in `map` and returns the value and the updated map. If `key` is present in `map`, it returns `{value, updated_map}` where `value` is the value of the key and `updated_map` is the result of removing `key` from `map`. If `key` is not present in `map`, `{default, map}` is returned. ### Examples - Map.pop/3 (function) iex> Map.pop(%{a: 1}, :a) {1, %{}} iex> Map.pop(%{a: 1}, :b) {nil, %{a: 1}} iex> Map.pop(%{a: 1}, :b, 3) {3, %{a: 1}} ### Map.pop!/2 (function) Removes and returns the value associated with `key` in `map` alongside the updated map, or raises if `key` is not present. Behaves the same as `pop/3` but raises a `KeyError` exception if `key` is not present in `map`. ### Examples - Map.pop!/2 (function) iex> Map.pop!(%{a: 1}, :a) {1, %{}} iex> Map.pop!(%{a: 1, b: 2}, :a) {1, %{b: 2}} iex> Map.pop!(%{a: 1}, :b) ** (KeyError) key :b not found in: %{a: 1} ### Map.pop_lazy/3 (function) Lazily returns and removes the value associated with `key` in `map`. If `key` is present in `map`, it returns `{value, new_map}` where `value` is the value of the key and `new_map` is the result of removing `key` from `map`. If `key` is not present in `map`, `{fun_result, map}` is returned, where `fun_result` is the result of applying `fun`. This is useful if the default value is very expensive to calculate or generally difficult to setup and teardown again. ### Examples - Map.pop_lazy/3 (function) iex> map = %{a: 1} iex> fun = fn -> ...> # some expensive operation here ...> 13 ...> end iex> Map.pop_lazy(map, :a, fun) {1, %{}} iex> Map.pop_lazy(map, :b, fun) {13, %{a: 1}} ### Map.put/3 (function) Puts the given `value` under `key` in `map`. Inlined by the compiler. ### Examples - Map.put/3 (function) iex> Map.put(%{a: 1}, :b, 2) %{a: 1, b: 2} iex> Map.put(%{a: 1, b: 2}, :a, 3) %{a: 3, b: 2} ### Map.put_new/3 (function) Puts the given `value` under `key` unless the entry `key` already exists in `map`. ### Examples - Map.put_new/3 (function) iex> Map.put_new(%{a: 1}, :b, 2) %{a: 1, b: 2} iex> Map.put_new(%{a: 1, b: 2}, :a, 3) %{a: 1, b: 2} ### Map.put_new_lazy/3 (function) Evaluates `fun` and puts the result under `key` in `map` unless `key` is already present. This function is useful in case you want to compute the value to put under `key` only if `key` is not already present, as for example, when the value is expensive to calculate or generally difficult to setup and teardown again. ### Examples - Map.put_new_lazy/3 (function) iex> map = %{a: 1} iex> fun = fn -> ...> # some expensive operation here ...> 3 ...> end iex> Map.put_new_lazy(map, :a, fun) %{a: 1} iex> Map.put_new_lazy(map, :b, fun) %{a: 1, b: 3} ### Map.reject/2 (function) Returns map excluding the pairs from `map` for which `fun` returns a truthy value. See also `filter/2`. ### Examples - Map.reject/2 (function) iex> Map.reject(%{one: 1, two: 2, three: 3}, fn {_key, val} -> rem(val, 2) == 1 end) %{two: 2} ### Map.replace/3 (function) Puts a value under `key` only if the `key` already exists in `map`. ### Examples - Map.replace/3 (function) iex> Map.replace(%{a: 1, b: 2}, :a, 3) %{a: 3, b: 2} iex> Map.replace(%{a: 1}, :b, 2) %{a: 1} ### Map.replace!/3 (function) Puts a value under `key` only if the `key` already exists in `map`. If `key` is not present in `map`, a `KeyError` exception is raised. Inlined by the compiler. ### Examples - Map.replace!/3 (function) iex> Map.replace!(%{a: 1, b: 2}, :a, 3) %{a: 3, b: 2} iex> Map.replace!(%{a: 1}, :b, 2) ** (KeyError) key :b not found in: %{a: 1} ### Map.replace_lazy/3 (function) Replaces the value under `key` using the given function only if `key` already exists in `map`. In comparison to `replace/3`, this can be useful when it's expensive to calculate the value. If `key` does not exist, the original map is returned unchanged. ### Examples - Map.replace_lazy/3 (function) iex> Map.replace_lazy(%{a: 1, b: 2}, :a, fn v -> v * 4 end) %{a: 4, b: 2} iex> Map.replace_lazy(%{a: 1, b: 2}, :c, fn v -> v * 4 end) %{a: 1, b: 2} ### Map.split/2 (function) Takes all entries corresponding to the given `keys` in `map` and extracts them into a separate map. Returns a tuple with the new map and the old map with removed keys. Keys for which there are no entries in `map` are ignored. ### Examples - Map.split/2 (function) iex> Map.split(%{a: 1, b: 2, c: 3}, [:a, :c, :e]) {%{a: 1, c: 3}, %{b: 2}} ### Map.split_with/2 (function) Splits the `map` into two maps according to the given function `fun`. `fun` receives each `{key, value}` pair in the `map` as its only argument. Returns a tuple with the first map containing all the elements in `map` for which applying `fun` returned a truthy value, and a second map with all the elements for which applying `fun` returned a falsy value (`false` or `nil`). ### Examples - Map.split_with/2 (function) iex> Map.split_with(%{a: 1, b: 2, c: 3, d: 4}, fn {_k, v} -> rem(v, 2) == 0 end) {%{b: 2, d: 4}, %{a: 1, c: 3}} iex> Map.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {k, _v} -> k in [:b, :d] end) {%{b: -2, d: -3}, %{a: 1, c: 1}} iex> Map.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {_k, v} -> v > 50 end) {%{}, %{a: 1, b: -2, c: 1, d: -3}} iex> Map.split_with(%{}, fn {_k, v} -> v > 50 end) {%{}, %{}} ### Map.take/2 (function) Returns a new map with all the key-value pairs in `map` where the key is in `keys`. If `keys` contains keys that are not in `map`, they're simply ignored. ### Examples - Map.take/2 (function) iex> Map.take(%{a: 1, b: 2, c: 3}, [:a, :c, :e]) %{a: 1, c: 3} ### Map.to_list/1 (function) Converts `map` to a list. Each key-value pair in the map is converted to a two-element tuple `{key, value}` in the resulting list. Inlined by the compiler. ### Examples - Map.to_list/1 (function) iex> Map.to_list(%{a: 1}) [a: 1] iex> Map.to_list(%{1 => 2}) [{1, 2}] ### Map.update/4 (function) Updates the `key` in `map` with the given function. If `key` is present in `map` then the existing value is passed to `fun` and its result is used as the updated value of `key`. If `key` is not present in `map`, `default` is inserted as the value of `key`. The default value will not be passed through the update function. ### Examples - Map.update/4 (function) iex> Map.update(%{a: 1}, :a, 13, fn existing_value -> existing_value * 2 end) %{a: 2} iex> Map.update(%{a: 1}, :b, 11, fn existing_value -> existing_value * 2 end) %{a: 1, b: 11} ### Map.update!/3 (function) Updates `key` with the given function. If `key` is present in `map` then the existing value is passed to `fun` and its result is used as the updated value of `key`. If `key` is not present in `map`, a `KeyError` exception is raised. ### Examples - Map.update!/3 (function) iex> Map.update!(%{a: 1}, :a, &(&1 * 2)) %{a: 2} iex> Map.update!(%{a: 1}, :b, &(&1 * 2)) ** (KeyError) key :b not found in: %{a: 1} ### Map.values/1 (function) Returns all values from `map`. Inlined by the compiler. ### Examples - Map.values/1 (function) Map.values(%{a: 1, b: 2}) [1, 2] ### Map.key/0 (type) ### Map.value/0 (type) ### MapSet (module) Functions that work on sets. A set is a data structure that can contain unique elements of any kind, without any particular order. `MapSet` is the "go to" set data structure in Elixir. A set can be constructed using `MapSet.new/0`: iex> MapSet.new() MapSet.new([]) Elements in a set don't have to be of the same type and they can be populated from an [enumerable](`t:Enumerable.t/0`) using `MapSet.new/1`: iex> MapSet.new([1, :two, {"three"}]) MapSet.new([1, :two, {"three"}]) Elements can be inserted using `MapSet.put/2`: iex> MapSet.new([2]) |> MapSet.put(4) |> MapSet.put(0) MapSet.new([0, 2, 4]) By definition, sets can't contain duplicate elements: when inserting an element in a set where it's already present, the insertion is simply a no-op. iex> map_set = MapSet.new() iex> MapSet.put(map_set, "foo") MapSet.new(["foo"]) iex> map_set |> MapSet.put("foo") |> MapSet.put("foo") MapSet.new(["foo"]) A `MapSet` is represented internally using the `%MapSet{}` struct. This struct can be used whenever there's a need to pattern match on something being a `MapSet`: iex> match?(%MapSet{}, MapSet.new()) true Note that, however, the struct fields are private and must not be accessed directly; use the functions in this module to perform operations on sets. `MapSet`s can also be constructed starting from other collection-type data structures: for example, see `MapSet.new/1` or `Enum.into/2`. `MapSet` is built on top of Erlang's [`:sets`](https://www.erlang.org/doc/man/sets.html) (version 2). This means that they share many properties, including logarithmic time complexity. Erlang `:sets` (version 2) are implemented on top of maps, so see the documentation for `Map` for more information on its execution time complexity. ### MapSet.delete/2 (function) Deletes `value` from `map_set`. Returns a new set which is a copy of `map_set` but without `value`. ### Examples - MapSet.delete/2 (function) iex> map_set = MapSet.new([1, 2, 3]) iex> MapSet.delete(map_set, 4) MapSet.new([1, 2, 3]) iex> MapSet.delete(map_set, 2) MapSet.new([1, 3]) ### MapSet.difference/2 (function) Returns a set that is `map_set1` without the members of `map_set2`. ### Examples - MapSet.difference/2 (function) iex> MapSet.difference(MapSet.new([1, 2]), MapSet.new([2, 3, 4])) MapSet.new([1]) ### MapSet.disjoint?/2 (function) Checks if `map_set1` and `map_set2` have no members in common. ### Examples - MapSet.disjoint?/2 (function) iex> MapSet.disjoint?(MapSet.new([1, 2]), MapSet.new([3, 4])) true iex> MapSet.disjoint?(MapSet.new([1, 2]), MapSet.new([2, 3])) false ### MapSet.equal?/2 (function) Checks if two sets are equal. The comparison between elements is done using `===/2`, which a set with `1` is not equivalent to a set with `1.0`. ### Examples - MapSet.equal?/2 (function) iex> MapSet.equal?(MapSet.new([1, 2]), MapSet.new([2, 1, 1])) true iex> MapSet.equal?(MapSet.new([1, 2]), MapSet.new([3, 4])) false iex> MapSet.equal?(MapSet.new([1]), MapSet.new([1.0])) false ### MapSet.filter/2 (function) Filters the set by returning only the elements from `map_set` for which invoking `fun` returns a truthy value. Also see `reject/2` which discards all elements where the function returns a truthy value. > #### Performance considerations {: .tip} > > If you find yourself doing multiple calls to `MapSet.filter/2` > and `MapSet.reject/2` in a pipeline, it is likely more efficient > to use `Enum.map/2` and `Enum.filter/2` instead and convert to > a map at the end using `MapSet.new/1`. ### Examples - MapSet.filter/2 (function) iex> MapSet.filter(MapSet.new(1..5), fn x -> x > 3 end) MapSet.new([4, 5]) iex> MapSet.filter(MapSet.new(["a", :b, "c"]), &is_atom/1) MapSet.new([:b]) ### MapSet.intersection/2 (function) Returns a set containing only members that `map_set1` and `map_set2` have in common. ### Examples - MapSet.intersection/2 (function) iex> MapSet.intersection(MapSet.new([1, 2]), MapSet.new([2, 3, 4])) MapSet.new([2]) iex> MapSet.intersection(MapSet.new([1, 2]), MapSet.new([3, 4])) MapSet.new([]) ### MapSet.member?/2 (function) Checks if `map_set` contains `value`. ### Examples - MapSet.member?/2 (function) iex> MapSet.member?(MapSet.new([1, 2, 3]), 2) true iex> MapSet.member?(MapSet.new([1, 2, 3]), 4) false ### MapSet.new/0 (function) Returns a new set. ### Examples - MapSet.new/0 (function) iex> MapSet.new() MapSet.new([]) ### MapSet.new/1 (function) Creates a set from an enumerable. ### Examples - MapSet.new/1 (function) iex> MapSet.new([:b, :a, 3]) MapSet.new([3, :a, :b]) iex> MapSet.new([3, 3, 3, 2, 2, 1]) MapSet.new([1, 2, 3]) ### MapSet.new/2 (function) Creates a set from an enumerable via the transformation function. ### Examples - MapSet.new/2 (function) iex> MapSet.new([1, 2, 1], fn x -> 2 * x end) MapSet.new([2, 4]) ### MapSet.put/2 (function) Inserts `value` into `map_set` if `map_set` doesn't already contain it. ### Examples - MapSet.put/2 (function) iex> MapSet.put(MapSet.new([1, 2, 3]), 3) MapSet.new([1, 2, 3]) iex> MapSet.put(MapSet.new([1, 2, 3]), 4) MapSet.new([1, 2, 3, 4]) ### MapSet.reject/2 (function) Returns a set by excluding the elements from `map_set` for which invoking `fun` returns a truthy value. See also `filter/2`. ### Examples - MapSet.reject/2 (function) iex> MapSet.reject(MapSet.new(1..5), fn x -> rem(x, 2) != 0 end) MapSet.new([2, 4]) iex> MapSet.reject(MapSet.new(["a", :b, "c"]), &is_atom/1) MapSet.new(["a", "c"]) ### MapSet.size/1 (function) Returns the number of elements in `map_set`. ### Examples - MapSet.size/1 (function) iex> MapSet.size(MapSet.new([1, 2, 3])) 3 ### MapSet.split_with/2 (function) Splits the `map_set` into two `MapSet`s according to the given function `fun`. `fun` receives each element in the `map_set` as its only argument. Returns a tuple with the first `MapSet` containing all the elements in `map_set` for which applying `fun` returned a truthy value, and a second `MapSet` with all the elements for which applying `fun` returned a falsy value (`false` or `nil`). ### Examples - MapSet.split_with/2 (function) iex> {while_true, while_false} = MapSet.split_with(MapSet.new([1, 2, 3, 4]), fn v -> rem(v, 2) == 0 end) iex> while_true MapSet.new([2, 4]) iex> while_false MapSet.new([1, 3]) iex> {while_true, while_false} = MapSet.split_with(MapSet.new(), fn {_k, v} -> v > 50 end) iex> while_true MapSet.new([]) iex> while_false MapSet.new([]) ### MapSet.subset?/2 (function) Checks if `map_set1`'s members are all contained in `map_set2`. This function checks if `map_set1` is a subset of `map_set2`. ### Examples - MapSet.subset?/2 (function) iex> MapSet.subset?(MapSet.new([1, 2]), MapSet.new([1, 2, 3])) true iex> MapSet.subset?(MapSet.new([1, 2, 3]), MapSet.new([1, 2])) false ### MapSet.symmetric_difference/2 (function) Returns a set with elements that are present in only one but not both sets. ### Examples - MapSet.symmetric_difference/2 (function) iex> MapSet.symmetric_difference(MapSet.new([1, 2, 3]), MapSet.new([2, 3, 4])) MapSet.new([1, 4]) ### MapSet.to_list/1 (function) Converts `map_set` to a list. ### Examples - MapSet.to_list/1 (function) iex> MapSet.to_list(MapSet.new([1, 2, 3])) [1, 2, 3] ### MapSet.union/2 (function) Returns a set containing all members of `map_set1` and `map_set2`. ### Examples - MapSet.union/2 (function) iex> MapSet.union(MapSet.new([1, 2]), MapSet.new([2, 3, 4])) MapSet.new([1, 2, 3, 4]) ### MapSet.t/0 (type) ### MapSet.t/1 (type) ### MapSet.value/0 (type) ### Range (module) Ranges represent a sequence of zero, one or many, ascending or descending integers with a common difference called step. The most common form of creating and matching on ranges is via the [`first..last`](`../2`) and [`first..last//step`](`..///3`) notations, auto-imported from `Kernel`: iex> 1 in 1..10 true iex> 5 in 1..10 true iex> 10 in 1..10 true Ranges are always inclusive in Elixir. When a step is defined, integers will only belong to the range if they match the step: iex> 5 in 1..10//2 true iex> 4 in 1..10//2 false When defining a range without a step, the step will be defined based on the first and last position of the range, If `last >= first`, it will be an increasing range with a step of 1. Otherwise, it is a decreasing range. Note, however, implicit decreasing ranges are deprecated. Therefore, if you need a decreasing range from `3` to `1`, prefer to write `3..1//-1` instead. `../0` can also be used as a shortcut to create the range `0..-1//1`, also known as the full-slice range: iex> .. 0..-1//1 ### Use cases - Range (module) Ranges typically have two uses in Elixir: as a collection or to represent a slice of another data structure. ### Ranges as collections - Range (module) Ranges in Elixir are enumerables and therefore can be used with the `Enum` module: iex> Enum.to_list(1..3) [1, 2, 3] iex> Enum.to_list(3..1//-1) [3, 2, 1] iex> Enum.to_list(1..5//2) [1, 3, 5] Ranges may also have a single element: iex> Enum.to_list(1..1) [1] iex> Enum.to_list(1..1//2) [1] Or even no elements at all: iex> Enum.to_list(10..0//1) [] iex> Enum.to_list(0..10//-1) [] The full-slice range, returned by `../0`, is an empty collection: iex> Enum.to_list(..) [] ### Ranges as slices - Range (module) Ranges are also frequently used to slice collections. You can slice strings or any enumerable: iex> String.slice("elixir", 1..4) "lixi" iex> Enum.slice([0, 1, 2, 3, 4, 5], 1..4) [1, 2, 3, 4] In those cases, the first and last values of the range are mapped to positions in the collections. If a negative number is given, it maps to a position from the back: iex> String.slice("elixir", 1..-2//1) "lixi" iex> Enum.slice([0, 1, 2, 3, 4, 5], 1..-2//1) [1, 2, 3, 4] The range `0..-1//1`, returned by `../0`, returns the collection as is, which is why it is called the full-slice range: iex> String.slice("elixir", ..) "elixir" iex> Enum.slice([0, 1, 2, 3, 4, 5], ..) [0, 1, 2, 3, 4, 5] ### Definition - Range (module) An increasing range `first..last//step` is a range from `first` to `last` increasing by `step` where `step` must be a positive integer and all values `v` must be `first <= v and v <= last`. Therefore, a range `10..0//1` is an empty range because there is no value `v` that is `10 <= v and v <= 0`. Similarly, a decreasing range `first..last//step` is a range from `first` to `last` decreasing by `step` where `step` must be a negative integer and values `v` must be `first >= v and v >= last`. Therefore, a range `0..10//-1` is an empty range because there is no value `v` that is `0 >= v and v >= 10`. ### Representation - Range (module) Internally, ranges are represented as structs: iex> range = 1..9//2 1..9//2 iex> first..last//step = range iex> first 1 iex> last 9 iex> step 2 iex> range.step 2 You can access the range fields (`first`, `last`, and `step`) directly but you should not modify nor create ranges by hand. Instead use the proper operators or `new/2` and `new/3`. Ranges implement the `Enumerable` protocol with memory efficient versions of all `Enumerable` callbacks: iex> range = 1..10 1..10 iex> Enum.reduce(range, 0, fn i, acc -> i * i + acc end) 385 iex> Enum.count(range) 10 iex> Enum.member?(range, 11) false iex> Enum.member?(range, 8) true Such function calls are efficient memory-wise no matter the size of the range. The implementation of the `Enumerable` protocol uses logic based solely on the endpoints and does not materialize the whole list of integers. ### Range.disjoint?/2 (function) Checks if two ranges are disjoint. ### Examples - Range.disjoint?/2 (function) iex> Range.disjoint?(1..5, 6..9) true iex> Range.disjoint?(5..1//-1, 6..9) true iex> Range.disjoint?(1..5, 5..9) false iex> Range.disjoint?(1..5, 2..7) false Steps are also considered when computing the ranges to be disjoint: iex> Range.disjoint?(1..10//2, 2..10//2) true # First element in common is 29 iex> Range.disjoint?(1..100//14, 8..100//21) false iex> Range.disjoint?(57..-1//-14, 8..100//21) false iex> Range.disjoint?(1..100//14, 50..8//-21) false iex> Range.disjoint?(1..28//14, 8..28//21) true # First element in common is 14 iex> Range.disjoint?(2..28//3, 9..28//5) false iex> Range.disjoint?(26..2//-3, 29..9//-5) false # Starting from the back without alignment iex> Range.disjoint?(27..11//-3, 30..0//-7) true ### Range.new/2 (function) Creates a new range. If `first` is less than `last`, the range will be increasing from `first` to `last`. If `first` is equal to `last`, the range will contain one element, which is the number itself. If `first` is greater than `last`, the range will be decreasing from `first` to `last`, albeit this behavior is deprecated. Therefore, it is advised to explicitly list the step with `new/3`. ### Examples - Range.new/2 (function) iex> Range.new(-100, 100) -100..100 ### Range.new/3 (function) Creates a new range with `step`. ### Examples - Range.new/3 (function) iex> Range.new(-100, 100, 2) -100..100//2 ### Range.shift/2 (function) Shifts a range by the given number of steps. ### Examples - Range.shift/2 (function) iex> Range.shift(0..10, 1) 1..11 iex> Range.shift(0..10, 2) 2..12 iex> Range.shift(0..10//2, 2) 4..14//2 iex> Range.shift(10..0//-2, 2) 6..-4//-2 ### Range.size/1 (function) Returns the size of `range`. ### Examples - Range.size/1 (function) iex> Range.size(1..10) 10 iex> Range.size(1..10//2) 5 iex> Range.size(1..10//3) 4 iex> Range.size(1..10//-1) 0 iex> Range.size(10..1//-1) 10 iex> Range.size(10..1//-2) 5 iex> Range.size(10..1//-3) 4 iex> Range.size(10..1//1) 0 ### Range.split/2 (function) Splits a range in two. It returns a tuple of two elements. If `split` is less than the number of elements in the range, the first element in the range will have `split` entries and the second will have all remaining entries. If `split` is more than the number of elements in the range, the second range in the tuple will emit zero elements. ### Examples - Range.split/2 (function) Increasing ranges: iex> Range.split(1..5, 2) {1..2, 3..5} iex> Range.split(1..5//2, 2) {1..3//2, 5..5//2} iex> Range.split(1..5//2, 0) {1..-1//2, 1..5//2} iex> Range.split(1..5//2, 10) {1..5//2, 7..5//2} Decreasing ranges can also be split: iex> Range.split(5..1//-1, 2) {5..4//-1, 3..1//-1} iex> Range.split(5..1//-2, 2) {5..3//-2, 1..1//-2} iex> Range.split(5..1//-2, 0) {5..7//-2, 5..1//-2} iex> Range.split(5..1//-2, 10) {5..1//-2, -1..1//-2} Empty ranges preserve their property but still return empty ranges: iex> Range.split(2..5//-1, 2) {2..3//-1, 4..5//-1} iex> Range.split(2..5//-1, 10) {2..3//-1, 4..5//-1} iex> Range.split(5..2//1, 2) {5..4//1, 3..2//1} iex> Range.split(5..2//1, 10) {5..4//1, 3..2//1} If the number to split is negative, it splits from the back: iex> Range.split(1..5, -2) {1..3, 4..5} iex> Range.split(5..1//-1, -2) {5..3//-1, 2..1//-1} If it is negative and greater than the elements in the range, the first element of the tuple will be an empty range: iex> Range.split(1..5, -10) {1..0//1, 1..5} iex> Range.split(5..1//-1, -10) {5..6//-1, 5..1//-1} ### Properties - Range.split/2 (function) When a range is split, the following properties are observed. Given `split(input)` returns `{left, right}`, we have: assert input.first == left.first assert input.last == right.last assert input.step == left.step assert input.step == right.step assert Range.size(input) == Range.size(left) + Range.size(right) ### Range.to_list/1 (function) Converts a range to a list. ### Examples - Range.to_list/1 (function) iex> Range.to_list(0..5) [0, 1, 2, 3, 4, 5] iex> Range.to_list(-3..0) [-3, -2, -1, 0] ### Range.limit/0 (type) ### Range.step/0 (type) ### Range.t/0 (type) ### Range.t/2 (type) ### Stream (module) Functions for creating and composing streams. Streams are composable, lazy enumerables (for an introduction on enumerables, see the `Enum` module). Any enumerable that generates elements one by one during enumeration is called a stream. For example, Elixir's `Range` is a stream: iex> range = 1..5 1..5 iex> Enum.map(range, &(&1 * 2)) [2, 4, 6, 8, 10] In the example above, as we mapped over the range, the elements being enumerated were created one by one, during enumeration. The `Stream` module allows us to map the range, without triggering its enumeration: iex> range = 1..3 iex> stream = Stream.map(range, &(&1 * 2)) iex> Enum.map(stream, &(&1 + 1)) [3, 5, 7] Note that we started with a range and then we created a stream that is meant to multiply each element in the range by 2. At this point, no computation was done. Only when `Enum.map/2` is called we actually enumerate over each element in the range, multiplying it by 2 and adding 1. We say the functions in `Stream` are *lazy* and the functions in `Enum` are *eager*. Due to their laziness, streams are useful when working with large (or even infinite) collections. When chaining many operations with `Enum`, intermediate lists are created, while `Stream` creates a recipe of computations that are executed at a later moment. Then when the stream is consumed later on, most commonly by using a function in the `Enum` module, the stream will emit its elements one by one. Let's see another example: 1..3 |> Enum.map(&IO.inspect(&1)) |> Enum.map(&(&1 * 2)) |> Enum.map(&IO.inspect(&1)) 1 2 3 2 4 6 #=> [2, 4, 6] Note that we first printed each element in the list, then multiplied each element by 2 and finally printed each new value. In this example, the list was enumerated three times. Let's see an example with streams: stream = 1..3 |> Stream.map(&IO.inspect(&1)) |> Stream.map(&(&1 * 2)) |> Stream.map(&IO.inspect(&1)) Enum.to_list(stream) 1 2 2 4 3 6 #=> [2, 4, 6] Although the end result is the same, the order in which the elements were printed changed! With streams, we print the first element and then print its double. In this example, the list was enumerated just once! That's what we meant when we said earlier that streams are composable, lazy enumerables. Note that we could call `Stream.map/2` multiple times, effectively composing the streams and keeping them lazy. The computations are only performed when you call a function from the `Enum` module. Like with `Enum`, the functions in this module work in linear time. This means that, the time it takes to perform an operation grows at the same rate as the length of the list. This is expected on operations such as `Stream.map/2`. After all, if we want to traverse every element on a stream, the longer the stream, the more elements we need to traverse, and the longer it will take. ### Creating Streams - Stream (module) There are many functions in Elixir's standard library that return streams, some examples are: * `IO.stream/2` - streams input lines, one by one * `URI.query_decoder/1` - decodes a query string, pair by pair This module also provides many convenience functions for creating streams, like `Stream.cycle/1`, `Stream.unfold/2`, `Stream.resource/3` and more. > #### Do not check for `Stream` structs > > While some functions in this module may return the `Stream` struct, > you must never explicitly check for the `Stream` struct, as streams > may come in several shapes, such as `IO.Stream`, `File.Stream`, or > even `Range`s. > > The functions in this module only guarantee to return enumerables > and their implementation (structs, anonymous functions, etc) may > change at any time. For example, a function that returns an anonymous > function today may return a struct in future releases. > > Instead of checking for a particular type, you must instead write > assertive code that assumes you have an enumerable, using the functions > in the `Enum` or `Stream` module accordingly. ### Stream.chunk_by/2 (function) Chunks the `enum` by buffering elements for which `fun` returns the same value. Elements are only emitted when `fun` returns a new value or the `enum` finishes. ### Examples - Stream.chunk_by/2 (function) iex> stream = Stream.chunk_by([1, 2, 2, 3, 4, 4, 6, 7, 7], &(rem(&1, 2) == 1)) iex> Enum.to_list(stream) [[1], [2, 2], [3], [4, 4, 6], [7, 7]] ### Stream.chunk_every/2 (function) Shortcut to `chunk_every(enum, count, count)`. ### Stream.chunk_every/4 (function) Streams the enumerable in chunks, containing `count` elements each, where each new chunk starts `step` elements into the enumerable. `step` is optional and, if not passed, defaults to `count`, i.e. chunks do not overlap. Chunking will stop as soon as the collection ends or when we emit an incomplete chunk. If the last chunk does not have `count` elements to fill the chunk, elements are taken from `leftover` to fill in the chunk. If `leftover` does not have enough elements to fill the chunk, then a partial chunk is returned with less than `count` elements. If `:discard` is given in `leftover`, the last chunk is discarded unless it has exactly `count` elements. ### Examples - Stream.chunk_every/4 (function) iex> Stream.chunk_every([1, 2, 3, 4, 5, 6], 2) |> Enum.to_list() [[1, 2], [3, 4], [5, 6]] iex> Stream.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, :discard) |> Enum.to_list() [[1, 2, 3], [3, 4, 5]] iex> Stream.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, [7]) |> Enum.to_list() [[1, 2, 3], [3, 4, 5], [5, 6, 7]] iex> Stream.chunk_every([1, 2, 3, 4, 5, 6], 3, 3, []) |> Enum.to_list() [[1, 2, 3], [4, 5, 6]] iex> Stream.chunk_every([1, 2, 3, 4], 3, 3, Stream.cycle([0])) |> Enum.to_list() [[1, 2, 3], [4, 0, 0]] ### Stream.chunk_while/4 (function) Chunks the `enum` with fine grained control when every chunk is emitted. `chunk_fun` receives the current element and the accumulator and must return `{:cont, element, acc}` to emit the given chunk and continue with accumulator or `{:cont, acc}` to not emit any chunk and continue with the return accumulator. `after_fun` is invoked when iteration is done and must also return `{:cont, element, acc}` or `{:cont, acc}`. ### Examples - Stream.chunk_while/4 (function) iex> chunk_fun = fn element, acc -> ...> if rem(element, 2) == 0 do ...> {:cont, Enum.reverse([element | acc]), []} ...> else ...> {:cont, [element | acc]} ...> end ...> end iex> after_fun = fn ...> [] -> {:cont, []} ...> acc -> {:cont, Enum.reverse(acc), []} ...> end iex> stream = Stream.chunk_while(1..10, [], chunk_fun, after_fun) iex> Enum.to_list(stream) [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] ### Stream.concat/1 (function) Creates a stream that enumerates each enumerable in an enumerable. ### Examples - Stream.concat/1 (function) iex> stream = Stream.concat([1..3, 4..6, 7..9]) iex> Enum.to_list(stream) [1, 2, 3, 4, 5, 6, 7, 8, 9] ### Stream.concat/2 (function) Creates a stream that enumerates the first argument, followed by the second. ### Examples - Stream.concat/2 (function) iex> stream = Stream.concat(1..3, 4..6) iex> Enum.to_list(stream) [1, 2, 3, 4, 5, 6] iex> stream1 = Stream.cycle([1, 2, 3]) iex> stream2 = Stream.cycle([4, 5, 6]) iex> stream = Stream.concat(stream1, stream2) iex> Enum.take(stream, 6) [1, 2, 3, 1, 2, 3] ### Stream.cycle/1 (function) Creates a stream that cycles through the given enumerable, infinitely. ### Examples - Stream.cycle/1 (function) iex> stream = Stream.cycle([1, 2, 3]) iex> Enum.take(stream, 5) [1, 2, 3, 1, 2] ### Stream.dedup/1 (function) Creates a stream that only emits elements if they are different from the last emitted element. This function only ever needs to store the last emitted element. Elements are compared using `===/2`. ### Examples - Stream.dedup/1 (function) iex> Stream.dedup([1, 2, 3, 3, 2, 1]) |> Enum.to_list() [1, 2, 3, 2, 1] ### Stream.dedup_by/2 (function) Creates a stream that only emits elements if the result of calling `fun` on the element is different from the (stored) result of calling `fun` on the last emitted element. ### Examples - Stream.dedup_by/2 (function) iex> Stream.dedup_by([{1, :x}, {2, :y}, {2, :z}, {1, :x}], fn {x, _} -> x end) |> Enum.to_list() [{1, :x}, {2, :y}, {1, :x}] ### Stream.drop/2 (function) Lazily drops the next `n` elements from the enumerable. If a negative `n` is given, it will drop the last `n` elements from the collection. Note that the mechanism by which this is implemented will delay the emission of any element until `n` additional elements have been emitted by the enum. ### Examples - Stream.drop/2 (function) iex> stream = Stream.drop(1..10, 5) iex> Enum.to_list(stream) [6, 7, 8, 9, 10] iex> stream = Stream.drop(1..10, -5) iex> Enum.to_list(stream) [1, 2, 3, 4, 5] ### Stream.drop_every/2 (function) Creates a stream that drops every `nth` element from the enumerable. The first element is always dropped, unless `nth` is 0. `nth` must be a non-negative integer. ### Examples - Stream.drop_every/2 (function) iex> stream = Stream.drop_every(1..10, 2) iex> Enum.to_list(stream) [2, 4, 6, 8, 10] iex> stream = Stream.drop_every(1..1000, 1) iex> Enum.to_list(stream) [] iex> stream = Stream.drop_every([1, 2, 3, 4, 5], 0) iex> Enum.to_list(stream) [1, 2, 3, 4, 5] ### Stream.drop_while/2 (function) Lazily drops elements of the enumerable while the given function returns a truthy value. ### Examples - Stream.drop_while/2 (function) iex> stream = Stream.drop_while(1..10, &(&1 <= 5)) iex> Enum.to_list(stream) [6, 7, 8, 9, 10] ### Stream.duplicate/2 (function) Duplicates the given element `n` times in a stream. `n` is an integer greater than or equal to `0`. If `n` is `0`, an empty stream is returned. ### Examples - Stream.duplicate/2 (function) iex> stream = Stream.duplicate("hello", 0) iex> Enum.to_list(stream) [] iex> stream = Stream.duplicate("hi", 1) iex> Enum.to_list(stream) ["hi"] iex> stream = Stream.duplicate("bye", 2) iex> Enum.to_list(stream) ["bye", "bye"] iex> stream = Stream.duplicate([1, 2], 3) iex> Enum.to_list(stream) [[1, 2], [1, 2], [1, 2]] ### Stream.each/2 (function) Executes the given function for each element. The values in the stream do not change, therefore this function is useful for adding side effects (like printing) to a stream. See `map/2` if producing a different stream is desired. ### Examples - Stream.each/2 (function) iex> stream = Stream.each([1, 2, 3], fn x -> send(self(), x) end) iex> Enum.to_list(stream) iex> receive do: (x when is_integer(x) -> x) 1 iex> receive do: (x when is_integer(x) -> x) 2 iex> receive do: (x when is_integer(x) -> x) 3 ### Stream.filter/2 (function) Creates a stream that filters elements according to the given function on enumeration. ### Examples - Stream.filter/2 (function) iex> stream = Stream.filter([1, 2, 3], fn x -> rem(x, 2) == 0 end) iex> Enum.to_list(stream) [2] ### Stream.flat_map/2 (function) Maps the given `fun` over `enumerable` and flattens the result. This function returns a new stream built by appending the result of invoking `fun` on each element of `enumerable` together. ### Examples - Stream.flat_map/2 (function) iex> stream = Stream.flat_map([1, 2, 3], fn x -> [x, x * 2] end) iex> Enum.to_list(stream) [1, 2, 2, 4, 3, 6] iex> stream = Stream.flat_map([1, 2, 3], fn x -> [[x]] end) iex> Enum.to_list(stream) [[1], [2], [3]] ### Stream.from_index/1 (function) Builds a stream from an index, either starting from offset, or given by function. May receive a function or an integer offset. If an `offset` is given, it will emit elements from offset. If a `function` is given, it will invoke the function with elements from offset. ### Examples - Stream.from_index/1 (function) iex> Stream.from_index() |> Enum.take(3) [0, 1, 2] iex> Stream.from_index(1) |> Enum.take(3) [1, 2, 3] iex> Stream.from_index(fn x -> x * 10 end) |> Enum.take(3) [0, 10, 20] ### Stream.intersperse/2 (function) Lazily intersperses `intersperse_element` between each element of the enumeration. ### Examples - Stream.intersperse/2 (function) iex> Stream.intersperse([1, 2, 3], 0) |> Enum.to_list() [1, 0, 2, 0, 3] iex> Stream.intersperse([1], 0) |> Enum.to_list() [1] iex> Stream.intersperse([], 0) |> Enum.to_list() [] ### Stream.interval/1 (function) Creates a stream that emits a value after the given period `n` in milliseconds. The values emitted are an increasing counter starting at `0`. This operation will block the caller by the given interval every time a new element is streamed. Do not use this function to generate a sequence of numbers. If blocking the caller process is not necessary, use `Stream.iterate(0, & &1 + 1)` instead. ### Examples - Stream.interval/1 (function) iex> Stream.interval(10) |> Enum.take(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ### Stream.into/3 (function) Injects the stream values into the given collectable as a side-effect. This function is often used with `run/1` since any evaluation is delayed until the stream is executed. See `run/1` for an example. ### Stream.iterate/2 (function) Emits a sequence of values, starting with `start_value`. Successive values are generated by calling `next_fun` on the previous value. ### Examples - Stream.iterate/2 (function) iex> Stream.iterate(1, &(&1 * 2)) |> Enum.take(5) [1, 2, 4, 8, 16] ### Stream.map/2 (function) Creates a stream that will apply the given function on enumeration. ### Examples - Stream.map/2 (function) iex> stream = Stream.map([1, 2, 3], fn x -> x * 2 end) iex> Enum.to_list(stream) [2, 4, 6] ### Stream.map_every/3 (function) Creates a stream that will apply the given function on every `nth` element from the enumerable. The first element is always passed to the given function. `nth` must be a non-negative integer. ### Examples - Stream.map_every/3 (function) iex> stream = Stream.map_every(1..10, 2, fn x -> x * 2 end) iex> Enum.to_list(stream) [2, 2, 6, 4, 10, 6, 14, 8, 18, 10] iex> stream = Stream.map_every([1, 2, 3, 4, 5], 1, fn x -> x * 2 end) iex> Enum.to_list(stream) [2, 4, 6, 8, 10] iex> stream = Stream.map_every(1..5, 0, fn x -> x * 2 end) iex> Enum.to_list(stream) [1, 2, 3, 4, 5] ### Stream.reject/2 (function) Creates a stream that will reject elements according to the given function on enumeration. ### Examples - Stream.reject/2 (function) iex> stream = Stream.reject([1, 2, 3], fn x -> rem(x, 2) == 0 end) iex> Enum.to_list(stream) [1, 3] ### Stream.repeatedly/1 (function) Returns a stream generated by calling `generator_fun` repeatedly. ### Examples - Stream.repeatedly/1 (function) # Although not necessary, let's seed the random algorithm iex> :rand.seed(:exsss, {1, 2, 3}) iex> Stream.repeatedly(&:rand.uniform/0) |> Enum.take(3) [0.5455598952593053, 0.6039309974353404, 0.6684893034823949] ### Stream.resource/3 (function) Emits a sequence of values for the given resource. Similar to `transform/3` but the initial accumulated value is computed lazily via `start_fun` and executes an `after_fun` at the end of enumeration (both in cases of success and failure). Successive values are generated by calling `next_fun` with the previous accumulator (the initial value being the result returned by `start_fun`) and it must return a tuple containing a list of elements to be emitted and the next accumulator. The enumeration finishes if it returns `{:halt, acc}`. As the function name suggests, this function is useful to stream values from resources. ### Examples - Stream.resource/3 (function) Stream.resource( fn -> File.open!("sample") end, fn file -> case IO.read(file, :line) do data when is_binary(data) -> {[data], file} _ -> {:halt, file} end end, fn file -> File.close(file) end ) iex> Stream.resource( ...> fn -> ...> {:ok, pid} = StringIO.open("string") ...> pid ...> end, ...> fn pid -> ...> case IO.getn(pid, "", 1) do ...> :eof -> {:halt, pid} ...> char -> {[char], pid} ...> end ...> end, ...> fn pid -> StringIO.close(pid) end ...> ) |> Enum.to_list() ["s", "t", "r", "i", "n", "g"] ### Stream.run/1 (function) Runs the given stream. This is useful when a stream needs to be run, for side effects, and there is no interest in its return result. ### Examples - Stream.run/1 (function) Open up a file, replace all `#` by `%` and stream to another file without loading the whole file in memory: File.stream!("/path/to/file") |> Stream.map(&String.replace(&1, "#", "%")) |> Stream.into(File.stream!("/path/to/other/file")) |> Stream.run() No computation will be done until we call one of the `Enum` functions or `run/1`. ### Stream.scan/2 (function) Creates a stream that applies the given function to each element, emits the result and uses the same result as the accumulator for the next computation. Uses the first element in the enumerable as the starting value. ### Examples - Stream.scan/2 (function) iex> stream = Stream.scan(1..5, &(&1 + &2)) iex> Enum.to_list(stream) [1, 3, 6, 10, 15] ### Stream.scan/3 (function) Creates a stream that applies the given function to each element, emits the result and uses the same result as the accumulator for the next computation. Uses the given `acc` as the starting value. ### Examples - Stream.scan/3 (function) iex> stream = Stream.scan(1..5, 0, &(&1 + &2)) iex> Enum.to_list(stream) [1, 3, 6, 10, 15] ### Stream.take/2 (function) Lazily takes the next `count` elements from the enumerable and stops enumeration. If a negative `count` is given, the last `count` values will be taken. For such, the collection is fully enumerated keeping up to `2 * count` elements in memory. Once the end of the collection is reached, the last `count` elements will be executed. Therefore, using a negative `count` on an infinite collection will never return. ### Examples - Stream.take/2 (function) iex> stream = Stream.take(1..100, 5) iex> Enum.to_list(stream) [1, 2, 3, 4, 5] iex> stream = Stream.take(1..100, -5) iex> Enum.to_list(stream) [96, 97, 98, 99, 100] iex> stream = Stream.cycle([1, 2, 3]) |> Stream.take(5) iex> Enum.to_list(stream) [1, 2, 3, 1, 2] ### Stream.take_every/2 (function) Creates a stream that takes every `nth` element from the enumerable. The first element is always included, unless `nth` is 0. `nth` must be a non-negative integer. ### Examples - Stream.take_every/2 (function) iex> stream = Stream.take_every(1..10, 2) iex> Enum.to_list(stream) [1, 3, 5, 7, 9] iex> stream = Stream.take_every([1, 2, 3, 4, 5], 1) iex> Enum.to_list(stream) [1, 2, 3, 4, 5] iex> stream = Stream.take_every(1..1000, 0) iex> Enum.to_list(stream) [] ### Stream.take_while/2 (function) Lazily takes elements of the enumerable while the given function returns a truthy value. ### Examples - Stream.take_while/2 (function) iex> stream = Stream.take_while(1..100, &(&1 <= 5)) iex> Enum.to_list(stream) [1, 2, 3, 4, 5] ### Stream.timer/1 (function) Creates a stream that emits a single value after `n` milliseconds. The value emitted is `0`. This operation will block the caller by the given time until the element is streamed. ### Examples - Stream.timer/1 (function) iex> Stream.timer(10) |> Enum.to_list() [0] ### Stream.transform/3 (function) Transforms an existing stream. It expects an accumulator and a function that receives two arguments, the stream element and the updated accumulator. It must return a tuple, where the first element is a new stream (often a list) or the atom `:halt`, and the second element is the accumulator to be used by the next element. Note: this function is equivalent to `Enum.flat_map_reduce/3`, except this function does not return the accumulator once the stream is processed. ### Examples - Stream.transform/3 (function) `Stream.transform/3` is useful as it can be used as the basis to implement many of the functions defined in this module. For example, we can implement `Stream.take(enum, n)` as follows: iex> enum = 1001..9999 iex> n = 3 iex> stream = Stream.transform(enum, 0, fn i, acc -> ...> if acc end) iex> Enum.to_list(stream) [1001, 1002, 1003] `Stream.transform/5` further generalizes this function to allow wrapping around resources. ### Stream.transform/4 (function) Similar to `Stream.transform/5`, except `last_fun` is not supplied. This function can be seen as a combination of `Stream.resource/3` with `Stream.transform/3`. ### Stream.transform/5 (function) Transforms an existing stream with function-based start, last, and after callbacks. Once transformation starts, `start_fun` is invoked to compute the initial accumulator. Then, for each element in the enumerable, the `reducer` function is invoked with the element and the accumulator, returning new elements and a new accumulator, as in `transform/3`. Once the collection is done, `last_fun` is invoked with the accumulator to emit any remaining items. Then `after_fun` is invoked, to close any resource, but not emitting any new items. `last_fun` is only invoked if the given enumerable terminates successfully (either because it is done or it halted itself). `after_fun` is always invoked, therefore `after_fun` must be the one used for closing resources. ### Stream.unfold/2 (function) Emits a sequence of values for the given accumulator. Successive values are generated by calling `next_fun` with the previous accumulator and it must return a tuple with the current value and next accumulator. The enumeration finishes if it returns `nil`. ### Examples - Stream.unfold/2 (function) To create a stream that counts down and stops before zero: iex> Stream.unfold(5, fn ...> 0 -> nil ...> n -> {n, n - 1} ...> end) |> Enum.to_list() [5, 4, 3, 2, 1] If `next_fun` never returns `nil`, the returned stream is *infinite*: iex> Stream.unfold(0, fn ...> n -> {n, n + 1} ...> end) |> Enum.take(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] iex> Stream.unfold(1, fn ...> n -> {n, n * 2} ...> end) |> Enum.take(10) [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] ### Stream.uniq/1 (function) Creates a stream that only emits elements if they are unique. Keep in mind that, in order to know if an element is unique or not, this function needs to store all unique values emitted by the stream. Therefore, if the stream is infinite, the number of elements stored will grow infinitely, never being garbage-collected. ### Examples - Stream.uniq/1 (function) iex> Stream.uniq([1, 2, 3, 3, 2, 1]) |> Enum.to_list() [1, 2, 3] ### Stream.uniq_by/2 (function) Creates a stream that only emits elements if they are unique, by removing the elements for which function `fun` returned duplicate elements. The function `fun` maps every element to a term which is used to determine if two elements are duplicates. Keep in mind that, in order to know if an element is unique or not, this function needs to store all unique values emitted by the stream. Therefore, if the stream is infinite, the number of elements stored will grow infinitely, never being garbage-collected. ### Example - Stream.uniq_by/2 (function) iex> Stream.uniq_by([{1, :x}, {2, :y}, {1, :z}], fn {x, _} -> x end) |> Enum.to_list() [{1, :x}, {2, :y}] iex> Stream.uniq_by([a: {:tea, 2}, b: {:tea, 2}, c: {:coffee, 1}], fn {_, y} -> y end) |> Enum.to_list() [a: {:tea, 2}, c: {:coffee, 1}] ### Stream.with_index/2 (function) Creates a stream where each element in the enumerable will be wrapped in a tuple alongside its index or according to a given function. May receive a function or an integer offset. If an `offset` is given, it will index from the given offset instead of from zero. If a `function` is given, it will index by invoking the function for each element and index (zero-based) of the enumerable. ### Examples - Stream.with_index/2 (function) iex> stream = Stream.with_index([1, 2, 3]) iex> Enum.to_list(stream) [{1, 0}, {2, 1}, {3, 2}] iex> stream = Stream.with_index([1, 2, 3], 3) iex> Enum.to_list(stream) [{1, 3}, {2, 4}, {3, 5}] iex> stream = Stream.with_index([1, 2, 3], fn x, index -> x + index end) iex> Enum.to_list(stream) [1, 3, 5] ### Stream.zip/1 (function) Zips corresponding elements from a finite collection of enumerables into one stream of tuples. The zipping finishes as soon as any enumerable in the given collection completes. ### Examples - Stream.zip/1 (function) iex> concat = Stream.concat(1..3, 4..6) iex> cycle = Stream.cycle(["foo", "bar", "baz"]) iex> Stream.zip([concat, [:a, :b, :c], cycle]) |> Enum.to_list() [{1, :a, "foo"}, {2, :b, "bar"}, {3, :c, "baz"}] ### Stream.zip/2 (function) Zips two enumerables together, lazily. Because a list of two-element tuples with atoms as the first tuple element is a keyword list (`Keyword`), zipping a first `Stream` of atoms with a second `Stream` of any kind creates a `Stream` that generates a keyword list. The zipping finishes as soon as either enumerable completes. ### Examples - Stream.zip/2 (function) iex> concat = Stream.concat(1..3, 4..6) iex> cycle = Stream.cycle([:a, :b, :c]) iex> Stream.zip(concat, cycle) |> Enum.to_list() [{1, :a}, {2, :b}, {3, :c}, {4, :a}, {5, :b}, {6, :c}] iex> Stream.zip(cycle, concat) |> Enum.to_list() [a: 1, b: 2, c: 3, a: 4, b: 5, c: 6] ### Stream.zip_with/2 (function) Lazily zips corresponding elements from a finite collection of enumerables into a new enumerable, transforming them with the `zip_fun` function as it goes. The first element from each of the enums in `enumerables` will be put into a list which is then passed to the one-arity `zip_fun` function. Then, the second elements from each of the enums are put into a list and passed to `zip_fun`, and so on until any one of the enums in `enumerables` completes. Returns a new enumerable with the results of calling `zip_fun`. ### Examples - Stream.zip_with/2 (function) iex> concat = Stream.concat(1..3, 4..6) iex> Stream.zip_with([concat, concat], fn [a, b] -> a + b end) |> Enum.to_list() [2, 4, 6, 8, 10, 12] iex> concat = Stream.concat(1..3, 4..6) iex> Stream.zip_with([concat, concat, 1..3], fn [a, b, c] -> a + b + c end) |> Enum.to_list() [3, 6, 9] ### Stream.zip_with/3 (function) Lazily zips corresponding elements from two enumerables into a new one, transforming them with the `zip_fun` function as it goes. The `zip_fun` will be called with the first element from `enumerable1` and the first element from `enumerable2`, then with the second element from each, and so on until either one of the enumerables completes. ### Examples - Stream.zip_with/3 (function) iex> concat = Stream.concat(1..3, 4..6) iex> Stream.zip_with(concat, concat, fn a, b -> a + b end) |> Enum.to_list() [2, 4, 6, 8, 10, 12] ### Stream.acc/0 (type) ### Stream.default/0 (type) ### Stream.element/0 (type) ### Stream.index/0 (type) Zero-based index. ### Stream.timer/0 (type) ### File (module) This module contains functions to manipulate files. Some of those functions are low-level, allowing the user to interact with files or IO devices, like `open/2`, `copy/3` and others. This module also provides higher level functions that work with filenames and have their naming based on Unix variants. For example, one can copy a file via `cp/3` and remove files and directories recursively via `rm_rf/1`. Paths given to functions in this module can be either relative to the current working directory (as returned by `File.cwd/0`), or absolute paths. Shell conventions like `~` are not expanded automatically. To use paths like `~/Downloads`, you can use `Path.expand/1` or `Path.expand/2` to expand your path to an absolute path. ### Encoding - File (module) In order to write and read files, one must use the functions in the `IO` module. By default, a file is opened in binary mode, which requires the functions `IO.binread/2` and `IO.binwrite/2` to interact with the file. A developer may pass `:utf8` as an option when opening the file, then the slower `IO.read/2` and `IO.write/2` functions must be used as they are responsible for doing the proper conversions and providing the proper data guarantees. Note that filenames when given as charlists in Elixir are always treated as UTF-8. In particular, we expect that the shell and the operating system are configured to use UTF-8 encoding. Binary filenames are considered raw and passed to the operating system as is. ### API - File (module) Most of the functions in this module return `:ok` or `{:ok, result}` in case of success, `{:error, reason}` otherwise. Those functions also have a variant that ends with `!` which returns the result (instead of the `{:ok, result}` tuple) in case of success or raises an exception in case it fails. For example: File.read("hello.txt") #=> {:ok, "World"} File.read("invalid.txt") #=> {:error, :enoent} File.read!("hello.txt") #=> "World" File.read!("invalid.txt") #=> raises File.Error In general, a developer should use the former in case they want to react if the file does not exist. The latter should be used when the developer expects their software to fail in case the file cannot be read (i.e. it is literally an exception). ### Processes and raw files - File (module) Every time a file is opened, Elixir spawns a new process. Writing to a file is equivalent to sending messages to the process that writes to the file descriptor. This means files can be passed between nodes and message passing guarantees they can write to the same file in a network. However, you may not always want to pay the price for this abstraction. In such cases, a file can be opened in `:raw` mode. The options `:read_ahead` and `:delayed_write` are also useful when operating on large files or working with files in tight loops. Check `:file.open/2` for more information about such options and other performance considerations. ### Seeking within a file - File (module) You may also use any of the functions from the [`:file`](`:file`) module to interact with files returned by Elixir. For example, to read from a specific position in a file, use `:file.pread/3`: File.write!("example.txt", "Eats, Shoots & Leaves") file = File.open!("example.txt") :file.pread(file, 15, 6) #=> {:ok, "Leaves"} Alternatively, if you need to keep track of the current position, use `:file.position/2` and `:file.read/2`: :file.position(file, 6) #=> {:ok, 6} :file.read(file, 6) #=> {:ok, "Shoots"} :file.position(file, {:cur, -12}) #=> {:ok, 0} :file.read(file, 4) #=> {:ok, "Eats"} ### File.cd/1 (function) Sets the current working directory. The current working directory is set for the BEAM globally. This can lead to race conditions if multiple processes are changing the current working directory concurrently. To run an external command in a given directory without changing the global current working directory, use the `:cd` option of `System.cmd/3` and `Port.open/2`. Returns `:ok` if successful, `{:error, reason}` otherwise. ### File.cd!/1 (function) The same as `cd/1`, but raises a `File.Error` exception if it fails. ### File.cd!/2 (function) Changes the current directory to the given `path`, executes the given function and then reverts back to the previous path regardless of whether there is an exception. The current working directory is temporarily set for the BEAM globally. This can lead to race conditions if multiple processes are changing the current working directory concurrently. To run an external command in a given directory without changing the global current working directory, use the `:cd` option of `System.cmd/3` and `Port.open/2`. Raises an error if retrieving or changing the current directory fails. ### File.chgrp/2 (function) Changes the group given by the group ID `gid` for a given `file`. Returns `:ok` on success, or `{:error, reason}` on failure. ### File.chgrp!/2 (function) Same as `chgrp/2`, but raises a `File.Error` exception in case of failure. Otherwise `:ok`. ### File.chmod/2 (function) Changes the `mode` for a given `file`. Returns `:ok` on success, or `{:error, reason}` on failure. ### Permissions - File.chmod/2 (function) File permissions are specified by adding together the following octal modes: * `0o400` - read permission: owner * `0o200` - write permission: owner * `0o100` - execute permission: owner * `0o040` - read permission: group * `0o020` - write permission: group * `0o010` - execute permission: group * `0o004` - read permission: other * `0o002` - write permission: other * `0o001` - execute permission: other For example, setting the mode `0o755` gives it write, read and execute permission to the owner and both read and execute permission to group and others. ### File.chmod!/2 (function) Same as `chmod/2`, but raises a `File.Error` exception in case of failure. Otherwise `:ok`. ### File.chown/2 (function) Changes the owner given by the user ID `uid` for a given `file`. Returns `:ok` on success, or `{:error, reason}` on failure. ### File.chown!/2 (function) Same as `chown/2`, but raises a `File.Error` exception in case of failure. Otherwise `:ok`. ### File.close/1 (function) Closes the file referenced by `io_device`. It mostly returns `:ok`, except for some severe errors such as out of memory. Note that if the option `:delayed_write` was used when opening the file, `close/1` might return an old write error and not even try to close the file. See `open/2` for more information. ### File.copy/3 (function) Copies the contents of `source` to `destination`. Both parameters can be a filename or an IO device opened with `open/2`. `bytes_count` specifies the number of bytes to copy, the default being `:infinity`. If file `destination` already exists, it is overwritten by the contents in `source`. Returns `{:ok, bytes_copied}` if successful, `{:error, reason}` otherwise. Compared to the `cp/3`, this function is more low-level, allowing a copy from device to device limited by a number of bytes. On the other hand, `cp/3` performs more extensive checks on both source and destination and it also preserves the file mode after copy. Typical error reasons are the same as in `open/2`, `read/1` and `write/3`. ### File.copy!/3 (function) The same as `copy/3` but raises a `File.CopyError` exception if it fails. Returns the `bytes_copied` otherwise. ### File.cp/3 (function) Copies the contents of `source_file` to `destination_file` preserving its modes. `source_file` must be a file or a symbolic link to one. `destination_file` must be a path to a non-existent file. If either is a directory, `{:error, :eisdir}` will be returned. The function returns `:ok` in case of success. Otherwise, it returns `{:error, reason}`. If you want to copy contents from an IO device to another device or do a straight copy from a source to a destination without preserving modes, check `copy/3` instead. Note: The command `cp` in Unix-like systems behaves differently depending on whether the destination is an existing directory or not. We have chosen to explicitly disallow copying to a destination which is a directory, and an error will be returned if tried. ### Options - File.cp/3 (function) * `:on_conflict` - (since v1.14.0) Invoked when a file already exists in the destination. The function receives arguments for `source_file` and `destination_file`. It should return `true` if the existing file should be overwritten, `false` if otherwise. The default callback returns `true`. On earlier versions, this callback could be given as third argument, but such behavior is now deprecated. ### File.cp!/3 (function) The same as `cp/3`, but raises a `File.CopyError` exception if it fails. Returns `:ok` otherwise. ### File.cp_r/3 (function) Copies the contents in `source` to `destination` recursively, maintaining the source directory structure and modes. If `source` is a file or a symbolic link to it, `destination` must be a path to an existent file, a symbolic link to one, or a path to a non-existent file. If `source` is a directory, or a symbolic link to it, then `destination` must be an existent `directory` or a symbolic link to one, or a path to a non-existent directory. If the source is a file, it copies `source` to `destination`. If the `source` is a directory, it copies the contents inside source into the `destination` directory. If a file already exists in the destination, it invokes the optional `on_conflict` callback given as an option. See "Options" for more information. This function may fail while copying files, in such cases, it will leave the destination directory in a dirty state, where file which have already been copied won't be removed. The function returns `{:ok, files_and_directories}` in case of success, `files_and_directories` lists all files and directories copied in no specific order. It returns `{:error, reason, file}` otherwise. Note: The command `cp` in Unix-like systems behaves differently depending on whether `destination` is an existing directory or not. We have chosen to explicitly disallow this behavior. If `source` is a `file` and `destination` is a directory, `{:error, :eisdir}` will be returned. ### Options - File.cp_r/3 (function) * `:on_conflict` - (since v1.14.0) Invoked when a file already exists in the destination. The function receives arguments for `source` and `destination`. It should return `true` if the existing file should be overwritten, `false` if otherwise. The default callback returns `true`. On earlier versions, this callback could be given as third argument, but such behavior is now deprecated. * `:dereference_symlinks` - (since v1.14.0) By default, this function will copy symlinks by creating symlinks that point to the same location. This option forces symlinks to be dereferenced and have their contents copied instead when set to `true`. If the dereferenced files do not exist, than the operation fails. The default is `false`. ### Examples - File.cp_r/3 (function) # Copies file "a.txt" to "b.txt" File.cp_r("a.txt", "b.txt") # Copies all files in "samples" to "tmp" File.cp_r("samples", "tmp") # Same as before, but asks the user how to proceed in case of conflicts File.cp_r("samples", "tmp", on_conflict: fn source, destination -> IO.gets("Overwriting #{destination} by #{source}. Type y to confirm. ") == "y\n" end) ### File.cp_r!/3 (function) The same as `cp_r/3`, but raises a `File.CopyError` exception if it fails. Returns the list of copied files otherwise. ### File.cwd/0 (function) Gets the current working directory. In rare circumstances, this function can fail on Unix-like systems. It may happen if read permissions do not exist for the parent directories of the current directory. For this reason, returns `{:ok, cwd}` in case of success, `{:error, reason}` otherwise. ### File.cwd!/0 (function) The same as `cwd/0`, but raises a `File.Error` exception if it fails. ### File.dir?/2 (function) Returns `true` if the given path is a directory. This function follows symbolic links, so if a symbolic link points to a directory, `true` is returned. ### Options - File.dir?/2 (function) The supported options are: * `:raw` - a single atom to bypass the file server and only check for the file locally ### Examples - File.dir?/2 (function) File.dir?("./test") #=> true File.dir?("test") #=> true File.dir?("/usr/bin") #=> true File.dir?("~/Downloads") #=> false "~/Downloads" |> Path.expand() |> File.dir?() #=> true ### File.exists?/2 (function) Returns `true` if the given path exists. It can be a regular file, directory, socket, symbolic link, named pipe, or device file. Returns `false` for symbolic links pointing to non-existing targets. ### Options - File.exists?/2 (function) The supported options are: * `:raw` - a single atom to bypass the file server and only check for the file locally ### Examples - File.exists?/2 (function) File.exists?("test/") #=> true File.exists?("missing.txt") #=> false File.exists?("/dev/null") #=> true ### File.ln/2 (function) Creates a hard link `new` to the file `existing`. Returns `:ok` if successful, `{:error, reason}` otherwise. If the operating system does not support hard links, returns `{:error, :enotsup}`. ### File.ln!/2 (function) Same as `ln/2` but raises a `File.LinkError` exception if it fails. Returns `:ok` otherwise. ### File.ln_s/2 (function) Creates a symbolic link `new` to the file or directory `existing`. Returns `:ok` if successful, `{:error, reason}` otherwise. If the operating system does not support symlinks, returns `{:error, :enotsup}`. ### File.ln_s!/2 (function) Same as `ln_s/2` but raises a `File.LinkError` exception if it fails. Returns `:ok` otherwise. ### File.ls/1 (function) Returns the list of files in the given directory. Hidden files are not ignored and the results are *not* sorted. Since directories are considered files by the file system, they are also included in the returned value. Returns `{:ok, files}` in case of success, `{:error, reason}` otherwise. ### File.ls!/1 (function) The same as `ls/1` but raises a `File.Error` exception in case of an error. ### File.lstat/2 (function) Returns information about the `path`. If the file is a symlink, sets the `type` to `:symlink` and returns a `File.Stat` struct for the link. For any other file, returns exactly the same values as `stat/2`. For more details, see `:file.read_link_info/2`. ### Options - File.lstat/2 (function) The accepted options are: * `:time` - configures how the file timestamps are returned The values for `:time` can be: * `:universal` - returns a `{date, time}` tuple in UTC (default) * `:local` - returns a `{date, time}` tuple using the machine time * `:posix` - returns the time as integer seconds since epoch Note: Since file times are stored in POSIX time format on most operating systems, it is faster to retrieve file information with the `time: :posix` option. ### File.lstat!/2 (function) Same as `lstat/2` but returns the `File.Stat` struct directly, or raises a `File.Error` exception if an error is returned. ### File.mkdir/1 (function) Tries to create the directory `path`. Missing parent directories are not created. Returns `:ok` if successful, or `{:error, reason}` if an error occurs. Typical error reasons are: * `:eacces` - missing search or write permissions for the parent directories of `path` * `:eexist` - there is already a file or directory named `path` * `:enoent` - a component of `path` does not exist * `:enospc` - there is no space left on the device * `:enotdir` - a component of `path` is not a directory; on some platforms, `:enoent` is returned instead ### File.mkdir!/1 (function) Same as `mkdir/1`, but raises a `File.Error` exception in case of failure. Otherwise `:ok`. ### File.mkdir_p/1 (function) Tries to create the directory `path`. Missing parent directories are created. Returns `:ok` if successful, or `{:error, reason}` if an error occurs. Typical error reasons are: * `:eacces` - missing search or write permissions for the parent directories of `path` * `:enospc` - there is no space left on the device * `:enotdir` - a component of `path` is not a directory ### File.mkdir_p!/1 (function) Same as `mkdir_p/1`, but raises a `File.Error` exception in case of failure. Otherwise `:ok`. ### File.open/2 (function) Opens the given `path`. `modes_or_function` can either be a list of modes or a function. If it's a list, it's considered to be a list of modes (that are documented below). If it's a function, then it's equivalent to calling `open(path, [], modes_or_function)`. See the documentation for `open/3` for more information on this function. The allowed modes: * `:binary` - opens the file in binary mode, disabling special handling of Unicode sequences (default mode). * `:read` - the file, which must exist, is opened for reading. * `:write` - the file is opened for writing. It is created if it does not exist. If the file does exist, and if write is not combined with read, the file will be truncated. * `:append` - the file will be opened for writing, and it will be created if it does not exist. Every write operation to a file opened with append will take place at the end of the file. * `:exclusive` - the file, when opened for writing, is created if it does not exist. If the file exists, open will return `{:error, :eexist}`. * `:charlist` - when this term is given, read operations on the file will return charlists rather than binaries. * `:compressed` - makes it possible to read or write gzip compressed files. The compressed option must be combined with either read or write, but not both. Note that the file size obtained with `stat/1` will most probably not match the number of bytes that can be read from a compressed file. * `:utf8` - this option denotes how data is actually stored in the disk file and makes the file perform automatic translation of characters to and from UTF-8. If data is sent to a file in a format that cannot be converted to the UTF-8 or if data is read by a function that returns data in a format that cannot cope with the character range of the data, an error occurs and the file will be closed. * `:delayed_write`, `:raw`, `:ram`, `:read_ahead`, `:sync`, `{:encoding, ...}`, `{:read_ahead, pos_integer}`, `{:delayed_write, non_neg_integer, non_neg_integer}` - for more information about these options see `:file.open/2`. This function returns: * `{:ok, io_device | file_descriptor}` - the file has been opened in the requested mode. We explore the differences between these two results in the following section * `{:error, reason}` - the file could not be opened due to `reason`. ### IO devices - File.open/2 (function) By default, this function returns an IO device. An `io_device` is a process which handles the file and you can interact with it using the functions in the `IO` module. By default, a file is opened in `:binary` mode, which requires the functions `IO.binread/2` and `IO.binwrite/2` to interact with the file. A developer may pass `:utf8` as a mode when opening the file and then all other functions from `IO` are available, since they work directly with Unicode data. Given the IO device is a file, if the owner process terminates, the file is closed and the process itself terminates too. If any process to which the `io_device` is linked terminates, the file will be closed and the process itself will be terminated. ### File descriptors - File.open/2 (function) When the `:raw` or `:ram` modes are given, this function returns a low-level file descriptors. This avoids creating a process but requires using the functions in the [`:file`](`:file`) module to interact with it. ### Examples - File.open/2 (function) {:ok, file} = File.open("foo.tar.gz", [:read, :compressed]) IO.read(file, :line) File.close(file) ### File.open/3 (function) Similar to `open/2` but expects a function as its last argument. The file is opened, given to the function as an argument and automatically closed after the function returns, regardless if there was an error when executing the function. Returns `{:ok, function_result}` in case of success, `{:error, reason}` otherwise. This function expects the file to be closed with success, which is usually the case unless the `:delayed_write` option is given. For this reason, we do not recommend passing `:delayed_write` to this function. ### Examples - File.open/3 (function) File.open("file.txt", [:read, :write], fn file -> IO.read(file, :line) end) See `open/2` for the list of available `modes`. ### File.open!/2 (function) Similar to `open/2` but raises a `File.Error` exception if the file could not be opened. Returns the IO device otherwise. See `open/2` for the list of available modes. ### File.open!/3 (function) Similar to `open/3` but raises a `File.Error` exception if the file could not be opened. If it succeeds opening the file, it returns the `function` result on the IO device. See `open/2` for the list of available `modes`. ### File.read/1 (function) Returns `{:ok, binary}`, where `binary` is a binary data object that contains the contents of `path`, or `{:error, reason}` if an error occurs. Typical error reasons: * `:enoent` - the file does not exist * `:eacces` - missing permission for reading the file, or for searching one of the parent directories * `:eisdir` - the named file is a directory * `:enotdir` - a component of the file name is not a directory; on some platforms, `:enoent` is returned instead * `:enomem` - there is not enough memory for the contents of the file You can use `:file.format_error/1` to get a descriptive string of the error. ### File.read!/1 (function) Returns a binary with the contents of the given filename, or raises a `File.Error` exception if an error occurs. ### File.read_link/1 (function) Reads the symbolic link at `path`. If `path` exists and is a symlink, returns `{:ok, target}`, otherwise returns `{:error, reason}`. For more details, see `:file.read_link/1`. Typical error reasons are: * `:einval` - path is not a symbolic link * `:enoent` - path does not exist * `:enotsup` - symbolic links are not supported on the current platform ### File.read_link!/1 (function) Same as `read_link/1` but returns the target directly, or raises a `File.Error` exception if an error is returned. ### File.regular?/2 (function) Returns `true` if the path is a regular file. This function follows symbolic links, so if a symbolic link points to a regular file, `true` is returned. ### Options - File.regular?/2 (function) The supported options are: * `:raw` - a single atom to bypass the file server and only check for the file locally ### Examples - File.regular?/2 (function) File.regular?(__ENV__.file) #=> true ### File.rename/2 (function) Renames the `source` file to `destination` file. It can be used to move files (and directories) between directories. If moving a file, you must fully specify the `destination` filename, it is not sufficient to simply specify its directory. Returns `:ok` in case of success, `{:error, reason}` otherwise. Note: The command `mv` in Unix-like systems behaves differently depending on whether `source` is a file and the `destination` is an existing directory. We have chosen to explicitly disallow this behavior. ### Examples - File.rename/2 (function) # Rename file "a.txt" to "b.txt" File.rename("a.txt", "b.txt") # Rename directory "samples" to "tmp" File.rename("samples", "tmp") ### File.rename!/2 (function) The same as `rename/2` but raises a `File.RenameError` exception if it fails. Returns `:ok` otherwise. ### File.rm/1 (function) Tries to delete the file `path`. Returns `:ok` if successful, or `{:error, reason}` if an error occurs. Note the file is deleted even if in read-only mode. Typical error reasons are: * `:enoent` - the file does not exist * `:eacces` - missing permission for the file or one of its parents * `:eperm` - the file is a directory and user is not super-user * `:enotdir` - a component of the file name is not a directory; on some platforms, `:enoent` is returned instead * `:einval` - filename had an improper type, such as tuple ### Examples - File.rm/1 (function) File.rm("file.txt") #=> :ok File.rm("tmp_dir/") #=> {:error, :eperm} ### File.rm!/1 (function) Same as `rm/1`, but raises a `File.Error` exception in case of failure. Otherwise `:ok`. ### File.rm_rf/1 (function) Removes files and directories recursively at the given `path`. Symlinks are not followed but simply removed, non-existing files are simply ignored (i.e. doesn't make this function fail). Returns `{:ok, files_and_directories}` with all files and directories removed in no specific order, `{:error, reason, file}` otherwise. ### Examples - File.rm_rf/1 (function) File.rm_rf("samples") #=> {:ok, ["samples", "samples/1.txt"]} File.rm_rf("unknown") #=> {:ok, []} ### File.rm_rf!/1 (function) Same as `rm_rf/1` but raises a `File.Error` exception in case of failures, otherwise the list of files or directories removed. ### File.rmdir/1 (function) Tries to delete the dir at `path`. Returns `:ok` if successful, or `{:error, reason}` if an error occurs. It returns `{:error, :eexist}` if the directory is not empty. ### Examples - File.rmdir/1 (function) File.rmdir("tmp_dir") #=> :ok File.rmdir("non_empty_dir") #=> {:error, :eexist} File.rmdir("file.txt") #=> {:error, :enotdir} ### File.rmdir!/1 (function) Same as `rmdir/1`, but raises a `File.Error` exception in case of failure. Otherwise `:ok`. ### File.stat/2 (function) Returns information about the `path`. If it exists, it returns a `{:ok, info}` tuple, where info is a `File.Stat` struct. Returns `{:error, reason}` with the same reasons as `read/1` if a failure occurs. ### Options - File.stat/2 (function) The accepted options are: * `:time` - configures how the file timestamps are returned The values for `:time` can be: * `:universal` - returns a `{date, time}` tuple in UTC (default) * `:local` - returns a `{date, time}` tuple using the same time zone as the machine * `:posix` - returns the time as integer seconds since epoch Note: Since file times are stored in POSIX time format on most operating systems, it is faster to retrieve file information with the `time: :posix` option. ### File.stat!/2 (function) Same as `stat/2` but returns the `File.Stat` directly, or raises a `File.Error` exception if an error is returned. ### File.stream!/2 (function) Shortcut for `File.stream!/3`. ### File.stream!/3 (function) Returns a `File.Stream` for the given `path` with the given `modes`. The stream implements both `Enumerable` and `Collectable` protocols, which means it can be used both for read and write. The `line_or_bytes` argument configures how the file is read when streaming, by `:line` (default) or by a given number of bytes. When using the `:line` option, CRLF line breaks (`"\r\n"`) are normalized to LF (`"\n"`). Similar to other file operations, a stream can be created in one node and forwarded to another node. Once the stream is opened in another node, a request will be sent to the creator node to spawn a process for file streaming. Operating the stream can fail on open for the same reasons as `File.open!/2`. Note that the file is automatically opened each time streaming begins. There is no need to pass `:read` and `:write` modes, as those are automatically set by Elixir. ### Raw files - File.stream!/3 (function) Since Elixir controls when the streamed file is opened, the underlying device cannot be shared and as such it is convenient to open the file in raw mode for performance reasons. Therefore, Elixir **will** open streams in `:raw` mode with the `:read_ahead` option if the stream is open in the same node as it is created and no encoding has been specified. This means any data streamed into the file must be converted to `t:iodata/0` type. If you pass, for example, `[encoding: :utf8]` or `[encoding: {:utf16, :little}]` in the modes parameter, the underlying stream will use `IO.write/2` and the `String.Chars` protocol to convert the data. See `IO.binwrite/2` and `IO.write/2` . One may also consider passing the `:delayed_write` option if the stream is meant to be written to under a tight loop. ### Byte order marks and read offset - File.stream!/3 (function) If you pass `:trim_bom` in the modes parameter, the stream will trim UTF-8, UTF-16 and UTF-32 byte order marks when reading from file. Note that this function does not try to discover the file encoding based on BOM. From Elixir v1.16.0, you may also pass a `:read_offset` that is skipped whenever enumerating the stream (if both `:read_offset` and `:trim_bom` are given, the offset is skipped after the BOM). ### Examples - File.stream!/3 (function) # Read a utf8 text file which may include BOM File.stream!("./test/test.txt", [:trim_bom, encoding: :utf8]) # Read in 2048 byte chunks rather than lines File.stream!("./test/test.data", 2048) See `Stream.run/1` for an example of streaming into a file. ### File.touch/2 (function) Updates modification time (mtime) and access time (atime) of the given file. The file is created if it doesn't exist. Requires datetime in UTC (as returned by `:erlang.universaltime()`) or an integer representing the POSIX timestamp (as returned by `System.os_time(:second)`). In Unix-like systems, changing the modification time may require you to be either `root` or the owner of the file. Having write access may not be enough. In those cases, touching the file the first time (to create it) will succeed, but touching an existing file with fail with `{:error, :eperm}`. ### Examples - File.touch/2 (function) File.touch("/tmp/a.txt", {{2018, 1, 30}, {13, 59, 59}}) #=> :ok File.touch("/fakedir/b.txt", {{2018, 1, 30}, {13, 59, 59}}) {:error, :enoent} File.touch("/tmp/a.txt", 1544519753) #=> :ok ### File.touch!/2 (function) Same as `touch/2` but raises a `File.Error` exception if it fails. Returns `:ok` otherwise. The file is created if it doesn't exist. Requires datetime in UTC (as returned by `:erlang.universaltime()`) or an integer representing the POSIX timestamp (as returned by `System.os_time(:second)`). ### Examples - File.touch!/2 (function) File.touch!("/tmp/a.txt", {{2018, 1, 30}, {13, 59, 59}}) #=> :ok File.touch!("/fakedir/b.txt", {{2018, 1, 30}, {13, 59, 59}}) ** (File.Error) could not touch "/fakedir/b.txt": no such file or directory File.touch!("/tmp/a.txt", 1544519753) ### File.write/3 (function) Writes `content` to the file `path`. The file is created if it does not exist. If it exists, the previous contents are overwritten. Returns `:ok` if successful, or `{:error, reason}` if an error occurs. `content` must be `iodata` (a list of bytes or a binary). Setting the encoding for this function has no effect. **Warning:** Every time this function is invoked, a file descriptor is opened and a new process is spawned to write to the file. For this reason, if you are doing multiple writes in a loop, opening the file via `File.open/2` and using the functions in `IO` to write to the file will yield much better performance than calling this function multiple times. Typical error reasons are: * `:enoent` - a component of the file name does not exist * `:enotdir` - a component of the file name is not a directory; on some platforms, `:enoent` is returned instead * `:enospc` - there is no space left on the device * `:eacces` - missing permission for writing the file or searching one of the parent directories * `:eisdir` - the named file is a directory Check `File.open/2` for other available options. ### File.write!/3 (function) Same as `write/3` but raises a `File.Error` exception if it fails. Returns `:ok` otherwise. ### File.write_stat/3 (function) Writes the given `File.Stat` back to the file system at the given path. Returns `:ok` or `{:error, reason}`. ### File.write_stat!/3 (function) Same as `write_stat/3` but raises a `File.Error` exception if it fails. Returns `:ok` otherwise. ### File.encoding_mode/0 (type) ### File.erlang_time/0 (type) ### File.file_descriptor/0 (type) ### File.io_device/0 (type) ### File.mode/0 (type) ### File.on_conflict_callback/0 (type) ### File.posix/0 (type) ### File.posix_time/0 (type) ### File.read_offset_mode/0 (type) ### File.stat_options/0 (type) ### File.stream_mode/0 (type) ### File.Stat (module) A struct that holds file information. In Erlang, this struct is represented by a `:file_info` record. Therefore this module also provides functions for converting between the Erlang record and the Elixir struct. Its fields are: * `size` - size of file in bytes. * `type` - `:device | :directory | :regular | :other | :symlink`; the type of the file. * `access` - `:read | :write | :read_write | :none`; the current system access to the file. * `atime` - the last time the file was read. * `mtime` - the last time the file was written. * `ctime` - the interpretation of this time field depends on the operating system. On Unix-like operating systems, it is the last time the file or the inode was changed. In Windows, it is the time of creation. * `mode` - the file permissions. * `links` - the number of links to this file. This is always 1 for file systems which have no concept of links. * `major_device` - identifies the file system where the file is located. In Windows, the number indicates a drive as follows: 0 means A:, 1 means B:, and so on. * `minor_device` - only valid for character devices on Unix-like systems. In all other cases, this field is zero. * `inode` - gives the inode number. On non-Unix-like file systems, this field will be zero. * `uid` - indicates the owner of the file. Will be zero for non-Unix-like file systems. * `gid` - indicates the group that owns the file. Will be zero for non-Unix-like file systems. The time type returned in `atime`, `mtime`, and `ctime` is dependent on the time type set in options. `{:time, type}` where type can be `:local`, `:universal`, or `:posix`. Default is `:universal`. ### File.Stat.from_record/1 (function) Converts a `:file_info` record into a `File.Stat`. ### File.Stat.to_record/1 (function) Converts a `File.Stat` struct to a `:file_info` record. ### File.Stat.t/0 (type) ### File.Stream (module) Defines a `File.Stream` struct returned by `File.stream!/3`. The following fields are public: * `path` - the file path * `modes` - the file modes * `raw` - a boolean indicating if bin functions should be used * `line_or_bytes` - if reading should read lines or a given number of bytes * `node` - the node the file belongs to ### File.Stream.t/0 (type) ### IO (module) Functions handling input/output (IO). Many functions in this module expect an IO device as an argument. An IO device must be a PID or an atom representing a process. For convenience, Elixir provides `:stdio` and `:stderr` as shortcuts to Erlang's `:standard_io` and `:standard_error`. The majority of the functions expect chardata. In case another type is given, functions will convert those types to string via the `String.Chars` protocol (as shown in typespecs). For more information on chardata, see the "IO data" section below. The functions of this module use UNIX-style naming where possible. ### IO devices - IO (module) An IO device may be an atom or a PID. In case it is an atom, the atom must be the name of a registered process. In addition, Elixir provides two shortcuts: * `:stdio` - a shortcut for `:standard_io`, which maps to the current `Process.group_leader/0` in Erlang * `:stderr` - a shortcut for the named process `:standard_error` provided in Erlang IO devices maintain their position, which means subsequent calls to any reading or writing functions will start from the place where the device was last accessed. The position of files can be changed using the `:file.position/2` function. ### IO data - IO (module) IO data is a data type that can be used as a more efficient alternative to binaries in certain situations. A term of type **IO data** is a binary or a list containing bytes (integers within the `0..255` range) or nested IO data. The type is recursive. Let's see an example of one of the possible IO data representing the binary `"hello"`: [?h, "el", ["l", [?o]]] The built-in `t:iodata/0` type is defined in terms of `t:iolist/0`. An IO list is the same as IO data but it doesn't allow for a binary at the top level (but binaries are still allowed in the list itself). ### Use cases for IO data - IO (module) IO data exists because often you need to do many append operations on smaller chunks of binaries in order to create a bigger binary. However, in Erlang and Elixir concatenating binaries will copy the concatenated binaries into a new binary. def email(username, domain) do username <> "@" <> domain end In this function, creating the email address will copy the `username` and `domain` binaries. Now imagine you want to use the resulting email inside another binary: def welcome_message(name, username, domain) do "Welcome #{name}, your email is: #{email(username, domain)}" end IO.puts(welcome_message("Meg", "meg", "example.com")) #=> "Welcome Meg, your email is: meg@example.com" Every time you concatenate binaries or use interpolation (`#{}`) you are making copies of those binaries. However, in many cases you don't need the complete binary while you create it, but only at the end to print it out or send it somewhere. In such cases, you can construct the binary by creating IO data: def email(username, domain) do [username, ?@, domain] end def welcome_message(name, username, domain) do ["Welcome ", name, ", your email is: ", email(username, domain)] end IO.puts(welcome_message("Meg", "meg", "example.com")) #=> "Welcome Meg, your email is: meg@example.com" Building IO data is cheaper than concatenating binaries. Concatenating multiple pieces of IO data just means putting them together inside a list since IO data can be arbitrarily nested, and that's a cheap and efficient operation. Most of the IO-based APIs, such as `:gen_tcp` and `IO`, receive IO data and write it to the socket directly without converting it to binary. One drawback of IO data is that you can't do things like pattern match on the first part of a piece of IO data like you can with a binary, because you usually don't know the shape of the IO data. In those cases, you may need to convert it to a binary by calling `iodata_to_binary/1`, which is reasonably efficient since it's implemented natively in C. Other functionality, like computing the length of IO data, can be computed directly on the iodata by calling `iodata_length/1`. ### Chardata - IO (module) Erlang and Elixir also have the idea of `t:chardata/0`. Chardata is very similar to IO data: the only difference is that integers in IO data represent bytes while integers in chardata represent Unicode code points. Bytes (`t:byte/0`) are integers within the `0..255` range, while Unicode code points (`t:char/0`) are integers within the `0..0x10FFFF` range. The `IO` module provides the `chardata_to_string/1` function for chardata as the "counter-part" of the `iodata_to_binary/1` function for IO data. If you try to use `iodata_to_binary/1` on chardata, it will result in an argument error. For example, let's try to put a code point that is not representable with one byte, like `?π`, inside IO data: IO.iodata_to_binary(["The symbol for pi is: ", ?π]) #=> ** (ArgumentError) argument error If we use chardata instead, it will work as expected: iex> IO.chardata_to_string(["The symbol for pi is: ", ?π]) "The symbol for pi is: π" ### IO.binread/2 (function) Reads from the IO `device`. The operation is Unicode unsafe. The `device` is iterated as specified by the `line_or_chars` argument: * if `line_or_chars` is an integer, it represents a number of bytes. The device is iterated by that number of bytes. This should be the preferred mode for reading non-textual inputs. * if `line_or_chars` is `:line`, the device is iterated line by line. CRFL newlines (" ") are automatically normalized to " ". * if `line_or_chars` is `:eof` (since v1.13), the device is iterated until `:eof`. If the device is already at the end, it returns `:eof` itself. It returns: * `data` - the output bytes * `:eof` - end of file was encountered * `{:error, reason}` - other (rare) error condition; for instance, `{:error, :estale}` if reading from an NFS volume Note: do not use this function on IO devices in Unicode mode as it will return the wrong result. ### IO.binstream/0 (function) Returns a raw, line-based `IO.Stream` on `:stdio`. The operation is Unicode unsafe. This is equivalent to: IO.binstream(:stdio, :line) ### IO.binstream/2 (function) Converts the IO `device` into an `IO.Stream`. The operation is Unicode unsafe. An `IO.Stream` implements both `Enumerable` and `Collectable`, allowing it to be used for both read and write. The `device` is iterated by the given number of bytes or line by line if `:line` is given. In case `:line` is given, " " is automatically normalized to " ". Passing the number of bytes should be the preferred mode for reading non-textual inputs. Note that an IO stream has side effects and every time you go over the stream you may get different results. This reads from the IO device as a raw binary. Therefore, do not use this function on IO devices in Unicode mode as it will return the wrong result. `binstream/0` has been introduced in Elixir v1.12.0, while `binstream/2` has been available since v1.0.0. ### IO.binwrite/2 (function) Writes `iodata` to the given `device`. This operation is meant to be used with "raw" devices that are started without an encoding. The given `iodata` is written as is to the device, without conversion. For more information on IO data, see the "IO data" section in the module documentation. Use `write/2` for devices with encoding. Important: do **not** use this function on IO devices in Unicode mode as it will write the wrong data. In particular, the standard IO device is set to Unicode by default, so writing to stdio with this function will likely result in the wrong data being sent down the wire. ### IO.chardata_to_string/1 (function) Converts chardata into a string. For more information about chardata, see the ["Chardata"](#module-chardata) section in the module documentation. In case the conversion fails, it raises an `UnicodeConversionError`. If a string is given, it returns the string itself. ### Examples - IO.chardata_to_string/1 (function) iex> IO.chardata_to_string([0x00E6, 0x00DF]) "æß" iex> IO.chardata_to_string([0x0061, "bc"]) "abc" iex> IO.chardata_to_string("string") "string" ### IO.getn/2 (function) Gets a number of bytes from IO device `:stdio`. If `:stdio` is a Unicode device, `count` implies the number of Unicode code points to be retrieved. Otherwise, `count` is the number of raw bytes to be retrieved. See `IO.getn/3` for a description of return values. ### IO.getn/3 (function) Gets a number of bytes from the IO `device`. If the IO `device` is a Unicode device, `count` implies the number of Unicode code points to be retrieved. Otherwise, `count` is the number of raw bytes to be retrieved. It returns: * `data` - the input characters * `:eof` - end of file was encountered * `{:error, reason}` - other (rare) error condition; for instance, `{:error, :estale}` if reading from an NFS volume ### IO.gets/2 (function) Reads a line from the IO `device`. It returns: * `data` - the characters in the line terminated by a line-feed (LF) or end of file (EOF) * `:eof` - end of file was encountered * `{:error, reason}` - other (rare) error condition; for instance, `{:error, :estale}` if reading from an NFS volume Trivia: `gets` is shorthand for `get string`. ### Examples - IO.gets/2 (function) To display "What is your name?" as a prompt and await user input: IO.gets("What is your name?\n") ### IO.inspect/2 (function) Inspects and writes the given `item` to the standard output. It's important to note that it returns the given `item` unchanged. This makes it possible to "spy" on values by inserting an `IO.inspect/2` call almost anywhere in your code, for example, in the middle of a pipeline. It enables pretty printing by default with width of 80 characters. The width can be changed by explicitly passing the `:width` option. The output can be decorated with a label, by providing the `:label` option to easily distinguish it from other `IO.inspect/2` calls. The label will be printed before the inspected `item`. See `Inspect.Opts` for a full list of remaining formatting options. To print to other IO devices, see `IO.inspect/3` ### Examples - IO.inspect/2 (function) IO.inspect(<<0, 1, 2>>, width: 40) Prints: <<0, 1, 2>> We can use the `:label` option to decorate the output: IO.inspect(1..100, label: "a wonderful range") Prints: a wonderful range: 1..100 The `:label` option is especially useful with pipelines: [1, 2, 3] |> IO.inspect(label: "before") |> Enum.map(&(&1 * 2)) |> IO.inspect(label: "after") |> Enum.sum() Prints: before: [1, 2, 3] after: [2, 4, 6] ### IO.inspect/3 (function) Inspects `item` according to the given options using the IO `device`. See `inspect/2` for a full list of options. ### IO.iodata_length/1 (function) Returns the size of an IO data. For more information about IO data, see the ["IO data"](#module-io-data) section in the module documentation. Inlined by the compiler. ### Examples - IO.iodata_length/1 (function) iex> IO.iodata_length([1, 2 | <<3, 4>>]) 4 ### IO.iodata_to_binary/1 (function) Converts IO data into a binary The operation is Unicode unsafe. Note that this function treats integers in the given IO data as raw bytes and does not perform any kind of encoding conversion. If you want to convert from a charlist to a UTF-8-encoded string, use `chardata_to_string/1` instead. For more information about IO data and chardata, see the ["IO data"](#module-io-data) section in the module documentation. If this function receives a binary, the same binary is returned. Inlined by the compiler. ### Examples - IO.iodata_to_binary/1 (function) iex> bin1 = <<1, 2, 3>> iex> bin2 = <<4, 5>> iex> bin3 = <<6>> iex> IO.iodata_to_binary([bin1, 1, [2, 3, bin2], 4 | bin3]) <<1, 2, 3, 1, 2, 3, 4, 5, 4, 6>> iex> bin = <<1, 2, 3>> iex> IO.iodata_to_binary(bin) <<1, 2, 3>> ### IO.puts/2 (function) Writes `item` to the given `device`, similar to `write/2`, but adds a newline at the end. By default, the `device` is the standard output. It returns `:ok` if it succeeds. Trivia: `puts` is shorthand for `put string`. ### Examples - IO.puts/2 (function) IO.puts("Hello World!") #=> Hello World! IO.puts(:stderr, "error") #=> error ### IO.read/2 (function) Reads from the IO `device`. The `device` is iterated as specified by the `line_or_chars` argument: * if `line_or_chars` is an integer, it represents a number of bytes. The device is iterated by that number of bytes. This should be the preferred mode for reading non-textual inputs. * if `line_or_chars` is `:line`, the device is iterated line by line. CRFL newlines (" ") are automatically normalized to " ". * if `line_or_chars` is `:eof` (since v1.13), the device is iterated until `:eof`. If the device is already at the end, it returns `:eof` itself. It returns: * `data` - the output characters * `:eof` - end of file was encountered * `{:error, reason}` - other (rare) error condition; for instance, `{:error, :estale}` if reading from an NFS volume ### IO.stream/0 (function) Returns a line-based `IO.Stream` on `:stdio`. This is equivalent to: IO.stream(:stdio, :line) ### IO.stream/2 (function) Converts the IO `device` into an `IO.Stream`. An `IO.Stream` implements both `Enumerable` and `Collectable`, allowing it to be used for both read and write. The `device` is iterated by the given number of characters or line by line if `:line` is given. In case `:line` is given, " " is automatically normalized to " ". This reads from the IO as UTF-8. Check out `IO.binstream/2` to handle the IO as a raw binary. Note that an IO stream has side effects and every time you go over the stream you may get different results. `stream/0` has been introduced in Elixir v1.12.0, while `stream/2` has been available since v1.0.0. ### Examples - IO.stream/2 (function) Here is an example on how we mimic an echo server from the command line: Enum.each(IO.stream(:stdio, :line), &IO.write(&1)) Another example where you might want to collect a user input every new line and break on an empty line, followed by removing redundant new line characters (`"\n"`): IO.stream(:stdio, :line) |> Enum.take_while(&(&1 != "\n")) |> Enum.map(&String.replace(&1, "\n", "")) ### IO.warn/1 (function) Writes a `message` to stderr, along with the current stacktrace. It returns `:ok` if it succeeds. Do not call this function at the tail of another function. Due to tail call optimization, a stacktrace entry would not be added and the stacktrace would be incorrectly trimmed. Therefore make sure at least one expression (or an atom such as `:ok`) follows the `IO.warn/1` call. ### Examples - IO.warn/1 (function) IO.warn("variable bar is unused") #=> warning: variable bar is unused #=> (iex) evaluator.ex:108: IEx.Evaluator.eval/4 ### IO.warn/2 (function) Writes a `message` to stderr, along with the given `stacktrace_info`. The `stacktrace_info` must be one of: * a `__STACKTRACE__`, where all entries in the stacktrace will be included in the error message * a `Macro.Env` structure (since v1.14.0), where a single stacktrace entry from the compilation environment will be used * a keyword list with at least the `:file` option representing a single stacktrace entry (since v1.14.0). The `:line`, `:column`, `:module`, and `:function` options are also supported This function notifies the compiler a warning was printed and emits a compiler diagnostic (`t:Code.diagnostic/1`). The diagnostic will include precise file and location information if a `Macro.Env` is given or those values have been passed as keyword list, but not for stacktraces, as they are often imprecise. It returns `:ok` if it succeeds. ### Examples - IO.warn/2 (function) IO.warn("variable bar is unused", module: MyApp, function: {:main, 1}, line: 4, file: "my_app.ex") #=> warning: variable bar is unused #=> my_app.ex:4: MyApp.main/1 ### IO.write/2 (function) Writes `chardata` to the given `device`. By default, the `device` is the standard output. ### Examples - IO.write/2 (function) IO.write("sample") #=> sample IO.write(:stderr, "error") #=> error ### IO.chardata/0 (type) ### IO.device/0 (type) ### IO.nodata/0 (type) ### IO.ANSI (module) Functionality to render ANSI escape sequences. [ANSI escape sequences](https://en.wikipedia.org/wiki/ANSI_escape_code) are characters embedded in text used to control formatting, color, and other output options on video text terminals. ANSI escapes are typically enabled on all Unix terminals. They are also available on Windows consoles from Windows 10, although it must be explicitly enabled for the current user in the registry by running the following command: reg add HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1 After running the command above, you must restart your current console. ### Examples - IO.ANSI (module) Because the ANSI escape sequences are embedded in text, the normal usage of these functions is to concatenate their output with text. formatted_text = IO.ANSI.blue_background() <> "Example" <> IO.ANSI.reset() IO.puts(formatted_text) A higher level and more convenient API is also available via `IO.ANSI.format/1`, where you use atoms to represent each ANSI escape sequence and by default checks if ANSI is enabled: IO.puts(IO.ANSI.format([:blue_background, "Example"])) In case ANSI is disabled, the ANSI escape sequences are simply discarded. ### IO.ANSI.black/0 (function) Sets foreground color to black. ### IO.ANSI.black_background/0 (function) Sets background color to black. ### IO.ANSI.blink_off/0 (function) Blink: off. ### IO.ANSI.blink_rapid/0 (function) Blink: rapid. MS-DOS ANSI.SYS; 150 per minute or more; not widely supported. ### IO.ANSI.blink_slow/0 (function) Blink: slow. Less than 150 per minute. ### IO.ANSI.blue/0 (function) Sets foreground color to blue. ### IO.ANSI.blue_background/0 (function) Sets background color to blue. ### IO.ANSI.bright/0 (function) Bright (increased intensity) or bold. ### IO.ANSI.clear/0 (function) Clears screen. ### IO.ANSI.clear_line/0 (function) Clears line. ### IO.ANSI.color/1 (function) Sets foreground color. ### IO.ANSI.color/3 (function) Sets the foreground color from individual RGB values. Valid values for each color are in the range 0 to 5. ### IO.ANSI.color_background/1 (function) Sets background color. ### IO.ANSI.color_background/3 (function) Sets the background color from individual RGB values. Valid values for each color are in the range 0 to 5. ### IO.ANSI.conceal/0 (function) Conceal. Not widely supported. ### IO.ANSI.crossed_out/0 (function) Crossed-out. Characters legible, but marked for deletion. Not widely supported. ### IO.ANSI.cursor/2 (function) Sends cursor to the absolute position specified by `line` and `column`. Line `0` and column `0` would mean the top left corner. ### IO.ANSI.cursor_down/1 (function) Sends cursor `lines` down. ### IO.ANSI.cursor_left/1 (function) Sends cursor `columns` to the left. ### IO.ANSI.cursor_right/1 (function) Sends cursor `columns` to the right. ### IO.ANSI.cursor_up/1 (function) Sends cursor `lines` up. ### IO.ANSI.cyan/0 (function) Sets foreground color to cyan. ### IO.ANSI.cyan_background/0 (function) Sets background color to cyan. ### IO.ANSI.default_background/0 (function) Default background color. ### IO.ANSI.default_color/0 (function) Default text color. ### IO.ANSI.enabled?/0 (function) Checks if ANSI coloring is supported and enabled on this machine. This function simply reads the configuration value for `:ansi_enabled` in the `:elixir` application. The value is by default `false` unless Elixir can detect during startup that both `stdout` and `stderr` are terminals. ### IO.ANSI.encircled/0 (function) Encircled. ### IO.ANSI.faint/0 (function) Faint (decreased intensity). Not widely supported. ### IO.ANSI.font_1/0 (function) Sets alternative font 1. ### IO.ANSI.font_2/0 (function) Sets alternative font 2. ### IO.ANSI.font_3/0 (function) Sets alternative font 3. ### IO.ANSI.font_4/0 (function) Sets alternative font 4. ### IO.ANSI.font_5/0 (function) Sets alternative font 5. ### IO.ANSI.font_6/0 (function) Sets alternative font 6. ### IO.ANSI.font_7/0 (function) Sets alternative font 7. ### IO.ANSI.font_8/0 (function) Sets alternative font 8. ### IO.ANSI.font_9/0 (function) Sets alternative font 9. ### IO.ANSI.format/2 (function) Formats a chardata-like argument by converting named ANSI sequences into actual ANSI codes. The named sequences are represented by atoms. It will also append an `IO.ANSI.reset/0` to the chardata when a conversion is performed. If you don't want this behavior, use `format_fragment/2`. An optional boolean parameter can be passed to enable or disable emitting actual ANSI codes. When `false`, no ANSI codes will be emitted. By default checks if ANSI is enabled using the `enabled?/0` function. An `ArgumentError` will be raised if an invalid ANSI code is provided. ### Examples - IO.ANSI.format/2 (function) iex> IO.ANSI.format(["Hello, ", :red, :bright, "world!"], true) [[[[[[], "Hello, "] | "\e[31m"] | "\e[1m"], "world!"] | "\e[0m"] ### IO.ANSI.format_fragment/2 (function) Formats a chardata-like argument by converting named ANSI sequences into actual ANSI codes. The named sequences are represented by atoms. An optional boolean parameter can be passed to enable or disable emitting actual ANSI codes. When `false`, no ANSI codes will be emitted. By default checks if ANSI is enabled using the `enabled?/0` function. ### Examples - IO.ANSI.format_fragment/2 (function) iex> IO.ANSI.format_fragment([:bright, ~c"Word"], true) [[[[[[] | "\e[1m"], 87], 111], 114], 100] ### IO.ANSI.framed/0 (function) Framed. ### IO.ANSI.green/0 (function) Sets foreground color to green. ### IO.ANSI.green_background/0 (function) Sets background color to green. ### IO.ANSI.home/0 (function) Sends cursor home. ### IO.ANSI.inverse/0 (function) Image: negative. Swap foreground and background. ### IO.ANSI.inverse_off/0 (function) Image: positive. Normal foreground and background. ### IO.ANSI.italic/0 (function) Italic: on. Not widely supported. Sometimes treated as inverse. ### IO.ANSI.light_black/0 (function) Sets foreground color to light black. ### IO.ANSI.light_black_background/0 (function) Sets background color to light black. ### IO.ANSI.light_blue/0 (function) Sets foreground color to light blue. ### IO.ANSI.light_blue_background/0 (function) Sets background color to light blue. ### IO.ANSI.light_cyan/0 (function) Sets foreground color to light cyan. ### IO.ANSI.light_cyan_background/0 (function) Sets background color to light cyan. ### IO.ANSI.light_green/0 (function) Sets foreground color to light green. ### IO.ANSI.light_green_background/0 (function) Sets background color to light green. ### IO.ANSI.light_magenta/0 (function) Sets foreground color to light magenta. ### IO.ANSI.light_magenta_background/0 (function) Sets background color to light magenta. ### IO.ANSI.light_red/0 (function) Sets foreground color to light red. ### IO.ANSI.light_red_background/0 (function) Sets background color to light red. ### IO.ANSI.light_white/0 (function) Sets foreground color to light white. ### IO.ANSI.light_white_background/0 (function) Sets background color to light white. ### IO.ANSI.light_yellow/0 (function) Sets foreground color to light yellow. ### IO.ANSI.light_yellow_background/0 (function) Sets background color to light yellow. ### IO.ANSI.magenta/0 (function) Sets foreground color to magenta. ### IO.ANSI.magenta_background/0 (function) Sets background color to magenta. ### IO.ANSI.no_underline/0 (function) Underline: none. ### IO.ANSI.normal/0 (function) Normal color or intensity. ### IO.ANSI.not_framed_encircled/0 (function) Not framed or encircled. ### IO.ANSI.not_italic/0 (function) Not italic. ### IO.ANSI.not_overlined/0 (function) Not overlined. ### IO.ANSI.overlined/0 (function) Overlined. ### IO.ANSI.primary_font/0 (function) Sets primary (default) font. ### IO.ANSI.red/0 (function) Sets foreground color to red. ### IO.ANSI.red_background/0 (function) Sets background color to red. ### IO.ANSI.reset/0 (function) Resets all attributes. ### IO.ANSI.reverse/0 (function) Image: negative. Swap foreground and background. ### IO.ANSI.reverse_off/0 (function) Image: positive. Normal foreground and background. ### IO.ANSI.syntax_colors/0 (function) Syntax colors to be used by `Inspect`. Those colors are used throughout Elixir's standard library, such as `dbg/2` and `IEx`. The colors can be changed by setting the `:ansi_syntax_colors` in the `:elixir` application configuration. Configuration for most built-in data types are supported: `:atom`, `:binary`, `:boolean`, `:charlist`, `:list`, `:map`, `:nil`, `:number`, `:string`, and `:tuple`. The default is: [ atom: :cyan boolean: :magenta, charlist: :yellow, nil: :magenta, number: :yellow, string: :green ] ### IO.ANSI.underline/0 (function) Underline: single. ### IO.ANSI.white/0 (function) Sets foreground color to white. ### IO.ANSI.white_background/0 (function) Sets background color to white. ### IO.ANSI.yellow/0 (function) Sets foreground color to yellow. ### IO.ANSI.yellow_background/0 (function) Sets background color to yellow. ### IO.ANSI.ansicode/0 (type) ### IO.ANSI.ansidata/0 (type) ### IO.ANSI.ansilist/0 (type) ### IO.Stream (module) Defines an `IO.Stream` struct returned by `IO.stream/2` and `IO.binstream/2`. The following fields are public: * `device` - the IO device * `raw` - a boolean indicating if bin functions should be used * `line_or_bytes` - if reading should read lines or a given number of bytes It is worth noting that an IO stream has side effects and every time you go over the stream you may get different results. ### IO.Stream.t/0 (type) ### OptionParser (module) Functions for parsing command line arguments. When calling a command, it's possible to pass command line options to modify what the command does. In this documentation, those are called "switches", in other situations they may be called "flags" or simply "options". A switch can be given a value, also called an "argument". The main function in this module is `parse/2`, which parses a list of command line options and arguments into a keyword list: iex> OptionParser.parse(["--debug"], strict: [debug: :boolean]) {[debug: true], [], []} `OptionParser` provides some conveniences out of the box, such as aliases and automatic handling of negation switches. The `parse_head/2` function is an alternative to `parse/2` which stops parsing as soon as it finds a value that is not a switch nor a value for a previous switch. This module also provides low-level functions, such as `next/2`, for parsing switches manually, as well as `split/1` and `to_argv/1` for parsing from and converting switches to strings. ### OptionParser.next/2 (function) Low-level function that parses one option. It accepts the same options as `parse/2` and `parse_head/2` as both functions are built on top of this function. This function may return: * `{:ok, key, value, rest}` - the option `key` with `value` was successfully parsed * `{:invalid, key, value, rest}` - the option `key` is invalid with `value` (returned when the value cannot be parsed according to the switch type) * `{:undefined, key, value, rest}` - the option `key` is undefined (returned in strict mode when the switch is unknown or on nonexistent atoms) * `{:error, rest}` - there are no switches at the head of the given `argv` ### OptionParser.parse/2 (function) Parses `argv` into a keyword list. It returns a three-element tuple with the form `{parsed, args, invalid}`, where: * `parsed` is a keyword list of parsed switches with `{switch_name, value}` tuples in it; `switch_name` is the atom representing the switch name while `value` is the value for that switch parsed according to `opts` (see the "Examples" section for more information) * `args` is a list of the remaining arguments in `argv` as strings * `invalid` is a list of invalid options as `{option_name, value}` where `option_name` is the raw option and `value` is `nil` if the option wasn't expected or the string value if the value didn't have the expected type for the corresponding option Elixir converts switches to underscored atoms, so `--source-path` becomes `:source_path`. This is done to better suit Elixir conventions. However, this means that switches can't contain underscores and switches that do contain underscores are always returned in the list of invalid switches. When parsing, it is common to list switches and their expected types: iex> OptionParser.parse(["--debug"], strict: [debug: :boolean]) {[debug: true], [], []} iex> OptionParser.parse(["--source", "lib"], strict: [source: :string]) {[source: "lib"], [], []} iex> OptionParser.parse( ...> ["--source-path", "lib", "test/enum_test.exs", "--verbose"], ...> strict: [source_path: :string, verbose: :boolean] ...> ) {[source_path: "lib", verbose: true], ["test/enum_test.exs"], []} We will explore the valid switches and operation modes of option parser below. ### Options - OptionParser.parse/2 (function) The following options are supported: * `:switches` or `:strict` - see the "Switch definitions" section below * `:allow_nonexistent_atoms` - see the "Parsing unknown switches" section below * `:aliases` - see the "Aliases" section below * `:return_separator` - see the "Return separator" section below ### Switch definitions - OptionParser.parse/2 (function) Switches can be specified via one of two options: * `:strict` - defines strict switches and their types. Any switch in `argv` that is not specified in the list is returned in the invalid options list. This is the preferred way to parse options. * `:switches` - defines switches and their types. This function still attempts to parse switches that are not in this list. Both these options accept a keyword list where the key is an atom defining the name of the switch and value is the `type` of the switch (see the "Types" section below for more information). Note that you should only supply the `:switches` or the `:strict` option. If you supply both, an `ArgumentError` exception will be raised. ### Types - OptionParser.parse/2 (function) Switches parsed by `OptionParser` may take zero or one arguments. The following switches types take no arguments: * `:boolean` - sets the value to `true` when given (see also the "Negation switches" section below) * `:count` - counts the number of times the switch is given The following switches take one argument: * `:integer` - parses the value as an integer * `:float` - parses the value as a float * `:string` - parses the value as a string If a switch can't be parsed according to the given type, it is returned in the invalid options list. ### Modifiers - OptionParser.parse/2 (function) Switches can be specified with modifiers, which change how they behave. The following modifiers are supported: * `:keep` - keeps duplicate elements instead of overriding them; works with all types except `:count`. Specifying `switch_name: :keep` assumes the type of `:switch_name` will be `:string`. To use `:keep` with a type other than `:string`, use a list as the type for the switch. For example: `[foo: [:integer, :keep]]`. ### Negation switches - OptionParser.parse/2 (function) In case a switch `SWITCH` is specified to have type `:boolean`, it may be passed as `--no-SWITCH` as well which will set the option to `false`: iex> OptionParser.parse(["--no-op", "path/to/file"], switches: [op: :boolean]) {[op: false], ["path/to/file"], []} ### Parsing unknown switches - OptionParser.parse/2 (function) When the `:switches` option is given, `OptionParser` will attempt to parse unknown switches. Switches without an argument will be set to `true`: iex> OptionParser.parse(["--debug"], switches: [key: :string]) {[debug: true], [], []} Even though we haven't specified `--debug` in the list of switches, it is part of the returned options. The same happens for switches followed by another switch: iex> OptionParser.parse(["--debug", "--ok"], switches: []) {[debug: true, ok: true], [], []} Switches followed by a value will be assigned the value, as a string: iex> OptionParser.parse(["--debug", "value"], switches: [key: :string]) {[debug: "value"], [], []} Since we cannot assert the type of the switch value, it is preferred to use the `:strict` option that accepts only known switches and always verify their types. If you do want to parse unknown switches, remember that Elixir converts switches to atoms. Since atoms are not garbage-collected, to avoid creating new ones, OptionParser by default only parses switches that translate to existing atoms. The code below discards the `--option-parser-example` switch because the `:option_parser_example` atom is never used anywhere: iex> OptionParser.parse(["--option-parser-example"], switches: []) {[], [], []} If a switch corresponds to an existing Elixir atom, whether from your code, a dependency or from Elixir itself, it will be accepted. However, it is best to not rely on external code, and always define the atoms you want to parse in the same module that calls `OptionParser` itself, as direct arguments to the `:switches` or `:strict` options. If you would like to parse all switches, regardless if they exist or not, you can force creation of atoms by passing `allow_nonexistent_atoms: true` as option. Use this option with care. It is only useful when you are building command-line applications that receive dynamically-named arguments and must be avoided in long-running systems. ### Aliases - OptionParser.parse/2 (function) A set of aliases can be specified in the `:aliases` option: iex> OptionParser.parse(["-d"], aliases: [d: :debug], strict: [debug: :boolean]) {[debug: true], [], []} ### Examples - OptionParser.parse/2 (function) Here are some examples of working with different types and modifiers: iex> OptionParser.parse(["--unlock", "path/to/file"], strict: [unlock: :boolean]) {[unlock: true], ["path/to/file"], []} iex> OptionParser.parse( ...> ["--unlock", "--limit", "0", "path/to/file"], ...> strict: [unlock: :boolean, limit: :integer] ...> ) {[unlock: true, limit: 0], ["path/to/file"], []} iex> OptionParser.parse(["--limit", "3"], strict: [limit: :integer]) {[limit: 3], [], []} iex> OptionParser.parse(["--limit", "xyz"], strict: [limit: :integer]) {[], [], [{"--limit", "xyz"}]} iex> OptionParser.parse(["--verbose"], switches: [verbose: :count]) {[verbose: 1], [], []} iex> OptionParser.parse(["-v", "-v"], aliases: [v: :verbose], strict: [verbose: :count]) {[verbose: 2], [], []} iex> OptionParser.parse(["--unknown", "xyz"], strict: []) {[], ["xyz"], [{"--unknown", nil}]} iex> OptionParser.parse( ...> ["--limit", "3", "--unknown", "xyz"], ...> switches: [limit: :integer] ...> ) {[limit: 3, unknown: "xyz"], [], []} iex> OptionParser.parse( ...> ["--unlock", "path/to/file", "--unlock", "path/to/another/file"], ...> strict: [unlock: :keep] ...> ) {[unlock: "path/to/file", unlock: "path/to/another/file"], [], []} ### Return separator - OptionParser.parse/2 (function) The separator `--` implies options should no longer be processed. By default, the separator is not returned as parts of the arguments, but that can be changed via the `:return_separator` option: iex> OptionParser.parse(["--", "lib"], return_separator: true, strict: []) {[], ["--", "lib"], []} iex> OptionParser.parse(["--no-halt", "--", "lib"], return_separator: true, switches: [halt: :boolean]) {[halt: false], ["--", "lib"], []} iex> OptionParser.parse(["script.exs", "--no-halt", "--", "foo"], return_separator: true, switches: [halt: :boolean]) {[{:halt, false}], ["script.exs", "--", "foo"], []} ### OptionParser.parse!/2 (function) The same as `parse/2` but raises an `OptionParser.ParseError` exception if any invalid options are given. If there are no errors, returns a `{parsed, rest}` tuple where: * `parsed` is the list of parsed switches (same as in `parse/2`) * `rest` is the list of arguments (same as in `parse/2`) ### Examples - OptionParser.parse!/2 (function) iex> OptionParser.parse!(["--debug", "path/to/file"], strict: [debug: :boolean]) {[debug: true], ["path/to/file"]} iex> OptionParser.parse!(["--limit", "xyz"], strict: [limit: :integer]) ** (OptionParser.ParseError) 1 error found! --limit : Expected type integer, got "xyz" iex> OptionParser.parse!(["--unknown", "xyz"], strict: []) ** (OptionParser.ParseError) 1 error found! --unknown : Unknown option iex> OptionParser.parse!( ...> ["-l", "xyz", "-f", "bar"], ...> switches: [limit: :integer, foo: :integer], ...> aliases: [l: :limit, f: :foo] ...> ) ** (OptionParser.ParseError) 2 errors found! -l : Expected type integer, got "xyz" -f : Expected type integer, got "bar" ### OptionParser.parse_head/2 (function) Similar to `parse/2` but only parses the head of `argv`; as soon as it finds a non-switch, it stops parsing. See `parse/2` for more information. ### Example - OptionParser.parse_head/2 (function) iex> OptionParser.parse_head( ...> ["--source", "lib", "test/enum_test.exs", "--verbose"], ...> switches: [source: :string, verbose: :boolean] ...> ) {[source: "lib"], ["test/enum_test.exs", "--verbose"], []} iex> OptionParser.parse_head( ...> ["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"], ...> switches: [source: :string, verbose: :boolean, unlock: :boolean] ...> ) {[verbose: true, source: "lib"], ["test/enum_test.exs", "--unlock"], []} ### OptionParser.parse_head!/2 (function) The same as `parse_head/2` but raises an `OptionParser.ParseError` exception if any invalid options are given. If there are no errors, returns a `{parsed, rest}` tuple where: * `parsed` is the list of parsed switches (same as in `parse_head/2`) * `rest` is the list of arguments (same as in `parse_head/2`) ### Examples - OptionParser.parse_head!/2 (function) iex> OptionParser.parse_head!( ...> ["--source", "lib", "path/to/file", "--verbose"], ...> switches: [source: :string, verbose: :boolean] ...> ) {[source: "lib"], ["path/to/file", "--verbose"]} iex> OptionParser.parse_head!( ...> ["--number", "lib", "test/enum_test.exs", "--verbose"], ...> strict: [number: :integer] ...> ) ** (OptionParser.ParseError) 1 error found! --number : Expected type integer, got "lib" iex> OptionParser.parse_head!( ...> ["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"], ...> strict: [verbose: :integer, source: :integer] ...> ) ** (OptionParser.ParseError) 2 errors found! --verbose : Missing argument of type integer --source : Expected type integer, got "lib" ### OptionParser.split/1 (function) Splits a string into `t:argv/0` chunks. This function splits the given `string` into a list of strings in a similar way to many shells. ### Examples - OptionParser.split/1 (function) iex> OptionParser.split("foo bar") ["foo", "bar"] iex> OptionParser.split("foo \"bar baz\"") ["foo", "bar baz"] ### OptionParser.to_argv/2 (function) Receives a key-value enumerable and converts it to `t:argv/0`. Keys must be atoms. Keys with `nil` value are discarded, boolean values are converted to `--key` or `--no-key` (if the value is `true` or `false`, respectively), and all other values are converted using `to_string/1`. It is advised to pass to `to_argv/2` the same set of `options` given to `parse/2`. Some switches can only be reconstructed correctly with the `:switches` information in hand. ### Examples - OptionParser.to_argv/2 (function) iex> OptionParser.to_argv(foo_bar: "baz") ["--foo-bar", "baz"] iex> OptionParser.to_argv(bool: true, bool: false, discarded: nil) ["--bool", "--no-bool"] Some switches will output different values based on the switches types: iex> OptionParser.to_argv([number: 2], switches: []) ["--number", "2"] iex> OptionParser.to_argv([number: 2], switches: [number: :count]) ["--number", "--number"] ### OptionParser.argv/0 (type) ### OptionParser.errors/0 (type) ### OptionParser.options/0 (type) ### OptionParser.parsed/0 (type) ### Path (module) This module provides conveniences for manipulating or retrieving file system paths. The functions in this module may receive chardata as arguments and will always return a string encoded in UTF-8. Chardata is a string or a list of characters and strings, see `t:IO.chardata/0`. If a binary is given, in whatever encoding, its encoding will be kept. The majority of the functions in this module do not interact with the file system, except for a few functions that require it (like `wildcard/2` and `expand/1`). ### Path.absname/1 (function) Converts the given path to an absolute one. Unlike `expand/1`, no attempt is made to resolve `..`, `.`, or `~`. ### Examples - Path.absname/1 (function) ### Unix-like operating systems - Path.absname/1 (function) Path.absname("foo") #=> "/usr/local/foo" Path.absname("../x") #=> "/usr/local/../x" ### Windows - Path.absname/1 (function) Path.absname("foo") #=> "D:/usr/local/foo" Path.absname("../x") #=> "D:/usr/local/../x" ### Path.absname/2 (function) Builds a path from `relative_to` to `path`. If `path` is already an absolute path, `relative_to` is ignored. See also `relative_to/3`. `relative_to` is either a path or an anonymous function, which is invoked only when necessary, that returns a path. Unlike `expand/2`, no attempt is made to resolve `..`, `.` or `~`. ### Examples - Path.absname/2 (function) iex> Path.absname("foo", "bar") "bar/foo" iex> Path.absname("../x", "bar") "bar/../x" iex> Path.absname("foo", fn -> "lazy" end) "lazy/foo" ### Path.basename/1 (function) Returns the last component of the path or the path itself if it does not contain any directory separators. ### Examples - Path.basename/1 (function) iex> Path.basename("foo") "foo" iex> Path.basename("foo/bar") "bar" iex> Path.basename("lib/module/submodule.ex") "submodule.ex" iex> Path.basename("/") "" ### Path.basename/2 (function) Returns the last component of `path` with the `extension` stripped. This function should be used to remove a specific extension which may or may not be there. ### Examples - Path.basename/2 (function) iex> Path.basename("~/foo/bar.ex", ".ex") "bar" iex> Path.basename("~/foo/bar.exs", ".ex") "bar.exs" iex> Path.basename("~/foo/bar.old.ex", ".ex") "bar.old" ### Path.dirname/1 (function) Returns the directory component of `path`. ### Examples - Path.dirname/1 (function) iex> Path.dirname("/foo/bar.ex") "/foo" iex> Path.dirname("/foo/bar/baz.ex") "/foo/bar" iex> Path.dirname("/foo/bar/") "/foo/bar" iex> Path.dirname("bar.ex") "." ### Path.expand/1 (function) Converts the path to an absolute one, expanding any `.` and `..` components and a leading `~`. If a relative path is provided it is expanded relatively to the current working directory. ### Examples - Path.expand/1 (function) Path.expand("/foo/bar/../baz") #=> "/foo/baz" Path.expand("foo/bar/../baz") #=> "$PWD/foo/baz" ### Path.expand/2 (function) Expands the path relative to the path given as the second argument expanding any `.` and `..` characters. If the path is already an absolute path, `relative_to` is ignored. Note that this function treats a `path` with a leading `~` as an absolute one. The second argument is first expanded to an absolute path. ### Examples - Path.expand/2 (function) # Assuming that the absolute path to baz is /quux/baz Path.expand("foo/bar/../bar", "baz") #=> "/quux/baz/foo/bar" Path.expand("foo/bar/../bar", "/baz") #=> "/baz/foo/bar" Path.expand("/foo/bar/../bar", "/baz") #=> "/foo/bar" ### Path.extname/1 (function) Returns the extension of the last component of `path`. For filenames starting with a dot and without an extension, it returns an empty string. See `basename/1` and `rootname/1` for related functions to extract information from paths. ### Examples - Path.extname/1 (function) iex> Path.extname("foo.erl") ".erl" iex> Path.extname("~/foo/bar") "" iex> Path.extname(".gitignore") "" ### Path.join/1 (function) Joins a list of paths. This function should be used to convert a list of paths to a path. Note that any trailing slash is removed when joining. Raises an error if the given list of paths is empty. ### Examples - Path.join/1 (function) iex> Path.join(["~", "foo"]) "~/foo" iex> Path.join(["foo"]) "foo" iex> Path.join(["/", "foo", "bar/"]) "/foo/bar" ### Path.join/2 (function) Joins two paths. The right path will always be expanded to its relative format and any trailing slash will be removed when joining. ### Examples - Path.join/2 (function) iex> Path.join("foo", "bar") "foo/bar" iex> Path.join("/foo", "/bar/") "/foo/bar" The functions in this module support chardata, so giving a list will treat it as a single entity: iex> Path.join("foo", ["bar", "fiz"]) "foo/barfiz" iex> Path.join(["foo", "bar"], "fiz") "foobar/fiz" Use `join/1` if you need to join a list of paths instead. ### Path.relative/1 (function) Forces the path to be a relative path. If an absolute path is given, it is stripped from its root component. ### Examples - Path.relative/1 (function) ### Unix-like operating systems - Path.relative/1 (function) Path.relative("/usr/local/bin") #=> "usr/local/bin" Path.relative("usr/local/bin") #=> "usr/local/bin" Path.relative("../usr/local/bin") #=> "../usr/local/bin" ### Windows - Path.relative/1 (function) Path.relative("D:/usr/local/bin") #=> "usr/local/bin" Path.relative("usr/local/bin") #=> "usr/local/bin" Path.relative("D:bar.ex") #=> "bar.ex" Path.relative("/bar/foo.ex") #=> "bar/foo.ex" ### Path.relative_to/3 (function) Returns the direct relative path from `path` in relation to `cwd`. In other words, this function attempts to return a path such that `Path.expand(result, cwd)` points to `path`. This function aims to return a relative path whenever possible, but that's not guaranteed: * If both paths are relative, a relative path is always returned * If both paths are absolute, a relative path may be returned if they share a common prefix. You can pass the `:force` option to force this function to traverse up, but even then a relative path is not guaranteed (for example, if the absolute paths belong to different drives on Windows) * If a mixture of paths are given, the result will always match the given `path` (the first argument) This function expands `.` and `..` entries without traversing the file system, so it assumes no symlinks between the paths. See `safe_relative_to/2` for a safer alternative. ### Options - Path.relative_to/3 (function) * `:force` - (boolean since v1.16.0) if `true` forces a relative path to be returned by traversing the path up. Except if the paths are in different volumes on Windows. Defaults to `false`. ### Examples - Path.relative_to/3 (function) ### With relative `cwd` - Path.relative_to/3 (function) If both paths are relative, a minimum path is computed: Path.relative_to("tmp/foo/bar", "tmp") #=> "foo/bar" Path.relative_to("tmp/foo/bar", "tmp/foo") #=> "bar" Path.relative_to("tmp/foo/bar", "tmp/bat") #=> "../foo/bar" If an absolute path is given with relative `cwd`, it is returned as: Path.relative_to("/usr/foo/bar", "tmp/bat") #=> "/usr/foo/bar" ### With absolute `cwd` - Path.relative_to/3 (function) If both paths are absolute, a relative is computed if possible, without traversing up: Path.relative_to("/usr/local/foo", "/usr/local") #=> "foo" Path.relative_to("/usr/local/foo", "/") #=> "usr/local/foo" Path.relative_to("/usr/local/foo", "/etc") #=> "/usr/local/foo" Path.relative_to("/usr/local/foo", "/usr/local/foo") #=> "." Path.relative_to("/usr/local/../foo", "/usr/foo") #=> "." Path.relative_to("/usr/local/../foo/bar", "/usr/foo") #=> "bar" If `:force` is set to `true` paths are traversed up: Path.relative_to("/usr", "/usr/local", force: true) #=> ".." Path.relative_to("/usr/foo", "/usr/local", force: true) #=> "../foo" Path.relative_to("/usr/../foo/bar", "/etc/foo", force: true) #=> "../../foo/bar" If a relative path is given, it is assumed to be relative to the given path, so the path is returned with "." and ".." expanded: Path.relative_to(".", "/usr/local") #=> "." Path.relative_to("foo", "/usr/local") #=> "foo" Path.relative_to("foo/../bar", "/usr/local") #=> "bar" Path.relative_to("foo/..", "/usr/local") #=> "." Path.relative_to("../foo", "/usr/local") #=> "../foo" ### Path.relative_to_cwd/2 (function) Convenience to get the path relative to the current working directory. If, for some reason, the current working directory cannot be retrieved, this function returns the given `path`. Check `relative_to/3` for the supported options. ### Path.rootname/1 (function) Returns the `path` with the `extension` stripped. ### Examples - Path.rootname/1 (function) iex> Path.rootname("/foo/bar") "/foo/bar" iex> Path.rootname("/foo/bar.ex") "/foo/bar" ### Path.rootname/2 (function) Returns the `path` with the `extension` stripped. This function should be used to remove a specific extension which may or may not be there. ### Examples - Path.rootname/2 (function) iex> Path.rootname("/foo/bar.erl", ".erl") "/foo/bar" iex> Path.rootname("/foo/bar.erl", ".ex") "/foo/bar.erl" ### Path.safe_relative/2 (function) Returns a relative path that is protected from directory-traversal attacks. The given relative path is sanitized by eliminating `..` and `.` components. This function checks that, after expanding those components, the path is still "safe". Paths are considered unsafe if either of these is true: * The path is not relative, such as `"/foo/bar"`. * A `..` component would make it so that the path would traverse up above the root of `relative_to`. * A symbolic link in the path points to something above the root of `cwd`. ### Examples - Path.safe_relative/2 (function) iex> Path.safe_relative("foo") {:ok, "foo"} iex> Path.safe_relative("deps/my_dep/app.beam") {:ok, "deps/my_dep/app.beam"} iex> Path.safe_relative("deps/my_dep/./build/../app.beam", File.cwd!()) {:ok, "deps/my_dep/app.beam"} iex> Path.safe_relative("my_dep/../..") :error iex> Path.safe_relative("/usr/local", File.cwd!()) :error ### Path.safe_relative_to/2 (function) Returns a relative path that is protected from directory-traversal attacks. See `safe_relative/2` for a non-deprecated version of this API. ### Path.split/1 (function) Splits the path into a list at the path separator. If an empty string is given, returns an empty list. On Windows, path is split on both `"\"` and `"/"` separators and the driver letter, if there is one, is always returned in lowercase. ### Examples - Path.split/1 (function) iex> Path.split("") [] iex> Path.split("foo") ["foo"] iex> Path.split("/foo/bar") ["/", "foo", "bar"] ### Path.type/1 (function) Returns the path type. ### Examples - Path.type/1 (function) ### Unix-like operating systems - Path.type/1 (function) Path.type("/") #=> :absolute Path.type("/usr/local/bin") #=> :absolute Path.type("usr/local/bin") #=> :relative Path.type("../usr/local/bin") #=> :relative Path.type("~/file") #=> :relative ### Windows - Path.type/1 (function) Path.type("D:/usr/local/bin") #=> :absolute Path.type("usr/local/bin") #=> :relative Path.type("D:bar.ex") #=> :volumerelative Path.type("/bar/foo.ex") #=> :volumerelative ### Path.wildcard/2 (function) Traverses paths according to the given `glob` expression and returns a list of matches. The wildcard looks like an ordinary path, except that the following "wildcard characters" are interpreted in a special way: * `?` - matches one character. * `*` - matches any number of characters up to the end of the filename, the next dot, or the next slash. * `**` - two adjacent `*`'s used as a single pattern will match all files and zero or more directories and subdirectories. * `[char1,char2,...]` - matches any of the characters listed; two characters separated by a hyphen will match a range of characters. Do not add spaces before and after the comma as it would then match paths containing the space character itself. * `{item1,item2,...}` - matches one of the alternatives. Do not add spaces before and after the comma as it would then match paths containing the space character itself. Other characters represent themselves. Only paths that have exactly the same character in the same position will match. Note that matching is case-sensitive: `"a"` will not match `"A"`. Directory separators must always be written as `/`, even on Windows. You may call `Path.expand/1` to normalize the path before invoking this function. A character preceded by `\\` loses its special meaning. Note that `\\` must be written as `\\\\` in a string literal. For example, `"\\\\?*"` will match any filename starting with `?.`. By default, the patterns `*` and `?` do not match files starting with a dot `.`. See the `:match_dot` option in the "Options" section below. ### Options - Path.wildcard/2 (function) * `:match_dot` - (boolean) if `false`, the special wildcard characters `*` and `?` will not match files starting with a dot (`.`). If `true`, files starting with a `.` will not be treated specially. Defaults to `false`. ### Examples - Path.wildcard/2 (function) Imagine you have a directory called `projects` with three Elixir projects inside of it: `elixir`, `ex_doc`, and `plug`. You can find all `.beam` files inside the `ebin` directory of each project as follows: Path.wildcard("projects/*/ebin/**/*.beam") If you want to search for both `.beam` and `.app` files, you could do: Path.wildcard("projects/*/ebin/**/*.{beam,app}") ### Path.t/0 (type) A path. ### Port (module) Functions for interacting with the external world through ports. Ports provide a mechanism to start operating system processes external to the Erlang VM and communicate with them via message passing. ### Example - Port (module) iex> port = Port.open({:spawn, "cat"}, [:binary]) iex> send(port, {self(), {:command, "hello"}}) iex> send(port, {self(), {:command, "world"}}) iex> flush() {#Port<0.1444>, {:data, "hello"}} {#Port<0.1444>, {:data, "world"}} iex> send(port, {self(), :close}) :ok iex> flush() {#Port<0.1444>, :closed} :ok In the example above, we have created a new port that executes the program `cat`. `cat` is a program available on Unix-like operating systems that receives data from multiple inputs and concatenates them in the output. After the port was created, we sent it two commands in the form of messages using `send/2`. The first command has the binary payload of "hello" and the second has "world". After sending those two messages, we invoked the IEx helper `flush()`, which printed all messages received from the port, in this case we got "hello" and "world" back. Note that the messages are in binary because we passed the `:binary` option when opening the port in `Port.open/2`. Without such option, it would have yielded a list of bytes. Once everything was done, we closed the port. Elixir provides many conveniences for working with ports and some drawbacks. We will explore those below. ### Message and function APIs - Port (module) There are two APIs for working with ports. It can be either asynchronous via message passing, as in the example above, or by calling the functions on this module. The messages supported by ports and their counterpart function APIs are listed below: * `{pid, {:command, binary}}` - sends the given data to the port. See `command/3`. * `{pid, :close}` - closes the port. Unless the port is already closed, the port will reply with `{port, :closed}` message once it has flushed its buffers and effectively closed. See `close/1`. * `{pid, {:connect, new_pid}}` - sets the `new_pid` as the new owner of the port. Once a port is opened, the port is linked and connected to the caller process and communication to the port only happens through the connected process. This message makes `new_pid` the new connected processes. Unless the port is dead, the port will reply to the old owner with `{port, :connected}`. See `connect/2`. On its turn, the port will send the connected process the following messages: * `{port, {:data, data}}` - data sent by the port * `{port, :closed}` - reply to the `{pid, :close}` message * `{port, :connected}` - reply to the `{pid, {:connect, new_pid}}` message * `{:EXIT, port, reason}` - exit signals in case the port crashes. If reason is not `:normal`, this message will only be received if the owner process is trapping exits ### Open mechanisms - Port (module) The port can be opened through four main mechanisms. As a short summary, prefer to using the `:spawn` and `:spawn_executable` options mentioned below. The other two options, `:spawn_driver` and `:fd` are for advanced usage within the VM. Also consider using `System.cmd/3` if all you want is to execute a program and retrieve its return value. > #### Windows argument splitting and untrusted arguments {: .warning} > > On Unix systems, arguments are passed to a new operating system > process as an array of strings but on Windows it is up to the child > process to parse them and some Windows programs may apply their own > rules, which are inconsistent with the standard C runtime `argv` parsing > > This is particularly troublesome when invoking `.bat` or `.com` files > as these run implicitly through `cmd.exe`, whose argument parsing is > vulnerable to malicious input and can be used to run arbitrary shell > commands. > > Therefore, if you are running on Windows and you execute batch > files or `.com` applications, you must not pass untrusted input as > arguments to the program. You may avoid accidentally executing them > by explicitly passing the extension of the program you want to run, > such as `.exe`, and double check the program is indeed not a batch > file or `.com` application. > > This affects both `spawn` and `spawn_executable`. ### spawn - Port (module) The `:spawn` tuple receives a binary that is going to be executed as a full invocation. For example, we can use it to invoke "echo hello" directly: iex> port = Port.open({:spawn, "echo hello"}, [:binary]) iex> flush() {#Port<0.1444>, {:data, "hello\n"}} `:spawn` will retrieve the program name from the argument and traverse your operating system `$PATH` environment variable looking for a matching program. Although the above is handy, it means it is impossible to invoke an executable that has whitespaces on its name or in any of its arguments. For those reasons, most times it is preferable to execute `:spawn_executable`. ### spawn_executable - Port (module) Spawn executable is a more restricted and explicit version of spawn. It expects full file paths to the executable you want to execute. If they are in your `$PATH`, they can be retrieved by calling `System.find_executable/1`: iex> path = System.find_executable("echo") iex> port = Port.open({:spawn_executable, path}, [:binary, args: ["hello world"]]) iex> flush() {#Port<0.1380>, {:data, "hello world\n"}} When using `:spawn_executable`, the list of arguments can be passed via the `:args` option as done above. For the full list of options, see the documentation for the Erlang function `:erlang.open_port/2`. ### fd - Port (module) The `:fd` name option allows developers to access `in` and `out` file descriptors used by the Erlang VM. You would use those only if you are reimplementing core part of the Runtime System, such as the `:user` and `:shell` processes. ### Zombie operating system processes - Port (module) A port can be closed via the `close/1` function or by sending a `{pid, :close}` message. However, if the VM crashes, a long-running program started by the port will have its stdin and stdout channels closed but **it won't be automatically terminated**. While most Unix command line tools will exit once its communication channels are closed, not all command line applications will do so. You can easily check this by starting the port and then shutting down the VM and inspecting your operating system to see if the port process is still running. While we encourage graceful termination by detecting if stdin/stdout has been closed, we do not always have control over how third-party software terminates. In those cases, you can wrap the application in a script that checks for stdin. Here is such script that has been verified to work on bash shells: #!/usr/bin/env bash # Start the program in the background exec "$@" & pid1=$! # Silence warnings from here on exec >/dev/null 2>&1 # Read from stdin in the background and # kill running program when stdin closes exec 0<&0 $( while read; do :; done kill -KILL $pid1 ) & pid2=$! # Clean up wait $pid1 ret=$? kill -KILL $pid2 exit $ret Note the program above hijacks stdin, so you won't be able to communicate with the underlying software via stdin (on the positive side, software that reads from stdin typically terminates when stdin closes). Now instead of: Port.open( {:spawn_executable, "/path/to/program"}, args: ["a", "b", "c"] ) You may invoke: Port.open( {:spawn_executable, "/path/to/wrapper"}, args: ["/path/to/program", "a", "b", "c"] ) ### Port.close/1 (function) Closes the `port`. For more information, see `:erlang.port_close/1`. Inlined by the compiler. ### Port.command/3 (function) Sends `data` to the port driver `port`. For more information, see `:erlang.port_command/3`. Inlined by the compiler. ### Port.connect/2 (function) Associates the `port` identifier with a `pid`. For more information, see `:erlang.port_connect/2`. Inlined by the compiler. ### Port.demonitor/2 (function) Demonitors the monitor identified by the given `reference`. If `monitor_ref` is a reference which the calling process obtained by calling `monitor/1`, that monitoring is turned off. If the monitoring is already turned off, nothing happens. See `:erlang.demonitor/2` for more information. Inlined by the compiler. ### Port.info/1 (function) Returns information about the `port` (or `nil` if the port is closed). For more information, see `:erlang.port_info/1`. ### Port.info/2 (function) Returns information about a specific field within the `port` (or `nil` if the port is closed). For more information, see `:erlang.port_info/2`. ### Port.list/0 (function) Returns a list of all ports in the current node. Inlined by the compiler. ### Port.monitor/1 (function) Starts monitoring the given `port` from the calling process. Once the monitored port process dies, a message is delivered to the monitoring process in the shape of: {:DOWN, ref, :port, object, reason} where: * `ref` is a monitor reference returned by this function; * `object` is either the `port` being monitored (when monitoring by port ID) or `{name, node}` (when monitoring by a port name); * `reason` is the exit reason. See `:erlang.monitor/2` for more information. Inlined by the compiler. ### Port.open/2 (function) Opens a port given a tuple `name` and a list of `options`. The module documentation above contains documentation and examples for the supported `name` values, summarized below: * `{:spawn, command}` - runs an external program. `command` must contain the program name and optionally a list of arguments separated by space. If passing programs or arguments with space in their name, use the next option. * `{:spawn_executable, filename}` - runs the executable given by the absolute file name `filename`. Arguments can be passed via the `:args` option. * `{:spawn_driver, command}` - spawns so-called port drivers. * `{:fd, fd_in, fd_out}` - accesses file descriptors, `fd_in` and `fd_out` opened by the VM. For more information and the list of options, see `:erlang.open_port/2`. Inlined by the compiler. ### Port.name/0 (type) ### StringIO (module) Controls an IO device process that wraps a string. A `StringIO` IO device can be passed as a "device" to most of the functions in the `IO` module. ### Examples - StringIO (module) iex> {:ok, pid} = StringIO.open("foo") iex> IO.read(pid, 2) "fo" ### StringIO.close/1 (function) Stops the IO device and returns the remaining input/output buffers. ### Examples - StringIO.close/1 (function) iex> {:ok, pid} = StringIO.open("in") iex> IO.write(pid, "out") iex> StringIO.close(pid) {:ok, {"in", "out"}} ### StringIO.contents/1 (function) Returns the current input/output buffers for the given IO device. ### Examples - StringIO.contents/1 (function) iex> {:ok, pid} = StringIO.open("in") iex> IO.write(pid, "out") iex> StringIO.contents(pid) {"in", "out"} ### StringIO.flush/1 (function) Flushes the output buffer and returns its current contents. ### Examples - StringIO.flush/1 (function) iex> {:ok, pid} = StringIO.open("in") iex> IO.write(pid, "out") iex> StringIO.flush(pid) "out" iex> StringIO.contents(pid) {"in", ""} ### StringIO.open/2 (function) Creates an IO device. `string` will be the initial input of the newly created device. `options_or_function` can be a keyword list of options or a function. If options are provided, the result will be `{:ok, pid}`, returning the IO device created. The option `:capture_prompt`, when set to `true`, causes prompts (which are specified as arguments to `IO.get*` functions) to be included in the device's output. If a function is provided, the device will be created and sent to the function. When the function returns, the device will be closed. The final result will be a tuple with `:ok` and the result of the function. ### Examples - StringIO.open/2 (function) iex> {:ok, pid} = StringIO.open("foo") iex> IO.gets(pid, ">") "foo" iex> StringIO.contents(pid) {"", ""} iex> {:ok, pid} = StringIO.open("foo", capture_prompt: true) iex> IO.gets(pid, ">") "foo" iex> StringIO.contents(pid) {"", ">"} iex> StringIO.open("foo", fn pid -> ...> input = IO.gets(pid, ">") ...> IO.write(pid, "The input was #{input}") ...> StringIO.contents(pid) ...> end) {:ok, {"", "The input was foo"}} ### StringIO.open/3 (function) Creates an IO device. `string` will be the initial input of the newly created device. The device will be created and sent to the function given. When the function returns, the device will be closed. The final result will be a tuple with `:ok` and the result of the function. ### Options - StringIO.open/3 (function) * `:capture_prompt` - if set to `true`, prompts (specified as arguments to `IO.get*` functions) are captured in the output. Defaults to `false`. * `:encoding` (since v1.10.0) - encoding of the IO device. Allowed values are `:unicode` (default) and `:latin1`. ### Examples - StringIO.open/3 (function) iex> StringIO.open("foo", [], fn pid -> ...> input = IO.gets(pid, ">") ...> IO.write(pid, "The input was #{input}") ...> StringIO.contents(pid) ...> end) {:ok, {"", "The input was foo"}} iex> StringIO.open("foo", [capture_prompt: true], fn pid -> ...> input = IO.gets(pid, ">") ...> IO.write(pid, "The input was #{input}") ...> StringIO.contents(pid) ...> end) {:ok, {"", ">The input was foo"}} ### System (module) The `System` module provides functions that interact directly with the VM or the host system. ### Time - System (module) The `System` module also provides functions that work with time, returning different times kept by the system with support for different time units. One of the complexities in relying on system times is that they may be adjusted. For example, when you enter and leave daylight saving time, the system clock will be adjusted, often adding or removing one hour. We call such changes "time warps". In order to understand how such changes may be harmful, imagine the following code: ### DO NOT DO THIS - System (module) prev = System.os_time() # ... execute some code ... next = System.os_time() diff = next - prev If, while the code is executing, the system clock changes, some code that executed in 1 second may be reported as taking over 1 hour! To address such concerns, the VM provides a monotonic time via `System.monotonic_time/0` which never decreases and does not leap: ### DO THIS - System (module) prev = System.monotonic_time() # ... execute some code ... next = System.monotonic_time() diff = next - prev Generally speaking, the VM provides three time measurements: * `os_time/0` - the time reported by the operating system (OS). This time may be adjusted forwards or backwards in time with no limitation; * `system_time/0` - the VM view of the `os_time/0`. The system time and operating system time may not match in case of time warps although the VM works towards aligning them. This time is not monotonic (i.e., it may decrease) as its behavior is configured [by the VM time warp mode](https://www.erlang.org/doc/apps/erts/time_correction.html#Time_Warp_Modes); * `monotonic_time/0` - a monotonically increasing time provided by the Erlang VM. This is not strictly monotonically increasing. Multiple sequential calls of the function may return the same value. The time functions in this module work in the `:native` unit (unless specified otherwise), which is operating system dependent. Most of the time, all calculations are done in the `:native` unit, to avoid loss of precision, with `convert_time_unit/3` being invoked at the end to convert to a specific time unit like `:millisecond` or `:microsecond`. See the `t:time_unit/0` type for more information. For a more complete rundown on the VM support for different times, see the [chapter on time and time correction](https://www.erlang.org/doc/apps/erts/time_correction.html) in the Erlang docs. ### System.argv/0 (function) Lists command line arguments. Returns the list of command line arguments passed to the program. ### System.argv/1 (function) Modifies command line arguments. Changes the list of command line arguments. Use it with caution, as it destroys any previous argv information. ### System.at_exit/1 (function) Registers a program exit handler function. Registers a function that will be invoked at the end of an Elixir script. A script is typically started via the command line via the `elixir` and `mix` executables. The handler always executes in a different process from the one it was registered in. As a consequence, any resources managed by the calling process (ETS tables, open files, and others) won't be available by the time the handler function is invoked. The function must receive the exit status code as an argument. If the VM terminates programmatically, via `System.stop/1`, `System.halt/1`, or exit signals, the `at_exit/1` callbacks are not guaranteed to be executed. ### System.build_info/0 (function) Elixir build information. Returns a map with the Elixir version, the Erlang/OTP release it was compiled with, a short Git revision hash and the date and time it was built. Every value in the map is a string, and these are: * `:build` - the Elixir version, short Git revision hash and Erlang/OTP release it was compiled with * `:date` - a string representation of the ISO8601 date and time it was built * `:otp_release` - OTP release it was compiled with * `:revision` - short Git revision hash. If Git was not available at building time, it is set to `""` * `:version` - the Elixir version One should not rely on the specific formats returned by each of those fields. Instead one should use specialized functions, such as `version/0` to retrieve the Elixir version and `otp_release/0` to retrieve the Erlang/OTP release. ### Examples - System.build_info/0 (function) iex> System.build_info() %{ build: "1.9.0-dev (772a00a0c) (compiled with Erlang/OTP 21)", date: "2018-12-24T01:09:21Z", otp_release: "21", revision: "772a00a0c", version: "1.9.0-dev" } ### System.cmd/3 (function) Executes the given `command` with `args`. `command` is expected to be an executable available in PATH unless an absolute path is given. `args` must be a list of binaries which the executable will receive as its arguments as is. This means that: * environment variables will not be interpolated * wildcard expansion will not happen (unless `Path.wildcard/2` is used explicitly) * arguments do not need to be escaped or quoted for shell safety This function returns a tuple containing the collected result and the command exit status. Internally, this function uses a `Port` for interacting with the outside world. However, if you plan to run a long-running program, ports guarantee stdin/stdout devices will be closed but it does not automatically terminate the program. The documentation for the `Port` module describes this problem and possible solutions under the "Zombie processes" section. > #### Windows argument splitting and untrusted arguments {: .warning} > > On Unix systems, arguments are passed to a new operating system > process as an array of strings but on Windows it is up to the child > process to parse them and some Windows programs may apply their own > rules, which are inconsistent with the standard C runtime `argv` parsing > > This is particularly troublesome when invoking `.bat` or `.com` files > as these run implicitly through `cmd.exe`, whose argument parsing is > vulnerable to malicious input and can be used to run arbitrary shell > commands. > > Therefore, if you are running on Windows and you execute batch > files or `.com` applications, you must not pass untrusted input as > arguments to the program. You may avoid accidentally executing them > by explicitly passing the extension of the program you want to run, > such as `.exe`, and double check the program is indeed not a batch > file or `.com` application. ### Examples - System.cmd/3 (function) iex> System.cmd("echo", ["hello"]) {"hello\n", 0} iex> System.cmd("echo", ["hello"], env: [{"MIX_ENV", "test"}]) {"hello\n", 0} If you want to stream the output to Standard IO as it arrives: iex> System.cmd("echo", ["hello"], into: IO.stream()) hello {%IO.Stream{}, 0} If you want to read lines: iex> System.cmd("echo", ["hello\nworld"], into: [], lines: 1024) {["hello", "world"], 0} ### Options - System.cmd/3 (function) * `:into` - injects the result into the given collectable, defaults to `""` * `:lines` - (since v1.15.0) reads the output by lines instead of in bytes. It expects a number of maximum bytes to buffer internally (1024 is a reasonable default). The collectable will be called with each finished line (regardless of buffer size) and without the EOL character * `:cd` - the directory to run the command in * `:env` - an enumerable of tuples containing environment key-value as binary. The child process inherits all environment variables from its parent process, the Elixir application, except those overwritten or cleared using this option. Specify a value of `nil` to clear (unset) an environment variable, which is useful for preventing credentials passed to the application from leaking into child processes * `:arg0` - sets the command arg0 * `:stderr_to_stdout` - redirects stderr to stdout when `true`, no effect if `use_stdio` is `false`. * `:use_stdio` - `true` by default, setting it to false allows direct interaction with the terminal from the callee * `:parallelism` - when `true`, the VM will schedule port tasks to improve parallelism in the system. If set to `false`, the VM will try to perform commands immediately, improving latency at the expense of parallelism. The default is `false`, and can be set on system startup by passing the [`+spp`](https://www.erlang.org/doc/man/erl.html#+spp) flag to `--erl`. Use `:erlang.system_info(:port_parallelism)` to check if enabled. ### Error reasons - System.cmd/3 (function) If invalid arguments are given, `ArgumentError` is raised by `System.cmd/3`. `System.cmd/3` also expects a strict set of options and will raise if unknown or invalid options are given. Furthermore, `System.cmd/3` may fail with one of the POSIX reasons detailed below: * `:system_limit` - all available ports in the Erlang emulator are in use * `:enomem` - there was not enough memory to create the port * `:eagain` - there are no more available operating system processes * `:enametoolong` - the external command given was too long * `:emfile` - there are no more available file descriptors (for the operating system process that the Erlang emulator runs in) * `:enfile` - the file table is full (for the entire operating system) * `:eacces` - the command does not point to an executable file * `:enoent` - the command does not point to an existing file ### Shell commands - System.cmd/3 (function) If you desire to execute a trusted command inside a shell, with pipes, redirecting and so on, please check `shell/2`. ### System.compiled_endianness/0 (function) Returns the endianness the system was compiled with. ### System.convert_time_unit/3 (function) Converts `time` from time unit `from_unit` to time unit `to_unit`. The result is rounded via the floor function. `convert_time_unit/3` accepts an additional time unit (other than the ones in the `t:time_unit/0` type) called `:native`. `:native` is the time unit used by the Erlang runtime system. It's determined when the runtime starts and stays the same until the runtime is stopped, but could differ the next time the runtime is started on the same machine. For this reason, you should use this function to convert `:native` time units to a predictable unit before you display them to humans. To determine how many seconds the `:native` unit represents in your current runtime, you can call this function to convert 1 second to the `:native` time unit: `System.convert_time_unit(1, :second, :native)`. ### System.cwd/0 (function) Current working directory. Returns the current working directory or `nil` if one is not available. ### System.cwd!/0 (function) Current working directory, exception on error. Returns the current working directory or raises `RuntimeError`. ### System.delete_env/1 (function) Deletes an environment variable. Removes the variable `varname` from the environment. ### System.endianness/0 (function) Returns the endianness. ### System.fetch_env/1 (function) Returns the value of the given environment variable or `:error` if not found. If the environment variable `varname` is set, then `{:ok, value}` is returned where `value` is a string. If `varname` is not set, `:error` is returned. ### Examples - System.fetch_env/1 (function) iex> System.fetch_env("PORT") {:ok, "4000"} iex> System.fetch_env("NOT_SET") :error ### System.fetch_env!/1 (function) Returns the value of the given environment variable or raises if not found. Same as `get_env/1` but raises instead of returning `nil` when the variable is not set. ### Examples - System.fetch_env!/1 (function) iex> System.fetch_env!("PORT") "4000" iex> System.fetch_env!("NOT_SET") ** (System.EnvError) could not fetch environment variable "NOT_SET" because it is not set ### System.find_executable/1 (function) Locates an executable on the system. This function looks up an executable program given its name using the environment variable PATH on Windows and Unix-like operating systems. It also considers the proper executable extension for each operating system, so for Windows it will try to lookup files with `.com`, `.cmd` or similar extensions. ### System.get_env/0 (function) Returns all system environment variables. The returned value is a map containing name-value pairs. Variable names and their values are strings. ### System.get_env/2 (function) Returns the value of the given environment variable. The returned value of the environment variable `varname` is a string. If the environment variable is not set, returns the string specified in `default` or `nil` if none is specified. ### Examples - System.get_env/2 (function) iex> System.get_env("PORT") "4000" iex> System.get_env("NOT_SET") nil iex> System.get_env("NOT_SET", "4001") "4001" ### System.get_pid/0 (function) Erlang VM process identifier. Returns the process identifier of the current Erlang emulator in the format most commonly used by the operating system environment. For more information, see `:os.getpid/0`. ### System.halt/1 (function) Immediately halts the Erlang runtime system. Terminates the Erlang runtime system without properly shutting down applications and ports. Please see `stop/1` for a careful shutdown of the system. `status` must be a non-negative integer, the atom `:abort` or a binary. * If an integer, the runtime system exits with the integer value which is returned to the operating system. * If `:abort`, the runtime system aborts producing a core dump, if that is enabled in the operating system. * If a string, an Erlang crash dump is produced with status as slogan, and then the runtime system exits with status code 1. Note that on many platforms, only the status codes 0-255 are supported by the operating system. For more information, see `:erlang.halt/1`. ### Examples - System.halt/1 (function) System.halt(0) System.halt(1) System.halt(:abort) ### System.monotonic_time/0 (function) Returns the current monotonic time in the `:native` time unit. This time is monotonically increasing and starts in an unspecified point in time. This is not strictly monotonically increasing. Multiple sequential calls of the function may return the same value. Inlined by the compiler. ### System.monotonic_time/1 (function) Returns the current monotonic time in the given time unit. This time is monotonically increasing and starts in an unspecified point in time. ### System.no_halt/0 (function) Checks if the system will halt or not at the end of ARGV processing. ### System.no_halt/1 (function) Marks if the system should halt or not at the end of ARGV processing. ### System.os_time/0 (function) Returns the current operating system (OS) time. The result is returned in the `:native` time unit. This time may be adjusted forwards or backwards in time with no limitation and is not monotonic. Inlined by the compiler. ### System.os_time/1 (function) Returns the current operating system (OS) time in the given time `unit`. This time may be adjusted forwards or backwards in time with no limitation and is not monotonic. ### System.otp_release/0 (function) Returns the Erlang/OTP release number. ### System.pid/0 (function) Returns the operating system PID for the current Erlang runtime system instance. Returns a string containing the (usually) numerical identifier for a process. On Unix-like operating systems, this is typically the return value of the `getpid()` system call. On Windows, the process ID as returned by the `GetCurrentProcessId()` system call is used. ### Examples - System.pid/0 (function) System.pid() ### System.put_env/1 (function) Sets multiple environment variables. Sets a new value for each environment variable corresponding to each `{key, value}` pair in `enum`. Keys and non-nil values are automatically converted to charlists. `nil` values erase the given keys. Overall, this is a convenience wrapper around `put_env/2` and `delete_env/2` with support for different key and value formats. ### System.put_env/2 (function) Sets an environment variable value. Sets a new `value` for the environment variable `varname`. ### System.restart/0 (function) Restarts all applications in the Erlang runtime system. All applications are taken down smoothly, all code is unloaded, and all ports are closed before the system starts all applications once again. ### Examples - System.restart/0 (function) System.restart() ### System.schedulers/0 (function) Returns the number of schedulers in the VM. ### System.schedulers_online/0 (function) Returns the number of schedulers online in the VM. ### System.shell/2 (function) Executes the given `command` in the OS shell. It uses `sh` for Unix-like systems and `cmd` for Windows. > #### Watch out {: .warning} > > Use this function with care. In particular, **never > pass untrusted user input to this function**, as the user would be > able to perform "command injection attacks" by executing any code > directly on the machine. Generally speaking, prefer to use `cmd/3` > over this function. ### Examples - System.shell/2 (function) iex> System.shell("echo hello") {"hello\n", 0} If you want to stream the output to Standard IO as it arrives: iex> System.shell("echo hello", into: IO.stream()) hello {%IO.Stream{}, 0} ### Options - System.shell/2 (function) It accepts the same options as `cmd/3` (except for `arg0`). It also accepts the following exclusive options: * `:close_stdin` (since v1.14.1) - if the stdin should be closed on Unix systems, forcing any command that waits on stdin to immediately terminate. Defaults to false. ### System.stacktrace/0 (function) Deprecated mechanism to retrieve the last exception stacktrace. It always return an empty list. ### System.stop/1 (function) Asynchronously and carefully stops the Erlang runtime system. All applications are taken down smoothly, all code is unloaded, and all ports are closed before the system terminates by calling `halt/1`. `status` must be a non-negative integer or a binary. * If an integer, the runtime system exits with the integer value which is returned to the operating system. On many platforms, only the status codes 0-255 are supported by the operating system. * If a binary, an Erlang crash dump is produced with status as slogan, and then the runtime system exits with status code 1. Note this function is asynchronous and the current process will continue executing after this function is invoked. In case you want to block the current process until the system effectively shuts down, you can invoke `Process.sleep(:infinity)`. ### Examples - System.stop/1 (function) System.stop(0) System.stop(1) ### System.system_time/0 (function) Returns the current system time in the `:native` time unit. It is the VM view of the `os_time/0`. They may not match in case of time warps although the VM works towards aligning them. This time is not monotonic. Inlined by the compiler. ### System.system_time/1 (function) Returns the current system time in the given time unit. It is the VM view of the `os_time/0`. They may not match in case of time warps although the VM works towards aligning them. This time is not monotonic. ### System.time_offset/0 (function) Returns the current time offset between the Erlang VM monotonic time and the Erlang VM system time. The result is returned in the `:native` time unit. See `time_offset/1` for more information. Inlined by the compiler. ### System.time_offset/1 (function) Returns the current time offset between the Erlang VM monotonic time and the Erlang VM system time. The result is returned in the given time unit `unit`. The returned offset, added to an Erlang monotonic time (for instance, one obtained with `monotonic_time/1`), gives the Erlang system time that corresponds to that monotonic time. ### System.tmp_dir/0 (function) Writable temporary directory. Returns a writable temporary directory. Searches for directories in the following order: 1. the directory named by the TMPDIR environment variable 2. the directory named by the TEMP environment variable 3. the directory named by the TMP environment variable 4. `C:\TMP` on Windows or `/tmp` on Unix-like operating systems 5. as a last resort, the current working directory Returns `nil` if none of the above are writable. ### System.tmp_dir!/0 (function) Writable temporary directory, exception on error. Same as `tmp_dir/0` but raises `RuntimeError` instead of returning `nil` if no temp dir is set. ### System.trap_signal/3 (function) Traps the given `signal` to execute the `fun`. > #### Avoid setting traps in libraries {: .warning} > > Trapping signals may have strong implications > on how a system shuts down and behaves in production and > therefore it is extremely discouraged for libraries to > set their own traps. Instead, they should redirect users > to configure them themselves. The only cases where it is > acceptable for libraries to set their own traps is when > using Elixir in script mode, such as in `.exs` files and > via Mix tasks. An optional `id` that uniquely identifies the function can be given, otherwise a unique one is automatically generated. If a previously registered `id` is given, this function returns an error tuple. The `id` can be used to remove a registered signal by calling `untrap_signal/2`. The given `fun` receives no arguments and it must return `:ok`. It returns `{:ok, id}` in case of success, `{:error, :already_registered}` in case the id has already been registered for the given signal, or `{:error, :not_sup}` in case trapping exists is not supported by the current OS. The first time a signal is trapped, it will override the default behavior from the operating system. If the same signal is trapped multiple times, subsequent functions given to `trap_signal` will execute *first*. In other words, you can consider each function is prepended to the signal handler. By default, the Erlang VM register traps to the three signals: * `:sigstop` - gracefully shuts down the VM with `stop/0` * `:sigquit` - halts the VM via `halt/0` * `:sigusr1` - halts the VM via status code of 1 Therefore, if you add traps to the signals above, the default behavior above will be executed after all user signals. ### Implementation notes - System.trap_signal/3 (function) All signals run from a single process. Therefore, blocking the `fun` will block subsequent traps. It is also not possible to add or remove traps from within a trap itself. Internally, this functionality is built on top of `:os.set_signal/2`. When you register a trap, Elixir automatically sets it to `:handle` and it reverts it back to `:default` once all traps are removed (except for `:sigquit`, `:sigterm`, and `:sigusr1` which are always handled). If you or a library call `:os.set_signal/2` directly, it may disable Elixir traps (or Elixir may override your configuration). ### System.unique_integer/1 (function) Generates and returns an integer that is unique in the current runtime instance. "Unique" means that this function, called with the same list of `modifiers`, will never return the same integer more than once on the current runtime instance. If `modifiers` is `[]`, then a unique integer (that can be positive or negative) is returned. Other modifiers can be passed to change the properties of the returned integer: * `:positive` - the returned integer is guaranteed to be positive. * `:monotonic` - the returned integer is monotonically increasing. This means that, on the same runtime instance (but even on different processes), integers returned using the `:monotonic` modifier will always be strictly less than integers returned by successive calls with the `:monotonic` modifier. All modifiers listed above can be combined; repeated modifiers in `modifiers` will be ignored. Inlined by the compiler. ### System.untrap_signal/2 (function) Removes a previously registered `signal` with `id`. ### System.user_home/0 (function) User home directory. Returns the user home directory (platform independent). ### System.user_home!/0 (function) User home directory, exception on error. Same as `user_home/0` but raises `RuntimeError` instead of returning `nil` if no user home is set. ### System.version/0 (function) Elixir version information. Returns Elixir's version as binary. ### System.signal/0 (type) ### System.time_unit/0 (type) The time unit to be passed to functions like `monotonic_time/1` and others. The `:second`, `:millisecond`, `:microsecond` and `:nanosecond` time units controls the return value of the functions that accept a time unit. A time unit can also be a strictly positive integer. In this case, it represents the "parts per second": the time will be returned in `1 / parts_per_second` seconds. For example, using the `:millisecond` time unit is equivalent to using `1000` as the time unit (as the time will be returned in 1/1000 seconds - milliseconds). ### Calendar (behaviour) This module defines the responsibilities for working with calendars, dates, times and datetimes in Elixir. It defines types and the minimal implementation for a calendar behaviour in Elixir. The goal of the calendar features in Elixir is to provide a base for interoperability rather than a full-featured datetime API. For the actual date, time and datetime structs, see `Date`, `Time`, `NaiveDateTime`, and `DateTime`. Types for year, month, day, and more are *overspecified*. For example, the `t:month/0` type is specified as an integer instead of `1..12`. This is because different calendars may have a different number of days per month. ### Calendar.compatible_calendars?/2 (function) Returns `true` if two calendars have the same moment of starting a new day, `false` otherwise. If two calendars are not compatible, we can only convert datetimes and times between them. If they are compatible, this means that we can also convert dates as well as naive datetimes between them. ### Calendar.date_to_string/3 (callback) Converts the date into a string according to the calendar. ### Calendar.datetime_to_string/11 (callback) Converts the datetime (with time zone) into a string according to the calendar. ### Calendar.day_of_era/3 (callback) Calculates the day and era from the given `year`, `month`, and `day`. ### Calendar.day_of_week/4 (callback) Calculates the day of the week from the given `year`, `month`, and `day`. `starting_on` represents the starting day of the week. All calendars must support at least the `:default` value. They may also support other values representing their days of the week. ### Calendar.day_of_year/3 (callback) Calculates the day of the year from the given `year`, `month`, and `day`. ### Calendar.day_rollover_relative_to_midnight_utc/0 (callback) Define the rollover moment for the calendar. This is the moment, in your calendar, when the current day ends and the next day starts. The result of this function is used to check if two calendars roll over at the same time of day. If they do not, we can only convert datetimes and times between them. If they do, this means that we can also convert dates as well as naive datetimes between them. This day fraction should be in its most simplified form possible, to make comparisons fast. ### Examples - Calendar.day_rollover_relative_to_midnight_utc/0 (callback) * If in your calendar a new day starts at midnight, return `{0, 1}`. * If in your calendar a new day starts at sunrise, return `{1, 4}`. * If in your calendar a new day starts at noon, return `{1, 2}`. * If in your calendar a new day starts at sunset, return `{3, 4}`. ### Calendar.days_in_month/2 (callback) Returns how many days there are in the given month of the given year. ### Calendar.get_time_zone_database/0 (function) Gets the current time zone database. ### Calendar.iso_days_to_beginning_of_day/1 (callback) Converts the given `t:iso_days/0` to the first moment of the day. ### Calendar.iso_days_to_end_of_day/1 (callback) Converts the given `t:iso_days/0` to the last moment of the day. ### Calendar.leap_year?/1 (callback) Returns `true` if the given year is a leap year. A leap year is a year of a longer length than normal. The exact meaning is up to the calendar. A calendar must return `false` if it does not support the concept of leap years. ### Calendar.months_in_year/1 (callback) Returns how many months there are in the given year. ### Calendar.naive_datetime_from_iso_days/1 (callback) Converts `t:iso_days/0` to the calendar's datetime format. ### Calendar.naive_datetime_to_iso_days/7 (callback) Converts the datetime (without time zone) into the `t:iso_days/0` format. ### Calendar.naive_datetime_to_string/7 (callback) Converts the naive datetime (without time zone) into a string according to the calendar. ### Calendar.parse_date/1 (callback) Parses the string representation for a date returned by `c:date_to_string/3` into a date tuple. ### Calendar.parse_naive_datetime/1 (callback) Parses the string representation for a naive datetime returned by `c:naive_datetime_to_string/7` into a naive datetime tuple. The given string may contain a timezone offset but it is ignored. ### Calendar.parse_time/1 (callback) Parses the string representation for a time returned by `c:time_to_string/4` into a time tuple. ### Calendar.parse_utc_datetime/1 (callback) Parses the string representation for a datetime returned by `c:datetime_to_string/11` into a datetime tuple. The returned datetime must be in UTC. The original `utc_offset` it was written in must be returned in the result. ### Calendar.put_time_zone_database/1 (function) Sets the current time zone database. ### Calendar.quarter_of_year/3 (callback) Calculates the quarter of the year from the given `year`, `month`, and `day`. ### Calendar.shift_date/4 (callback) Shifts date by given duration according to its calendar. ### Calendar.shift_naive_datetime/8 (callback) Shifts naive datetime by given duration according to its calendar. ### Calendar.shift_time/5 (callback) Shifts time by given duration according to its calendar. ### Calendar.strftime/3 (function) Formats the given date, time, or datetime into a string. The datetime can be any of the `Calendar` types (`Time`, `Date`, `NaiveDateTime`, and `DateTime`) or any map, as long as they contain all of the relevant fields necessary for formatting. For example, if you use `%Y` to format the year, the datetime must have the `:year` field. Therefore, if you pass a `Time`, or a map without the `:year` field to a format that expects `%Y`, an error will be raised. Examples of common usage: iex> Calendar.strftime(~U[2019-08-26 13:52:06.0Z], "%y-%m-%d %I:%M:%S %p") "19-08-26 01:52:06 PM" iex> Calendar.strftime(~U[2019-08-26 13:52:06.0Z], "%a, %B %d %Y") "Mon, August 26 2019" ### User Options - Calendar.strftime/3 (function) * `:preferred_datetime` - a string for the preferred format to show datetimes, it can't contain the `%c` format and defaults to `"%Y-%m-%d %H:%M:%S"` if the option is not received * `:preferred_date` - a string for the preferred format to show dates, it can't contain the `%x` format and defaults to `"%Y-%m-%d"` if the option is not received * `:preferred_time` - a string for the preferred format to show times, it can't contain the `%X` format and defaults to `"%H:%M:%S"` if the option is not received * `:am_pm_names` - a function that receives either `:am` or `:pm` and returns the name of the period of the day, if the option is not received it defaults to a function that returns `"am"` and `"pm"`, respectively * `:month_names` - a function that receives a number and returns the name of the corresponding month, if the option is not received it defaults to a function that returns the month names in English * `:abbreviated_month_names` - a function that receives a number and returns the abbreviated name of the corresponding month, if the option is not received it defaults to a function that returns the abbreviated month names in English * `:day_of_week_names` - a function that receives a number and returns the name of the corresponding day of week, if the option is not received it defaults to a function that returns the day of week names in English * `:abbreviated_day_of_week_names` - a function that receives a number and returns the abbreviated name of the corresponding day of week, if the option is not received it defaults to a function that returns the abbreviated day of week names in English ### Formatting syntax - Calendar.strftime/3 (function) The formatting syntax for the `string_format` argument is a sequence of characters in the following format: % where: * `%`: indicates the start of a formatted section * ` `: set the padding (see below) * ` `: a number indicating the minimum size of the formatted section * ` `: the format itself (see below) ### Accepted padding options - Calendar.strftime/3 (function) * `-`: no padding, removes all padding from the format * `_`: pad with spaces * `0`: pad with zeroes ### Accepted string formats - Calendar.strftime/3 (function) The accepted formats for `string_format` are: Format | Description | Examples (in ISO) :----- | :-----------------------------------------------------------------------| :------------------------ a | Abbreviated name of day | Mon A | Full name of day | Monday b | Abbreviated month name | Jan B | Full month name | January c | Preferred date+time representation | 2018-10-17 12:34:56 d | Day of the month | 01, 31 f | Microseconds *(does not support width and padding modifiers)* | 000000, 999999, 0123 H | Hour using a 24-hour clock | 00, 23 I | Hour using a 12-hour clock | 01, 12 j | Day of the year | 001, 366 m | Month | 01, 12 M | Minute | 00, 59 p | "AM" or "PM" (noon is "PM", midnight as "AM") | AM, PM P | "am" or "pm" (noon is "pm", midnight as "am") | am, pm q | Quarter | 1, 2, 3, 4 s | Number of seconds since the Epoch, 1970-01-01 00:00:00+0000 (UTC) | 1565888877 S | Second | 00, 59, 60 u | Day of the week | 1 (Monday), 7 (Sunday) x | Preferred date (without time) representation | 2018-10-17 X | Preferred time (without date) representation | 12:34:56 y | Year as 2-digits | 01, 01, 86, 18 Y | Year | -0001, 0001, 1986 z | +hhmm/-hhmm time zone offset from UTC (empty string if naive) | +0300, -0530 Z | Time zone abbreviation (empty string if naive) | CET, BRST % | Literal "%" character | % Any other character will be interpreted as an invalid format and raise an error. ### Examples - Calendar.strftime/3 (function) Without user options: iex> Calendar.strftime(~U[2019-08-26 13:52:06.0Z], "%y-%m-%d %I:%M:%S %p") "19-08-26 01:52:06 PM" iex> Calendar.strftime(~U[2019-08-26 13:52:06.0Z], "%a, %B %d %Y") "Mon, August 26 2019" iex> Calendar.strftime(~U[2020-04-02 13:52:06.0Z], "%B %-d, %Y") "April 2, 2020" iex> Calendar.strftime(~U[2019-08-26 13:52:06.0Z], "%c") "2019-08-26 13:52:06" With user options: iex> Calendar.strftime(~U[2019-08-26 13:52:06.0Z], "%c", preferred_datetime: "%H:%M:%S %d-%m-%y") "13:52:06 26-08-19" iex> Calendar.strftime( ...> ~U[2019-08-26 13:52:06.0Z], ...> "%A", ...> day_of_week_names: fn day_of_week -> ...> {"segunda-feira", "terça-feira", "quarta-feira", "quinta-feira", ...> "sexta-feira", "sábado", "domingo"} ...> |> elem(day_of_week - 1) ...> end ...>) "segunda-feira" iex> Calendar.strftime( ...> ~U[2019-08-26 13:52:06.0Z], ...> "%B", ...> month_names: fn month -> ...> {"січень", "лютий", "березень", "квітень", "травень", "червень", ...> "липень", "серпень", "вересень", "жовтень", "листопад", "грудень"} ...> |> elem(month - 1) ...> end ...>) "серпень" ### Calendar.time_from_day_fraction/1 (callback) Converts `t:day_fraction/0` to the calendar's time format. ### Calendar.time_to_day_fraction/4 (callback) Converts the given time to the `t:day_fraction/0` format. ### Calendar.time_to_string/4 (callback) Converts the time into a string according to the calendar. ### Calendar.truncate/2 (function) Returns a microsecond tuple truncated to a given precision (`:microsecond`, `:millisecond`, or `:second`). ### Calendar.valid_date?/3 (callback) Should return `true` if the given date describes a proper date in the calendar. ### Calendar.valid_time?/4 (callback) Should return `true` if the given time describes a proper time in the calendar. ### Calendar.year_of_era/3 (callback) Calculates the year and era from the given `year`. ### Calendar.calendar/0 (type) A calendar implementation. ### Calendar.date/0 (type) Any map or struct that contains the date fields. ### Calendar.datetime/0 (type) Any map or struct that contains the datetime fields. ### Calendar.day/0 (type) ### Calendar.day_fraction/0 (type) The internal time format is used when converting between calendars. It represents time as a fraction of a day (starting from midnight). `parts_in_day` specifies how much of the day is already passed, while `parts_per_day` signifies how many parts are there in a day. ### Calendar.day_of_era/0 (type) A tuple representing the `day` and the `era`. ### Calendar.day_of_week/0 (type) ### Calendar.era/0 (type) ### Calendar.hour/0 (type) ### Calendar.iso_days/0 (type) The internal date format that is used when converting between calendars. This is the number of days including the fractional part that has passed of the last day since `0000-01-01+00:00T00:00.000000` in ISO 8601 notation (also known as *midnight 1 January BC 1* of the proleptic Gregorian calendar). ### Calendar.microsecond/0 (type) Microseconds with stored precision. The precision represents the number of digits that must be used when representing the microseconds to external format. If the precision is `0`, it means microseconds must be skipped. ### Calendar.minute/0 (type) ### Calendar.month/0 (type) ### Calendar.naive_datetime/0 (type) Any map or struct that contains the naive datetime fields. ### Calendar.second/0 (type) ### Calendar.std_offset/0 (type) The time zone standard offset in ISO seconds (typically not zero in summer times). It must be added to `t:utc_offset/0` to get the total offset from UTC used for "wall time". ### Calendar.time/0 (type) Any map or struct that contains the time fields. ### Calendar.time_zone/0 (type) The time zone ID according to the IANA tz database (for example, `Europe/Zurich`). ### Calendar.time_zone_database/0 (type) Specifies the time zone database for calendar operations. Many functions in the `DateTime` module require a time zone database. By default, this module uses the default time zone database returned by `Calendar.get_time_zone_database/0`, which defaults to `Calendar.UTCOnlyTimeZoneDatabase`. This database only handles `Etc/UTC` datetimes and returns `{:error, :utc_only_time_zone_database}` for any other time zone. Other time zone databases (including ones provided by packages) can be configured as default either via configuration: config :elixir, :time_zone_database, CustomTimeZoneDatabase or by calling `Calendar.put_time_zone_database/1`. See `Calendar.TimeZoneDatabase` for more information on custom time zone databases. ### Calendar.utc_offset/0 (type) The time zone UTC offset in ISO seconds for standard time. See also `t:std_offset/0`. ### Calendar.week/0 (type) ### Calendar.year/0 (type) ### Calendar.zone_abbr/0 (type) The time zone abbreviation (for example, `CET` or `CEST` or `BST`). ### Calendar.ISO (module) The default calendar implementation, a Gregorian calendar following ISO 8601. This calendar implements a proleptic Gregorian calendar and is therefore compatible with the calendar used in most countries today. The proleptic means the Gregorian rules for leap years are applied for all time, consequently the dates give different results before the year 1583 from when the Gregorian calendar was adopted. ### ISO 8601 compliance - Calendar.ISO (module) The ISO 8601 specification is feature-rich, but allows applications to selectively implement most parts of it. The choices Elixir makes are catalogued below. ### Features - Calendar.ISO (module) The standard library supports a minimal set of possible ISO 8601 features. Specifically, the parser only supports calendar dates and does not support ordinal and week formats. Additionally, it supports parsing ISO 8601 formatted durations, including negative time units and fractional seconds. By default Elixir only parses extended-formatted date/times. You can opt-in to parse basic-formatted date/times. `NaiveDateTime.to_iso8601/2` and `DateTime.to_iso8601/2` allow you to produce either basic or extended formatted strings, and `Calendar.strftime/2` allows you to format datetimes however else you desire. Elixir does not support reduced accuracy formats (for example, a date without the day component) nor decimal precisions in the lowest component (such as `10:01:25,5`). #### Examples Elixir expects the extended format by default when parsing: iex> Calendar.ISO.parse_naive_datetime("2015-01-23T23:50:07") {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_naive_datetime("20150123T235007") {:error, :invalid_format} Parsing can be restricted to basic if desired: iex> Calendar.ISO.parse_naive_datetime("20150123T235007Z", :basic) {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_naive_datetime("20150123T235007Z", :extended) {:error, :invalid_format} Only calendar dates are supported in parsing; ordinal and week dates are not. iex> Calendar.ISO.parse_date("2015-04-15") {:ok, {2015, 4, 15}} iex> Calendar.ISO.parse_date("2015-105") {:error, :invalid_format} iex> Calendar.ISO.parse_date("2015-W16") {:error, :invalid_format} iex> Calendar.ISO.parse_date("2015-W016-3") {:error, :invalid_format} Years, months, days, hours, minutes, and seconds must be fully specified: iex> Calendar.ISO.parse_date("2015-04-15") {:ok, {2015, 4, 15}} iex> Calendar.ISO.parse_date("2015-04") {:error, :invalid_format} iex> Calendar.ISO.parse_date("2015") {:error, :invalid_format} iex> Calendar.ISO.parse_time("23:50:07.0123456") {:ok, {23, 50, 7, {12345, 6}}} iex> Calendar.ISO.parse_time("23:50:07") {:ok, {23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_time("23:50") {:error, :invalid_format} iex> Calendar.ISO.parse_time("23") {:error, :invalid_format} ### Extensions - Calendar.ISO (module) The parser and formatter adopt one ISO 8601 extension: extended year notation. This allows dates to be prefixed with a `+` or `-` sign, extending the range of expressible years from the default (`0000..9999`) to `-9999..9999`. Elixir still restricts years in this format to four digits. #### Examples iex> Calendar.ISO.parse_date("-2015-01-23") {:ok, {-2015, 1, 23}} iex> Calendar.ISO.parse_date("+2015-01-23") {:ok, {2015, 1, 23}} iex> Calendar.ISO.parse_naive_datetime("-2015-01-23 23:50:07") {:ok, {-2015, 1, 23, 23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_naive_datetime("+2015-01-23 23:50:07") {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_utc_datetime("-2015-01-23 23:50:07Z") {:ok, {-2015, 1, 23, 23, 50, 7, {0, 0}}, 0} iex> Calendar.ISO.parse_utc_datetime("+2015-01-23 23:50:07Z") {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}, 0} ### Additions - Calendar.ISO (module) ISO 8601 does not allow a whitespace instead of `T` as a separator between date and times, both when parsing and formatting. This is a common enough representation, Elixir allows it during parsing. The formatting of dates in `NaiveDateTime.to_iso8601/1` and `DateTime.to_iso8601/1` do produce specification-compliant string representations using the `T` separator. #### Examples iex> Calendar.ISO.parse_naive_datetime("2015-01-23 23:50:07.0123456") {:ok, {2015, 1, 23, 23, 50, 7, {12345, 6}}} iex> Calendar.ISO.parse_naive_datetime("2015-01-23T23:50:07.0123456") {:ok, {2015, 1, 23, 23, 50, 7, {12345, 6}}} iex> Calendar.ISO.parse_utc_datetime("2015-01-23 23:50:07.0123456Z") {:ok, {2015, 1, 23, 23, 50, 7, {12345, 6}}, 0} iex> Calendar.ISO.parse_utc_datetime("2015-01-23T23:50:07.0123456Z") {:ok, {2015, 1, 23, 23, 50, 7, {12345, 6}}, 0} ### Calendar.ISO.date_to_string/4 (function) Converts the given date into a string. By default, returns dates formatted in the "extended" format, for human readability. It also supports the "basic" format by passing the `:basic` option. ### Examples - Calendar.ISO.date_to_string/4 (function) iex> Calendar.ISO.date_to_string(2015, 2, 28) "2015-02-28" iex> Calendar.ISO.date_to_string(2017, 8, 1) "2017-08-01" iex> Calendar.ISO.date_to_string(-99, 1, 31) "-0099-01-31" iex> Calendar.ISO.date_to_string(2015, 2, 28, :basic) "20150228" iex> Calendar.ISO.date_to_string(-99, 1, 31, :basic) "-00990131" ### Calendar.ISO.datetime_to_string/12 (function) Converts the datetime (with time zone) into a string. By default, returns datetimes formatted in the "extended" format, for human readability. It also supports the "basic" format by passing the `:basic` option. ### Examples - Calendar.ISO.datetime_to_string/12 (function) iex> time_zone = "Etc/UTC" iex> Calendar.ISO.datetime_to_string(2017, 8, 1, 1, 2, 3, {4, 5}, time_zone, "UTC", 0, 0) "2017-08-01 01:02:03.00000Z" iex> Calendar.ISO.datetime_to_string(2017, 8, 1, 1, 2, 3, {4, 5}, time_zone, "UTC", 3600, 0) "2017-08-01 01:02:03.00000+01:00" iex> Calendar.ISO.datetime_to_string(2017, 8, 1, 1, 2, 3, {4, 5}, time_zone, "UTC", 3600, 3600) "2017-08-01 01:02:03.00000+02:00" iex> time_zone = "Europe/Berlin" iex> Calendar.ISO.datetime_to_string(2017, 8, 1, 1, 2, 3, {4, 5}, time_zone, "CET", 3600, 0) "2017-08-01 01:02:03.00000+01:00 CET Europe/Berlin" iex> Calendar.ISO.datetime_to_string(2017, 8, 1, 1, 2, 3, {4, 5}, time_zone, "CDT", 3600, 3600) "2017-08-01 01:02:03.00000+02:00 CDT Europe/Berlin" iex> time_zone = "America/Los_Angeles" iex> Calendar.ISO.datetime_to_string(2015, 2, 28, 1, 2, 3, {4, 5}, time_zone, "PST", -28800, 0) "2015-02-28 01:02:03.00000-08:00 PST America/Los_Angeles" iex> Calendar.ISO.datetime_to_string(2015, 2, 28, 1, 2, 3, {4, 5}, time_zone, "PDT", -28800, 3600) "2015-02-28 01:02:03.00000-07:00 PDT America/Los_Angeles" iex> time_zone = "Europe/Berlin" iex> Calendar.ISO.datetime_to_string(2017, 8, 1, 1, 2, 3, {4, 5}, time_zone, "CET", 3600, 0, :basic) "20170801 010203.00000+0100 CET Europe/Berlin" ### Calendar.ISO.day_of_era/3 (function) Calculates the day and era from the given `year`, `month`, and `day`. ### Examples - Calendar.ISO.day_of_era/3 (function) iex> Calendar.ISO.day_of_era(0, 1, 1) {366, 0} iex> Calendar.ISO.day_of_era(1, 1, 1) {1, 1} iex> Calendar.ISO.day_of_era(0, 12, 31) {1, 0} iex> Calendar.ISO.day_of_era(0, 12, 30) {2, 0} iex> Calendar.ISO.day_of_era(-1, 12, 31) {367, 0} ### Calendar.ISO.day_of_week/4 (function) Calculates the day of the week from the given `year`, `month`, and `day`. It is an integer from 1 to 7, where 1 is the given `starting_on` weekday. For example, if `starting_on` is set to `:monday`, then 1 is Monday and 7 is Sunday. `starting_on` can also be `:default`, which is equivalent to `:monday`. ### Examples - Calendar.ISO.day_of_week/4 (function) iex> Calendar.ISO.day_of_week(2016, 10, 31, :monday) {1, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 1, :monday) {2, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 2, :monday) {3, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 3, :monday) {4, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 4, :monday) {5, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 5, :monday) {6, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 6, :monday) {7, 1, 7} iex> Calendar.ISO.day_of_week(-99, 1, 31, :monday) {4, 1, 7} iex> Calendar.ISO.day_of_week(2016, 10, 31, :sunday) {2, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 1, :sunday) {3, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 2, :sunday) {4, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 3, :sunday) {5, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 4, :sunday) {6, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 5, :sunday) {7, 1, 7} iex> Calendar.ISO.day_of_week(2016, 11, 6, :sunday) {1, 1, 7} iex> Calendar.ISO.day_of_week(-99, 1, 31, :sunday) {5, 1, 7} iex> Calendar.ISO.day_of_week(2016, 10, 31, :saturday) {3, 1, 7} ### Calendar.ISO.day_of_year/3 (function) Calculates the day of the year from the given `year`, `month`, and `day`. It is an integer from 1 to 366. ### Examples - Calendar.ISO.day_of_year/3 (function) iex> Calendar.ISO.day_of_year(2016, 1, 31) 31 iex> Calendar.ISO.day_of_year(-99, 2, 1) 32 iex> Calendar.ISO.day_of_year(2018, 2, 28) 59 ### Calendar.ISO.day_rollover_relative_to_midnight_utc/0 (function) See `c:Calendar.day_rollover_relative_to_midnight_utc/0` for documentation. ### Calendar.ISO.days_in_month/2 (function) Returns how many days there are in the given year-month. ### Examples - Calendar.ISO.days_in_month/2 (function) iex> Calendar.ISO.days_in_month(1900, 1) 31 iex> Calendar.ISO.days_in_month(1900, 2) 28 iex> Calendar.ISO.days_in_month(2000, 2) 29 iex> Calendar.ISO.days_in_month(2001, 2) 28 iex> Calendar.ISO.days_in_month(2004, 2) 29 iex> Calendar.ISO.days_in_month(2004, 4) 30 iex> Calendar.ISO.days_in_month(-1, 5) 31 ### Calendar.ISO.iso_days_to_beginning_of_day/1 (function) Converts the `t:Calendar.iso_days/0` to the first moment of the day. ### Examples - Calendar.ISO.iso_days_to_beginning_of_day/1 (function) iex> Calendar.ISO.iso_days_to_beginning_of_day({0, {0, 86400000000}}) {0, {0, 86400000000}} iex> Calendar.ISO.iso_days_to_beginning_of_day({730485, {43200000000, 86400000000}}) {730485, {0, 86400000000}} iex> Calendar.ISO.iso_days_to_beginning_of_day({730485, {46800000000, 86400000000}}) {730485, {0, 86400000000}} ### Calendar.ISO.iso_days_to_end_of_day/1 (function) Converts the `t:Calendar.iso_days/0` to the last moment of the day. ### Examples - Calendar.ISO.iso_days_to_end_of_day/1 (function) iex> Calendar.ISO.iso_days_to_end_of_day({0, {0, 86400000000}}) {0, {86399999999, 86400000000}} iex> Calendar.ISO.iso_days_to_end_of_day({730485, {43200000000, 86400000000}}) {730485, {86399999999, 86400000000}} iex> Calendar.ISO.iso_days_to_end_of_day({730485, {46800000000, 86400000000}}) {730485, {86399999999, 86400000000}} ### Calendar.ISO.leap_year?/1 (function) Returns if the given year is a leap year. ### Examples - Calendar.ISO.leap_year?/1 (function) iex> Calendar.ISO.leap_year?(2000) true iex> Calendar.ISO.leap_year?(2001) false iex> Calendar.ISO.leap_year?(2004) true iex> Calendar.ISO.leap_year?(1900) false iex> Calendar.ISO.leap_year?(-4) true ### Calendar.ISO.months_in_year/1 (function) Returns how many months there are in the given year. ### Example - Calendar.ISO.months_in_year/1 (function) iex> Calendar.ISO.months_in_year(2004) 12 ### Calendar.ISO.naive_datetime_from_iso_days/1 (function) Converts the `t:Calendar.iso_days/0` format to the datetime format specified by this calendar. ### Examples - Calendar.ISO.naive_datetime_from_iso_days/1 (function) iex> Calendar.ISO.naive_datetime_from_iso_days({0, {0, 86400}}) {0, 1, 1, 0, 0, 0, {0, 6}} iex> Calendar.ISO.naive_datetime_from_iso_days({730_485, {0, 86400}}) {2000, 1, 1, 0, 0, 0, {0, 6}} iex> Calendar.ISO.naive_datetime_from_iso_days({730_485, {43200, 86400}}) {2000, 1, 1, 12, 0, 0, {0, 6}} iex> Calendar.ISO.naive_datetime_from_iso_days({-365, {0, 86400000000}}) {-1, 1, 1, 0, 0, 0, {0, 6}} ### Calendar.ISO.naive_datetime_to_iso_days/7 (function) Returns the `t:Calendar.iso_days/0` format of the specified date. ### Examples - Calendar.ISO.naive_datetime_to_iso_days/7 (function) iex> Calendar.ISO.naive_datetime_to_iso_days(0, 1, 1, 0, 0, 0, {0, 6}) {0, {0, 86400000000}} iex> Calendar.ISO.naive_datetime_to_iso_days(2000, 1, 1, 12, 0, 0, {0, 6}) {730485, {43200000000, 86400000000}} iex> Calendar.ISO.naive_datetime_to_iso_days(2000, 1, 1, 13, 0, 0, {0, 6}) {730485, {46800000000, 86400000000}} iex> Calendar.ISO.naive_datetime_to_iso_days(-1, 1, 1, 0, 0, 0, {0, 6}) {-365, {0, 86400000000}} ### Calendar.ISO.naive_datetime_to_string/8 (function) Converts the datetime (without time zone) into a string. By default, returns datetimes formatted in the "extended" format, for human readability. It also supports the "basic" format by passing the `:basic` option. ### Examples - Calendar.ISO.naive_datetime_to_string/8 (function) iex> Calendar.ISO.naive_datetime_to_string(2015, 2, 28, 1, 2, 3, {4, 6}) "2015-02-28 01:02:03.000004" iex> Calendar.ISO.naive_datetime_to_string(2017, 8, 1, 1, 2, 3, {4, 5}) "2017-08-01 01:02:03.00000" iex> Calendar.ISO.naive_datetime_to_string(2015, 2, 28, 1, 2, 3, {4, 6}, :basic) "20150228 010203.000004" ### Calendar.ISO.parse_date/1 (function) Parses a date `string` in the `:extended` format. For more information on supported strings, see how this module implements [ISO 8601](#module-iso-8601-compliance). ### Examples - Calendar.ISO.parse_date/1 (function) iex> Calendar.ISO.parse_date("2015-01-23") {:ok, {2015, 1, 23}} iex> Calendar.ISO.parse_date("2015:01:23") {:error, :invalid_format} iex> Calendar.ISO.parse_date("2015-01-32") {:error, :invalid_date} ### Calendar.ISO.parse_date/2 (function) Parses a date `string` according to a given `format`. The `format` can either be `:basic` or `:extended`. For more information on supported strings, see how this module implements [ISO 8601](#module-iso-8601-compliance). ### Examples - Calendar.ISO.parse_date/2 (function) iex> Calendar.ISO.parse_date("20150123", :basic) {:ok, {2015, 1, 23}} iex> Calendar.ISO.parse_date("20150123", :extended) {:error, :invalid_format} ### Calendar.ISO.parse_duration/1 (function) Parses an ISO 8601 formatted duration string to a list of `Duration` compabitble unit pairs. See `Duration.from_iso8601/1`. ### Calendar.ISO.parse_naive_datetime/1 (function) Parses a naive datetime `string` in the `:extended` format. For more information on supported strings, see how this module implements [ISO 8601](#module-iso-8601-compliance). ### Examples - Calendar.ISO.parse_naive_datetime/1 (function) iex> Calendar.ISO.parse_naive_datetime("2015-01-23 23:50:07") {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_naive_datetime("2015-01-23 23:50:07Z") {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_naive_datetime("2015-01-23 23:50:07-02:30") {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_naive_datetime("2015-01-23 23:50:07.0") {:ok, {2015, 1, 23, 23, 50, 7, {0, 1}}} iex> Calendar.ISO.parse_naive_datetime("2015-01-23 23:50:07,0123456") {:ok, {2015, 1, 23, 23, 50, 7, {12345, 6}}} ### Calendar.ISO.parse_naive_datetime/2 (function) Parses a naive datetime `string` according to a given `format`. The `format` can either be `:basic` or `:extended`. For more information on supported strings, see how this module implements [ISO 8601](#module-iso-8601-compliance). ### Examples - Calendar.ISO.parse_naive_datetime/2 (function) iex> Calendar.ISO.parse_naive_datetime("20150123 235007", :basic) {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_naive_datetime("20150123 235007", :extended) {:error, :invalid_format} ### Calendar.ISO.parse_time/1 (function) Parses a time `string` in the `:extended` format. For more information on supported strings, see how this module implements [ISO 8601](#module-iso-8601-compliance). ### Examples - Calendar.ISO.parse_time/1 (function) iex> Calendar.ISO.parse_time("23:50:07") {:ok, {23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_time("23:50:07Z") {:ok, {23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_time("T23:50:07Z") {:ok, {23, 50, 7, {0, 0}}} ### Calendar.ISO.parse_time/2 (function) Parses a time `string` according to a given `format`. The `format` can either be `:basic` or `:extended`. For more information on supported strings, see how this module implements [ISO 8601](#module-iso-8601-compliance). ### Examples - Calendar.ISO.parse_time/2 (function) iex> Calendar.ISO.parse_time("235007", :basic) {:ok, {23, 50, 7, {0, 0}}} iex> Calendar.ISO.parse_time("235007", :extended) {:error, :invalid_format} ### Calendar.ISO.parse_utc_datetime/1 (function) Parses a UTC datetime `string` in the `:extended` format. For more information on supported strings, see how this module implements [ISO 8601](#module-iso-8601-compliance). ### Examples - Calendar.ISO.parse_utc_datetime/1 (function) iex> Calendar.ISO.parse_utc_datetime("2015-01-23 23:50:07Z") {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}, 0} iex> Calendar.ISO.parse_utc_datetime("2015-01-23 23:50:07+02:30") {:ok, {2015, 1, 23, 21, 20, 7, {0, 0}}, 9000} iex> Calendar.ISO.parse_utc_datetime("2015-01-23 23:50:07") {:error, :missing_offset} ### Calendar.ISO.parse_utc_datetime/2 (function) Parses a UTC datetime `string` according to a given `format`. The `format` can either be `:basic` or `:extended`. For more information on supported strings, see how this module implements [ISO 8601](#module-iso-8601-compliance). ### Examples - Calendar.ISO.parse_utc_datetime/2 (function) iex> Calendar.ISO.parse_utc_datetime("20150123 235007Z", :basic) {:ok, {2015, 1, 23, 23, 50, 7, {0, 0}}, 0} iex> Calendar.ISO.parse_utc_datetime("20150123 235007Z", :extended) {:error, :invalid_format} ### Calendar.ISO.quarter_of_year/3 (function) Calculates the quarter of the year from the given `year`, `month`, and `day`. It is an integer from 1 to 4. ### Examples - Calendar.ISO.quarter_of_year/3 (function) iex> Calendar.ISO.quarter_of_year(2016, 1, 31) 1 iex> Calendar.ISO.quarter_of_year(2016, 4, 3) 2 iex> Calendar.ISO.quarter_of_year(-99, 9, 31) 3 iex> Calendar.ISO.quarter_of_year(2018, 12, 28) 4 ### Calendar.ISO.shift_date/4 (function) Shifts Date by Duration according to its calendar. ### Examples - Calendar.ISO.shift_date/4 (function) iex> Calendar.ISO.shift_date(2016, 1, 3, Duration.new!(month: 2)) {2016, 3, 3} iex> Calendar.ISO.shift_date(2016, 2, 29, Duration.new!(month: 1)) {2016, 3, 29} iex> Calendar.ISO.shift_date(2016, 1, 31, Duration.new!(month: 1)) {2016, 2, 29} iex> Calendar.ISO.shift_date(2016, 1, 31, Duration.new!(year: 4, day: 1)) {2020, 2, 1} ### Calendar.ISO.shift_naive_datetime/8 (function) Shifts NaiveDateTime by Duration according to its calendar. ### Examples - Calendar.ISO.shift_naive_datetime/8 (function) iex> Calendar.ISO.shift_naive_datetime(2016, 1, 3, 0, 0, 0, {0, 0}, Duration.new!(hour: 1)) {2016, 1, 3, 1, 0, 0, {0, 0}} iex> Calendar.ISO.shift_naive_datetime(2016, 1, 3, 0, 0, 0, {0, 0}, Duration.new!(hour: 30)) {2016, 1, 4, 6, 0, 0, {0, 0}} iex> Calendar.ISO.shift_naive_datetime(2016, 1, 3, 0, 0, 0, {0, 0}, Duration.new!(microsecond: {100, 6})) {2016, 1, 3, 0, 0, 0, {100, 6}} ### Calendar.ISO.shift_time/5 (function) Shifts Time by Duration units according to its calendar. ### Examples - Calendar.ISO.shift_time/5 (function) iex> Calendar.ISO.shift_time(13, 0, 0, {0, 0}, Duration.new!(hour: 2)) {15, 0, 0, {0, 0}} iex> Calendar.ISO.shift_time(13, 0, 0, {0, 0}, Duration.new!(microsecond: {100, 6})) {13, 0, 0, {100, 6}} ### Calendar.ISO.time_from_day_fraction/1 (function) Converts a day fraction to this Calendar's representation of time. ### Examples - Calendar.ISO.time_from_day_fraction/1 (function) iex> Calendar.ISO.time_from_day_fraction({1, 2}) {12, 0, 0, {0, 6}} iex> Calendar.ISO.time_from_day_fraction({13, 24}) {13, 0, 0, {0, 6}} ### Calendar.ISO.time_to_day_fraction/4 (function) Returns the normalized day fraction of the specified time. ### Examples - Calendar.ISO.time_to_day_fraction/4 (function) iex> Calendar.ISO.time_to_day_fraction(0, 0, 0, {0, 6}) {0, 86400000000} iex> Calendar.ISO.time_to_day_fraction(12, 34, 56, {123, 6}) {45296000123, 86400000000} ### Calendar.ISO.time_to_string/5 (function) Converts the given time into a string. By default, returns times formatted in the "extended" format, for human readability. It also supports the "basic" format by passing the `:basic` option. ### Examples - Calendar.ISO.time_to_string/5 (function) iex> Calendar.ISO.time_to_string(2, 2, 2, {2, 6}) "02:02:02.000002" iex> Calendar.ISO.time_to_string(2, 2, 2, {2, 2}) "02:02:02.00" iex> Calendar.ISO.time_to_string(2, 2, 2, {2, 0}) "02:02:02" iex> Calendar.ISO.time_to_string(2, 2, 2, {2, 6}, :basic) "020202.000002" iex> Calendar.ISO.time_to_string(2, 2, 2, {2, 6}, :extended) "02:02:02.000002" ### Calendar.ISO.time_unit_to_precision/1 (function) Converts a `t:System.time_unit/0` to precision. Integer-based time units always get maximum precision. ### Examples - Calendar.ISO.time_unit_to_precision/1 (function) iex> Calendar.ISO.time_unit_to_precision(:nanosecond) 6 iex> Calendar.ISO.time_unit_to_precision(:second) 0 iex> Calendar.ISO.time_unit_to_precision(1) 6 ### Calendar.ISO.valid_date?/3 (function) Determines if the date given is valid according to the proleptic Gregorian calendar. ### Examples - Calendar.ISO.valid_date?/3 (function) iex> Calendar.ISO.valid_date?(2015, 2, 28) true iex> Calendar.ISO.valid_date?(2015, 2, 30) false iex> Calendar.ISO.valid_date?(-1, 12, 31) true iex> Calendar.ISO.valid_date?(-1, 12, 32) false ### Calendar.ISO.valid_time?/4 (function) Determines if the date given is valid according to the proleptic Gregorian calendar. Leap seconds are not supported by the built-in Calendar.ISO. ### Examples - Calendar.ISO.valid_time?/4 (function) iex> Calendar.ISO.valid_time?(10, 50, 25, {3006, 6}) true iex> Calendar.ISO.valid_time?(23, 59, 60, {0, 0}) false iex> Calendar.ISO.valid_time?(24, 0, 0, {0, 0}) false ### Calendar.ISO.year_of_era/1 (function) Calculates the year and era from the given `year`. The ISO calendar has two eras: the "current era" (CE) which starts in year `1` and is defined as era `1`. And "before the current era" (BCE) for those years less than `1`, defined as era `0`. ### Examples - Calendar.ISO.year_of_era/1 (function) iex> Calendar.ISO.year_of_era(1) {1, 1} iex> Calendar.ISO.year_of_era(2018) {2018, 1} iex> Calendar.ISO.year_of_era(0) {1, 0} iex> Calendar.ISO.year_of_era(-1) {2, 0} ### Calendar.ISO.year_of_era/3 (function) Calendar callback to compute the year and era from the given `year`, `month` and `day`. In the ISO calendar, the new year coincides with the new era, so the `month` and `day` arguments are discarded. If you only have the year available, you can `year_of_era/1` instead. ### Examples - Calendar.ISO.year_of_era/3 (function) iex> Calendar.ISO.year_of_era(1, 1, 1) {1, 1} iex> Calendar.ISO.year_of_era(2018, 12, 1) {2018, 1} iex> Calendar.ISO.year_of_era(0, 1, 1) {1, 0} iex> Calendar.ISO.year_of_era(-1, 12, 1) {2, 0} ### Calendar.ISO.bce/0 (type) "Before the Current Era" or "Before the Common Era" (BCE), for those years less than `1`. ### Calendar.ISO.ce/0 (type) The "Current Era" or the "Common Era" (CE) which starts in year `1`. ### Calendar.ISO.day/0 (type) ### Calendar.ISO.day_of_week/0 (type) Integer that represents the day of the week, where 1 is Monday and 7 is Sunday. ### Calendar.ISO.day_of_year/0 (type) ### Calendar.ISO.era/0 (type) The calendar era. The ISO calendar has two eras: * [CE](`t:ce/0`) - which starts in year `1` and is defined as era `1`. * [BCE](`t:bce/0`) - for those years less than `1` and is defined as era `0`. ### Calendar.ISO.format/0 (type) ### Calendar.ISO.hour/0 (type) ### Calendar.ISO.microsecond/0 (type) Microseconds with stored precision. The precision represents the number of digits that must be used when representing the microseconds to external format. If the precision is 0, it means microseconds must be skipped. ### Calendar.ISO.minute/0 (type) ### Calendar.ISO.month/0 (type) ### Calendar.ISO.quarter_of_year/0 (type) ### Calendar.ISO.second/0 (type) ### Calendar.ISO.utc_offset/0 (type) ### Calendar.ISO.weekday/0 (type) ### Calendar.ISO.year/0 (type) ### Calendar.ISO.year_of_era/0 (type) ### Calendar.TimeZoneDatabase (behaviour) This module defines a behaviour for providing time zone data. IANA provides time zone data that includes data about different UTC offsets and standard offsets for time zones. ### Calendar.TimeZoneDatabase.time_zone_period_from_utc_iso_days/2 (callback) Time zone period for a point in time in UTC for a specific time zone. Takes a time zone name and a point in time for UTC and returns a `time_zone_period` for that point in time. ### Calendar.TimeZoneDatabase.time_zone_periods_from_wall_datetime/2 (callback) Possible time zone periods for a certain time zone and wall clock date and time. When the provided naive datetime is ambiguous, return a tuple with `:ambiguous` and the two possible periods. The periods in the tuple must be sorted with the first element being the one that begins first. When the provided naive datetime is in a gap, such as during the "spring forward" when going from winter time to summer time, return a tuple with `:gap` and two periods with limits in a nested tuple. The first nested two-tuple is the period before the gap and a naive datetime with a limit for when the period ends (wall time). The second nested two-tuple is the period just after the gap and a datetime (wall time) for when the period begins just after the gap. If there is only a single possible period for the provided `datetime`, then return a tuple with `:ok` and the `time_zone_period`. ### Calendar.TimeZoneDatabase.time_zone_period/0 (type) A period where a certain combination of UTC offset, standard offset, and zone abbreviation is in effect. For example, one period could be the summer of 2018 in the `Europe/London` timezone, where summer time/daylight saving time is in effect and lasts from spring to autumn. In autumn, the `std_offset` changes along with the `zone_abbr` so a different period is needed during winter. ### Calendar.TimeZoneDatabase.time_zone_period_limit/0 (type) Limit for when a certain time zone period begins or ends. A beginning is inclusive. An ending is exclusive. For example, if a period is from `2015-03-29 01:00:00` and until `2015-10-25 01:00:00`, the period includes and begins from the beginning of `2015-03-29 01:00:00` and lasts until just before `2015-10-25 01:00:00`. A beginning or end for certain periods are infinite, such as the latest period for time zones without DST or plans to change. However, for the purpose of this behaviour, they are only used for gaps in wall time where the needed period limits are at a certain time. ### Calendar.UTCOnlyTimeZoneDatabase (module) Built-in time zone database that works only in the `Etc/UTC` timezone. For all other time zones, it returns `{:error, :utc_only_time_zone_database}`. ### Agent (module) Agents are a simple abstraction around state. Often in Elixir there is a need to share or store state that must be accessed from different processes or by the same process at different points in time. The `Agent` module provides a basic server implementation that allows state to be retrieved and updated via a simple API. ### Examples - Agent (module) For example, the following agent implements a counter: defmodule Counter do use Agent def start_link(initial_value) do Agent.start_link(fn -> initial_value end, name: __MODULE__) end def value do Agent.get(__MODULE__, & &1) end def increment do Agent.update(__MODULE__, &(&1 + 1)) end end Usage would be: Counter.start_link(0) #=> {:ok, #PID<0.123.0>} Counter.value() #=> 0 Counter.increment() #=> :ok Counter.increment() #=> :ok Counter.value() #=> 2 Thanks to the agent server process, the counter can be safely incremented concurrently. > #### `use Agent` {: .info} > > When you `use Agent`, the `Agent` module will define a > `child_spec/1` function, so your module can be used > as a child in a supervision tree. Agents provide a segregation between the client and server APIs (similar to `GenServer`s). In particular, the functions passed as arguments to the calls to `Agent` functions are invoked inside the agent (the server). This distinction is important because you may want to avoid expensive operations inside the agent, as they will effectively block the agent until the request is fulfilled. Consider these two examples: # Compute in the agent/server def get_something(agent) do Agent.get(agent, fn state -> do_something_expensive(state) end) end # Compute in the agent/client def get_something(agent) do Agent.get(agent, & &1) |> do_something_expensive() end The first function blocks the agent. The second function copies all the state to the client and then executes the operation in the client. One aspect to consider is whether the data is large enough to require processing in the server, at least initially, or small enough to be sent to the client cheaply. Another factor is whether the data needs to be processed atomically: getting the state and calling `do_something_expensive(state)` outside of the agent means that the agent's state can be updated in the meantime. This is specially important in case of updates as computing the new state in the client rather than in the server can lead to race conditions if multiple clients are trying to update the same state to different values. ### How to supervise - Agent (module) An `Agent` is most commonly started under a supervision tree. When we invoke `use Agent`, it automatically defines a `child_spec/1` function that allows us to start the agent directly under a supervisor. To start an agent under a supervisor with an initial counter of 0, one may do: children = [ {Counter, 0} ] Supervisor.start_link(children, strategy: :one_for_all) While one could also simply pass the `Counter` as a child to the supervisor, such as: children = [ Counter # Same as {Counter, []} ] Supervisor.start_link(children, strategy: :one_for_all) The definition above wouldn't work for this particular example, as it would attempt to start the counter with an initial value of an empty list. However, this may be a viable option in your own agents. A common approach is to use a keyword list, as that would allow setting the initial value and giving a name to the counter process, for example: def start_link(opts) do {initial_value, opts} = Keyword.pop(opts, :initial_value, 0) Agent.start_link(fn -> initial_value end, opts) end and then you can use `Counter`, `{Counter, name: :my_counter}` or even `{Counter, initial_value: 0, name: :my_counter}` as a child specification. `use Agent` also accepts a list of options which configures the child specification and therefore how it runs under a supervisor. The generated `child_spec/1` can be customized with the following options: * `:id` - the child specification identifier, defaults to the current module * `:restart` - when the child should be restarted, defaults to `:permanent` * `:shutdown` - how to shut down the child, either immediately or by giving it time to shut down For example: use Agent, restart: :transient, shutdown: 10_000 See the "Child specification" section in the `Supervisor` module for more detailed information. The `@doc` annotation immediately preceding `use Agent` will be attached to the generated `child_spec/1` function. ### Name registration - Agent (module) An agent is bound to the same name registration rules as GenServers. Read more about it in the `GenServer` documentation. ### A word on distributed agents - Agent (module) It is important to consider the limitations of distributed agents. Agents provide two APIs, one that works with anonymous functions and another that expects an explicit module, function, and arguments. In a distributed setup with multiple nodes, the API that accepts anonymous functions only works if the caller (client) and the agent have the same version of the caller module. Keep in mind this issue also shows up when performing "rolling upgrades" with agents. By rolling upgrades we mean the following situation: you wish to deploy a new version of your software by *shutting down* some of your nodes and replacing them with nodes running a new version of the software. In this setup, part of your environment will have one version of a given module and the other part another version (the newer one) of the same module. The best solution is to simply use the explicit module, function, and arguments APIs when working with distributed agents. ### Hot code swapping - Agent (module) An agent can have its code hot swapped live by simply passing a module, function, and arguments tuple to the update instruction. For example, imagine you have an agent named `:sample` and you want to convert its inner state from a keyword list to a map. It can be done with the following instruction: {:update, :sample, {:advanced, {Enum, :into, [%{}]}}} The agent's state will be added to the given list of arguments (`[%{}]`) as the first argument. ### Agent.cast/2 (function) Performs a cast (*fire and forget*) operation on the agent state. The function `fun` is sent to the `agent` which invokes the function passing the agent state. The return value of `fun` becomes the new state of the agent. Note that `cast` returns `:ok` immediately, regardless of whether `agent` (or the node it should live on) exists. ### Examples - Agent.cast/2 (function) iex> {:ok, pid} = Agent.start_link(fn -> 42 end) iex> Agent.cast(pid, fn state -> state + 1 end) :ok iex> Agent.get(pid, fn state -> state end) 43 ### Agent.cast/4 (function) Performs a cast (*fire and forget*) operation on the agent state. Same as `cast/2` but a module, function, and arguments are expected instead of an anonymous function. The state is added as first argument to the given list of arguments. ### Examples - Agent.cast/4 (function) iex> {:ok, pid} = Agent.start_link(fn -> 42 end) iex> Agent.cast(pid, Kernel, :+, [12]) :ok iex> Agent.get(pid, fn state -> state end) 54 ### Agent.child_spec/1 (function) Returns a specification to start an agent under a supervisor. See the "Child specification" section in the `Supervisor` module for more detailed information. ### Agent.get/3 (function) Gets an agent value via the given anonymous function. The function `fun` is sent to the `agent` which invokes the function passing the agent state. The result of the function invocation is returned from this function. `timeout` is an integer greater than zero which specifies how many milliseconds are allowed before the agent executes the function and returns the result value, or the atom `:infinity` to wait indefinitely. If no result is received within the specified time, the function call fails and the caller exits. ### Examples - Agent.get/3 (function) iex> {:ok, pid} = Agent.start_link(fn -> 42 end) iex> Agent.get(pid, fn state -> state end) 42 ### Agent.get/5 (function) Gets an agent value via the given function. Same as `get/3` but a module, function, and arguments are expected instead of an anonymous function. The state is added as first argument to the given list of arguments. ### Agent.get_and_update/3 (function) Gets and updates the agent state in one operation via the given anonymous function. The function `fun` is sent to the `agent` which invokes the function passing the agent state. The function must return a tuple with two elements, the first being the value to return (that is, the "get" value) and the second one being the new state of the agent. `timeout` is an integer greater than zero which specifies how many milliseconds are allowed before the agent executes the function and returns the result value, or the atom `:infinity` to wait indefinitely. If no result is received within the specified time, the function call fails and the caller exits. ### Examples - Agent.get_and_update/3 (function) iex> {:ok, pid} = Agent.start_link(fn -> 42 end) iex> Agent.get_and_update(pid, fn state -> {state, state + 1} end) 42 iex> Agent.get(pid, fn state -> state end) 43 ### Agent.get_and_update/5 (function) Gets and updates the agent state in one operation via the given function. Same as `get_and_update/3` but a module, function, and arguments are expected instead of an anonymous function. The state is added as first argument to the given list of arguments. ### Agent.start/2 (function) Starts an agent process without links (outside of a supervision tree). See `start_link/2` for more information. ### Examples - Agent.start/2 (function) iex> {:ok, pid} = Agent.start(fn -> 42 end) iex> Agent.get(pid, fn state -> state end) 42 ### Agent.start/4 (function) Starts an agent without links with the given module, function, and arguments. See `start_link/4` for more information. ### Agent.start_link/2 (function) Starts an agent linked to the current process with the given function. This is often used to start the agent as part of a supervision tree. Once the agent is spawned, the given function `fun` is invoked in the server process, and should return the initial agent state. Note that `start_link/2` does not return until the given function has returned. ### Options - Agent.start_link/2 (function) The `:name` option is used for registration as described in the module documentation. If the `:timeout` option is present, the agent is allowed to spend at most the given number of milliseconds on initialization or it will be terminated and the start function will return `{:error, :timeout}`. If the `:debug` option is present, the corresponding function in the [`:sys` module](`:sys`) will be invoked. If the `:spawn_opt` option is present, its value will be passed as options to the underlying process as in `Process.spawn/4`. ### Return values - Agent.start_link/2 (function) If the server is successfully created and initialized, the function returns `{:ok, pid}`, where `pid` is the PID of the server. If an agent with the specified name already exists, the function returns `{:error, {:already_started, pid}}` with the PID of that process. If the given function callback fails, the function returns `{:error, reason}`. ### Examples - Agent.start_link/2 (function) iex> {:ok, pid} = Agent.start_link(fn -> 42 end) iex> Agent.get(pid, fn state -> state end) 42 iex> {:error, {exception, _stacktrace}} = Agent.start(fn -> raise "oops" end) iex> exception %RuntimeError{message: "oops"} ### Agent.start_link/4 (function) Starts an agent linked to the current process. Same as `start_link/2` but a module, function, and arguments are expected instead of an anonymous function; `fun` in `module` will be called with the given arguments `args` to initialize the state. ### Agent.stop/3 (function) Synchronously stops the agent with the given `reason`. It returns `:ok` if the agent terminates with the given reason. If the agent terminates with another reason, the call will exit. This function keeps OTP semantics regarding error reporting. If the reason is any other than `:normal`, `:shutdown` or `{:shutdown, _}`, an error report will be logged. ### Examples - Agent.stop/3 (function) iex> {:ok, pid} = Agent.start_link(fn -> 42 end) iex> Agent.stop(pid) :ok ### Agent.update/3 (function) Updates the agent state via the given anonymous function. The function `fun` is sent to the `agent` which invokes the function passing the agent state. The return value of `fun` becomes the new state of the agent. This function always returns `:ok`. `timeout` is an integer greater than zero which specifies how many milliseconds are allowed before the agent executes the function and returns the result value, or the atom `:infinity` to wait indefinitely. If no result is received within the specified time, the function call fails and the caller exits. ### Examples - Agent.update/3 (function) iex> {:ok, pid} = Agent.start_link(fn -> 42 end) iex> Agent.update(pid, fn state -> state + 1 end) :ok iex> Agent.get(pid, fn state -> state end) 43 ### Agent.update/5 (function) Updates the agent state via the given function. Same as `update/3` but a module, function, and arguments are expected instead of an anonymous function. The state is added as first argument to the given list of arguments. ### Examples - Agent.update/5 (function) iex> {:ok, pid} = Agent.start_link(fn -> 42 end) iex> Agent.update(pid, Kernel, :+, [12]) :ok iex> Agent.get(pid, fn state -> state end) 54 ### Agent.agent/0 (type) The agent reference ### Agent.name/0 (type) The agent name ### Agent.on_start/0 (type) Return values of `start*` functions ### Agent.state/0 (type) The agent state ### Application (behaviour) A module for working with applications and defining application callbacks. Applications are the idiomatic way to package software in Erlang/OTP. To get the idea, they are similar to the "library" concept common in other programming languages, but with some additional characteristics. An application is a component implementing some specific functionality, with a standardized directory structure, configuration, and life cycle. Applications are *loaded*, *started*, and *stopped*. Each application also has its own environment, which provides a unified API for configuring each application. Developers typically interact with the application environment and its callback module. Therefore those will be the topics we will cover first before jumping into details about the application resource file and life cycle. ### The application environment - Application (behaviour) Each application has its own environment. The environment is a keyword list that maps atoms to terms. Note that this environment is unrelated to the operating system environment. By default, the environment of an application is an empty list. In a Mix project's `mix.exs` file, you can set the `:env` key in `application/0`: def application do [env: [db_host: "localhost"]] end Now, in your application, you can read this environment by using functions such as `fetch_env!/2` and friends: defmodule MyApp.DBClient do def start_link() do SomeLib.DBClient.start_link(host: db_host()) end defp db_host do Application.fetch_env!(:my_app, :db_host) end end In Mix projects, the environment of the application and its dependencies can be overridden via the `config/config.exs` and `config/runtime.exs` files. The former is loaded at build-time, before your code compiles, and the latter at runtime, just before your app starts. For example, someone using your application can override its `:db_host` environment variable as follows: import Config config :my_app, :db_host, "db.local" See the "Configuration" section in the `Mix` module for more information. You can also change the application environment dynamically by using functions such as `put_env/3` and `delete_env/2`. > #### Application environment in libraries {: .info} > > If you are writing a library to be used by other developers, > it is generally recommended to avoid the application environment, as the > application environment is effectively a global storage. For more information, > read about this [anti-pattern](design-anti-patterns.md#using-application-configuration-for-libraries). > #### Reading the environment of other applications {: .warning} > > Each application is responsible for its own environment. Do not > use the functions in this module for directly accessing or modifying > the environment of other applications. Whenever you change the application > environment, Elixir's build tool will only recompile the files that > belong to that application. So if you read the application environment > of another application, there is a chance you will be depending on > outdated configuration, as your file won't be recompiled as it changes. ### Compile-time environment - Application (behaviour) In the previous example, we read the application environment at runtime: defmodule MyApp.DBClient do def start_link() do SomeLib.DBClient.start_link(host: db_host()) end defp db_host do Application.fetch_env!(:my_app, :db_host) end end In other words, the environment key `:db_host` for application `:my_app` will only be read when `MyApp.DBClient` effectively starts. While reading the application environment at runtime is the preferred approach, in some rare occasions you may want to use the application environment to configure the compilation of a certain project. However, if you try to access `Application.fetch_env!/2` outside of a function: defmodule MyApp.DBClient do @db_host Application.fetch_env!(:my_app, :db_host) def start_link() do SomeLib.DBClient.start_link(host: @db_host) end end You might see warnings and errors: warning: Application.fetch_env!/2 is discouraged in the module body, use Application.compile_env/3 instead iex:3: MyApp.DBClient ** (ArgumentError) could not fetch application environment :db_host for application :my_app because the application was not loaded nor configured This happens because, when defining modules, the application environment is not yet available. Luckily, the warning tells us how to solve this issue, by using `Application.compile_env/3` instead: defmodule MyApp.DBClient do @db_host Application.compile_env(:my_app, :db_host, "db.local") def start_link() do SomeLib.DBClient.start_link(host: @db_host) end end The difference here is that `compile_env` expects the default value to be given as an argument, instead of using the `def application` function of your `mix.exs`. Furthermore, by using `compile_env/3`, tools like Mix will store the values used during compilation and compare the compilation values with the runtime values whenever your system starts, raising an error in case they differ. In any case, compile-time environments should be avoided. Whenever possible, reading the application environment at runtime should be the first choice. ### The application callback module - Application (behaviour) Applications can be loaded, started, and stopped. Generally, build tools like Mix take care of starting an application and all of its dependencies for you, but you can also do it manually by calling: {:ok, _} = Application.ensure_all_started(:some_app) When an application starts, developers may configure a callback module that executes custom code. Developers use this callback to start the application supervision tree. The first step to do so is to add a `:mod` key to the `application/0` definition in your `mix.exs` file. It expects a tuple, with the application callback module and start argument (commonly an empty list): def application do [mod: {MyApp, []}] end The `MyApp` module given to `:mod` needs to implement the `Application` behaviour. This can be done by putting `use Application` in that module and implementing the `c:start/2` callback, for example: defmodule MyApp do use Application def start(_type, _args) do children = [] Supervisor.start_link(children, strategy: :one_for_one) end end > #### `use Application` {: .info} > > When you `use Application`, the `Application` module will > set `@behaviour Application` and define an overridable > definition for the `c:stop/1` function, which is required > by Erlang/OTP. The `c:start/2` callback has to spawn and link a supervisor and return `{:ok, pid}` or `{:ok, pid, state}`, where `pid` is the PID of the supervisor, and `state` is an optional application state. `args` is the second element of the tuple given to the `:mod` option. The `type` argument passed to `c:start/2` is usually `:normal` unless in a distributed setup where application takeovers and failovers are configured. Distributed applications are beyond the scope of this documentation. When an application is shutting down, its `c:stop/1` callback is called after the supervision tree has been stopped by the runtime. This callback allows the application to do any final cleanup. The argument is the state returned by `c:start/2`, if it did, or `[]` otherwise. The return value of `c:stop/1` is ignored. By using `Application`, modules get a default implementation of `c:stop/1` that ignores its argument and returns `:ok`, but it can be overridden. Application callback modules may also implement the optional callback `c:prep_stop/1`. If present, `c:prep_stop/1` is invoked before the supervision tree is terminated. Its argument is the state returned by `c:start/2`, if it did, or `[]` otherwise, and its return value is passed to `c:stop/1`. ### The application resource file - Application (behaviour) In the sections above, we have configured an application in the `application/0` section of the `mix.exs` file. Ultimately, Mix will use this configuration to create an [*application resource file*](https://www.erlang.org/doc/man/app), which is a file called `APP_NAME.app`. For example, the application resource file of the OTP application `ex_unit` is called `ex_unit.app`. You can learn more about the generation of application resource files in the documentation of `Mix.Tasks.Compile.App`, available as well by running `mix help compile.app`. ### The application life cycle - Application (behaviour) ### Loading applications - Application (behaviour) Applications are *loaded*, which means that the runtime finds and processes their resource files: Application.load(:ex_unit) #=> :ok When an application is loaded, the environment specified in its resource file is merged with any overrides from config files. Loading an application *does not* load its modules. In practice, you rarely load applications by hand because that is part of the start process, explained next. ### Starting applications - Application (behaviour) Applications are also *started*: Application.start(:ex_unit) #=> :ok Once your application is compiled, running your system is a matter of starting your current application and its dependencies. Differently from other languages, Elixir does not have a `main` procedure that is responsible for starting your system. Instead, you start one or more applications, each with their own initialization and termination logic. When an application is started, the `Application.load/1` is automatically invoked if it hasn't been done yet. Then, it checks if the dependencies listed in the `applications` key of the resource file are already started. Having at least one dependency not started is an error condition. Functions like `ensure_all_started/1` takes care of starting an application and all of its dependencies for you. If the application does not have a callback module configured, starting is done at this point. Otherwise, its `c:start/2` callback is invoked. The PID of the top-level supervisor returned by this function is stored by the runtime for later use, and the returned application state is saved too, if any. ### Stopping applications - Application (behaviour) Started applications are, finally, *stopped*: Application.stop(:ex_unit) #=> :ok Stopping an application without a callback module defined, is in practice a no-op, except for some system tracing. Stopping an application with a callback module has three steps: 1. If present, invoke the optional callback `c:prep_stop/1`. 2. Terminate the top-level supervisor. 3. Invoke the required callback `c:stop/1`. The arguments passed to the callbacks are related to the state optionally returned by `c:start/2`, and are documented in the section about the callback module above. It is important to highlight that step 2 is a blocking one. Termination of a supervisor triggers a recursive chain of children terminations, therefore orderly shutting down all descendant processes. The `c:stop/1` callback is invoked only after termination of the whole supervision tree. Shutting down a live system cleanly can be done by calling `System.stop/1`. It will shut down every application in the reverse order they were started. By default, a SIGTERM from the operating system will automatically translate to `System.stop/0`. You can also have more explicit control over operating system signals via the `:os.set_signal/2` function. ### Tooling - Application (behaviour) The Mix build tool automates most of the application management tasks. For example, `mix test` automatically starts your application dependencies and your application itself before your test runs. `mix run --no-halt` boots your current project and can be used to start a long running system. See `mix help run`. Developers can also use `mix release` to build **releases**. Releases are able to package all of your source code as well as the Erlang VM into a single directory. Releases also give you explicit control over how each application is started and in which order. They also provide a more streamlined mechanism for starting and stopping systems, debugging, logging, as well as system monitoring. Finally, Elixir provides tools such as escripts and archives, which are different mechanisms for packaging your application. Those are typically used when tools must be shared between developers and not as deployment options. See `mix help archive.build` and `mix help escript.build` for more detail. ### Further information - Application (behaviour) For further details on applications please check the documentation of the [`:application` Erlang module](`:application`), and the [Applications](https://www.erlang.org/doc/design_principles/applications.html) section of the [OTP Design Principles User's Guide](https://www.erlang.org/doc/design_principles/users_guide.html). ### Application.app_dir/1 (function) Gets the directory for app. This information is returned based on the code path. Here is an example: File.mkdir_p!("foo/ebin") Code.prepend_path("foo/ebin") Application.app_dir(:foo) #=> "foo" Even though the directory is empty and there is no `.app` file it is considered the application directory based on the name "foo/ebin". The name may contain a dash `-` which is considered to be the app version and it is removed for the lookup purposes: File.mkdir_p!("bar-123/ebin") Code.prepend_path("bar-123/ebin") Application.app_dir(:bar) #=> "bar-123" For more information on code paths, check the `Code` module in Elixir and also Erlang's [`:code` module](`:code`). ### Application.app_dir/2 (function) Returns the given path inside `app_dir/1`. If `path` is a string, then it will be used as the path inside `app_dir/1`. If `path` is a list of strings, it will be joined (see `Path.join/1`) and the result will be used as the path inside `app_dir/1`. ### Examples - Application.app_dir/2 (function) File.mkdir_p!("foo/ebin") Code.prepend_path("foo/ebin") Application.app_dir(:foo, "my_path") #=> "foo/my_path" Application.app_dir(:foo, ["my", "nested", "path"]) #=> "foo/my/nested/path" ### Application.compile_env/3 (macro) Reads the application environment at compilation time. Similar to `get_env/3`, except it must be used to read values at compile time. This allows Elixir to track when configuration values change between compile time and runtime. The first argument is the application name. The second argument `key_or_path` is either an atom key or a path to traverse in search of the configuration, starting with an atom key. For example, imagine the following configuration: config :my_app, :key, [foo: [bar: :baz]] We can access it during compile time as: Application.compile_env(:my_app, :key) #=> [foo: [bar: :baz]] Application.compile_env(:my_app, [:key, :foo]) #=> [bar: :baz] Application.compile_env(:my_app, [:key, :foo, :bar]) #=> :baz A default value can also be given as third argument. If any of the keys in the path along the way is missing, the default value is used: Application.compile_env(:my_app, [:unknown, :foo, :bar], :default) #=> :default Application.compile_env(:my_app, [:key, :unknown, :bar], :default) #=> :default Application.compile_env(:my_app, [:key, :foo, :unknown], :default) #=> :default Giving a path is useful to let Elixir know that only certain paths in a large configuration are compile time dependent. ### Application.compile_env/4 (function) Reads the application environment at compilation time from a macro. Typically, developers will use `compile_env/3`. This function must only be invoked from macros which aim to read the compilation environment dynamically. It expects a `Macro.Env` as first argument, where the `Macro.Env` is typically the `__CALLER__` in a macro. It raises if `Macro.Env` comes from a function. ### Application.compile_env!/2 (macro) Reads the application environment at compilation time or raises. This is the same as `compile_env/3` but it raises an `ArgumentError` if the configuration is not available. ### Application.compile_env!/3 (function) Reads the application environment at compilation time from a macro or raises. Typically, developers will use `compile_env!/2`. This function must only be invoked from macros which aim to read the compilation environment dynamically. It expects a `Macro.Env` as first argument, where the `Macro.Env` is typically the `__CALLER__` in a macro. It raises if `Macro.Env` comes from a function. ### Application.config_change/3 (callback) Callback invoked after code upgrade, if the application environment has changed. `changed` is a keyword list of keys and their changed values in the application environment. `new` is a keyword list with all new keys and their values. `removed` is a list with all removed keys. ### Application.delete_env/3 (function) Deletes the `key` from the given `app` environment. It receives the same options as `put_env/4`. Returns `:ok`. ### Application.ensure_all_started/2 (function) Ensures the given `app` or `apps` and their child applications are started. The second argument is either the `t:restart_type/1` (for consistency with `start/2`) or a keyword list. ### Options - Application.ensure_all_started/2 (function) * `:type` - if the application should be started `:temporary` (default), `:permanent`, or `:transient`. See `t:restart_type/1` for more information. * `:mode` - (since v1.15.0) if the applications should be started serially (`:serial`, default) or concurrently (`:concurrent`). This option requires Erlang/OTP 26+. ### Application.ensure_loaded/1 (function) Ensures the given `app` is loaded. Same as `load/1` but returns `:ok` if the application was already loaded. ### Application.ensure_started/2 (function) Ensures the given `app` is started with `t:restart_type/0`. Same as `start/2` but returns `:ok` if the application was already started. ### Application.fetch_env/2 (function) Returns the value for `key` in `app`'s environment in a tuple. If the configuration parameter does not exist, the function returns `:error`. > #### Warning {: .warning} > > You must use this function to read only your own application > environment. Do not read the environment of other applications. > #### Application environment in info > > If you are writing a library to be used by other developers, > it is generally recommended to avoid the application environment, as the > application environment is effectively a global storage. For more information, > read our [library guidelines](library-guidelines.md). ### Application.fetch_env!/2 (function) Returns the value for `key` in `app`'s environment. If the configuration parameter does not exist, raises `ArgumentError`. > #### Warning {: .warning} > > You must use this function to read only your own application > environment. Do not read the environment of other applications. > #### Application environment in info > > If you are writing a library to be used by other developers, > it is generally recommended to avoid the application environment, as the > application environment is effectively a global storage. For more information, > read our [library guidelines](library-guidelines.md). ### Application.format_error/1 (function) Formats the error reason returned by `start/2`, `ensure_started/2`, `stop/1`, `load/1` and `unload/1`, returns a string. ### Application.get_all_env/1 (function) Returns all key-value pairs for `app`. ### Application.get_application/1 (function) Gets the application for the given module. The application is located by analyzing the spec of all loaded applications. Returns `nil` if the module is not listed in any application spec. ### Application.get_env/3 (function) Returns the value for `key` in `app`'s environment. If the configuration parameter does not exist, the function returns the `default` value. > #### Warning {: .warning} > > You must use this function to read only your own application > environment. Do not read the environment of other applications. ### Examples - Application.get_env/3 (function) `get_env/3` is commonly used to read the configuration of your OTP applications. Since Mix configurations are commonly used to configure applications, we will use this as a point of illustration. Consider a new application `:my_app`. `:my_app` contains a database engine which supports a pool of databases. The database engine needs to know the configuration for each of those databases, and that configuration is supplied by key-value pairs in environment of `:my_app`. config :my_app, Databases.RepoOne, # A database configuration ip: "localhost", port: 5433 config :my_app, Databases.RepoTwo, # Another database configuration (for the same OTP app) ip: "localhost", port: 20717 config :my_app, my_app_databases: [Databases.RepoOne, Databases.RepoTwo] Our database engine used by `:my_app` needs to know what databases exist, and what the database configurations are. The database engine can make a call to `Application.get_env(:my_app, :my_app_databases, [])` to retrieve the list of databases (specified by module names). The engine can then traverse each repository in the list and call `Application.get_env(:my_app, Databases.RepoOne)` and so forth to retrieve the configuration of each one. In this case, each configuration will be a keyword list, so you can use the functions in the `Keyword` module or even the `Access` module to traverse it, for example: config = Application.get_env(:my_app, Databases.RepoOne) config[:ip] ### Application.load/1 (function) Loads the given `app`. In order to be loaded, an `.app` file must be in the load paths. All `:included_applications` will also be loaded. Loading the application does not start it nor load its modules, but it does load its environment. ### Application.loaded_applications/0 (function) Returns a list with information about the applications which have been loaded. ### Application.prep_stop/1 (callback) Called before stopping the application. This function is called before the top-level supervisor is terminated. It receives the state returned by `c:start/2`, if it did, or `[]` otherwise. The return value is later passed to `c:stop/1`. ### Application.put_all_env/2 (function) Puts the environment for multiple applications at the same time. The given config should not: * have the same application listed more than once * have the same key inside the same application listed more than once If those conditions are not met, this function will raise. This function receives the same options as `put_env/4`. Returns `:ok`. ### Examples - Application.put_all_env/2 (function) Application.put_all_env( my_app: [ key: :value, another_key: :another_value ], another_app: [ key: :value ] ) ### Application.put_env/4 (function) Puts the `value` in `key` for the given `app`. > #### Compile environment {: .warning} > > Do not use this function to change environment variables read > via `Application.compile_env/2`. The compile environment must > be exclusively set before compilation, in your config files. ### Options - Application.put_env/4 (function) * `:timeout` - the timeout for the change (defaults to `5_000` milliseconds) * `:persistent` - persists the given value on application load and reloads If `put_env/4` is called before the application is loaded, the application environment values specified in the `.app` file will override the ones previously set. The `:persistent` option can be set to `true` when there is a need to guarantee parameters set with this function will not be overridden by the ones defined in the application resource file on load. This means persistent values will stick after the application is loaded and also on application reload. ### Application.spec/1 (function) Returns the spec for `app`. The following keys are returned: * `:description` * `:id` * `:vsn` * `:modules` * `:maxP` * `:maxT` * `:registered` * `:included_applications` * `:optional_applications` * `:applications` * `:mod` * `:start_phases` For a description of all fields, see [Erlang's application specification](https://www.erlang.org/doc/man/app). Note the environment is not returned as it can be accessed via `fetch_env/2`. Returns `nil` if the application is not loaded. ### Application.spec/2 (function) Returns the value for `key` in `app`'s specification. See `spec/1` for the supported keys. If the given specification parameter does not exist, this function will raise. Returns `nil` if the application is not loaded. ### Application.start/2 (function) Starts the given `app` with `t:restart_type/0`. If the `app` is not loaded, the application will first be loaded using `load/1`. Any included application, defined in the `:included_applications` key of the `.app` file will also be loaded, but they won't be started. Furthermore, all applications listed in the `:applications` key must be explicitly started before this application is. If not, `{:error, {:not_started, app}}` is returned, where `app` is the name of the missing application. In case you want to automatically load **and start** all of `app`'s dependencies, see `ensure_all_started/2`. ### Application.start/2 (callback) Called when an application is started. This function is called when an application is started using `Application.start/2` (and functions on top of that, such as `Application.ensure_started/2`). This function should start the top-level process of the application (which should be the top supervisor of the application's supervision tree if the application follows the OTP design principles around supervision). `start_type` defines how the application is started: * `:normal` - used if the startup is a normal startup or if the application is distributed and is started on the current node because of a failover from another node and the application specification key `:start_phases` is `:undefined`. * `{:takeover, node}` - used if the application is distributed and is started on the current node because of a failover on the node `node`. * `{:failover, node}` - used if the application is distributed and is started on the current node because of a failover on node `node`, and the application specification key `:start_phases` is not `:undefined`. `start_args` are the arguments passed to the application in the `:mod` specification key (for example, `mod: {MyApp, [:my_args]}`). This function should either return `{:ok, pid}` or `{:ok, pid, state}` if startup is successful. `pid` should be the PID of the top supervisor. `state` can be an arbitrary term, and if omitted will default to `[]`; if the application is later stopped, `state` is passed to the `stop/1` callback (see the documentation for the `c:stop/1` callback for more information). `use Application` provides no default implementation for the `start/2` callback. ### Application.start_phase/3 (callback) Starts an application in synchronous phases. This function is called after `start/2` finishes but before `Application.start/2` returns. It will be called once for every start phase defined in the application's (and any included applications') specification, in the order they are listed in. ### Application.started_applications/1 (function) Returns a list with information about the applications which are currently running. ### Application.stop/1 (function) Stops the given `app`. When stopped, the application is still loaded. ### Application.stop/1 (callback) Called after an application has been stopped. This function is called after an application has been stopped, i.e., after its supervision tree has been stopped. It should do the opposite of what the `c:start/2` callback did, and should perform any necessary cleanup. The return value of this callback is ignored. `state` is the state returned by `c:start/2`, if it did, or `[]` otherwise. If the optional callback `c:prep_stop/1` is present, `state` is its return value instead. `use Application` defines a default implementation of this function which does nothing and just returns `:ok`. ### Application.unload/1 (function) Unloads the given `app`. It will also unload all `:included_applications`. Note that the function does not purge the application modules. ### Application.app/0 (type) ### Application.application_key/0 (type) ### Application.key/0 (type) ### Application.restart_type/0 (type) Specifies the type of the application: * `:permanent` - if `app` terminates, all other applications and the entire node are also terminated. * `:transient` - if `app` terminates with `:normal` reason, it is reported but no other applications are terminated. If a transient application terminates abnormally, all other applications and the entire node are also terminated. * `:temporary` - if `app` terminates, it is reported but no other applications are terminated (the default). Note that it is always possible to stop an application explicitly by calling `stop/1`. Regardless of the type of the application, no other applications will be affected. Note also that the `:transient` type is of little practical use, since when a supervision tree terminates, the reason is set to `:shutdown`, not `:normal`. ### Application.start_type/0 (type) ### Application.state/0 (type) ### Application.value/0 (type) ### Config (module) A simple keyword-based configuration API. ### Example - Config (module) This module is most commonly used to define application configuration, typically in `config/config.exs`: import Config config :some_app, key1: "value1", key2: "value2" import_config "#{config_env()}.exs" `import Config` will import the functions `config/2`, `config/3` `config_env/0`, `config_target/0`, and `import_config/1` to help you manage your configuration. `config/2` and `config/3` are used to define key-value configuration for a given application. Once Mix starts, it will automatically evaluate the configuration file and persist the configuration above into `:some_app`'s application environment, which can be accessed in as follows: "value1" = Application.fetch_env!(:some_app, :key1) Finally, the line `import_config "#{config_env()}.exs"` will import other config files based on the current configuration environment, such as `config/dev.exs` and `config/test.exs`. `Config` also provides a low-level API for evaluating and reading configuration, under the `Config.Reader` module. > #### Avoid application environment in libraries {: .info} > > If you are writing a library to be used by other developers, > it is generally recommended to avoid the application environment, as the > application environment is effectively a global storage. Also note that > the `config/config.exs` of a library is not evaluated when the library is > used as a dependency, as configuration is always meant to configure the > current project. For more information, see ["Using application configuration for > libraries"](design-anti-patterns.md#using-application-configuration-for-libraries). ### Migrating from `use Mix.Config` - Config (module) The `Config` module in Elixir was introduced in v1.9 as a replacement to `use Mix.Config`, which was specific to Mix and has been deprecated. You can leverage `Config` instead of `use Mix.Config` in three steps. The first step is to replace `use Mix.Config` at the top of your config files by `import Config`. The second is to make sure your `import_config/1` calls do not have a wildcard character. If so, you need to perform the wildcard lookup manually. For example, if you did: import_config "../apps/*/config/config.exs" It has to be replaced by: for config <- "../apps/*/config/config.exs" |> Path.expand(__DIR__) |> Path.wildcard() do import_config config end The last step is to replace all `Mix.env()` calls in the config files with `config_env()`. Keep in mind you must also avoid using `Mix.env()` inside your project files. To check the environment at _runtime_, you may add a configuration key: # config.exs ... config :my_app, env: config_env() Then, in other scripts and modules, you may get the environment with `Application.fetch_env!/2`: # router.exs ... if Application.fetch_env!(:my_app, :env) == :prod do ... end The only places where you may access functions from the `Mix` module are the `mix.exs` file and inside custom Mix tasks, which are always within the `Mix.Tasks` namespace. ## `config/runtime.exs` For runtime configuration, you can use the `config/runtime.exs` file. It is executed right before applications start in both Mix and releases (assembled with `mix release`). ### Config.config/2 (function) Configures the given `root_key`. Keyword lists are always deep-merged. ### Examples - Config.config/2 (function) The given `opts` are merged into the existing configuration for the given `root_key`. Conflicting keys are overridden by the ones specified in `opts`, unless they are keywords, which are deep merged recursively. For example, the application configuration below config :logger, level: :warn, backends: [:console] config :logger, level: :info, truncate: 1024 will have a final configuration for `:logger` of: [level: :info, backends: [:console], truncate: 1024] ### Config.config/3 (function) Configures the given `key` for the given `root_key`. Keyword lists are always deep merged. ### Examples - Config.config/3 (function) The given `opts` are merged into the existing values for `key` in the given `root_key`. Conflicting keys are overridden by the ones specified in `opts`, unless they are keywords, which are deep merged recursively. For example, the application configuration below config :ecto, Repo, log_level: :warn, adapter: Ecto.Adapters.Postgres, metadata: [read_only: true] config :ecto, Repo, log_level: :info, pool_size: 10, metadata: [replica: true] will have a final value of the configuration for the `Repo` key in the `:ecto` application of: Application.get_env(:ecto, Repo) #=> [ #=> log_level: :info, #=> pool_size: 10, #=> adapter: Ecto.Adapters.Postgres, #=> metadata: [read_only: true, replica: true] #=> ] ### Config.config_env/0 (macro) Returns the environment this configuration file is executed on. In Mix projects this function returns the environment this configuration file is executed on. In releases, the environment when `mix release` ran. This is most often used to execute conditional code: if config_env() == :prod do config :my_app, :debug, false end ### Config.config_target/0 (macro) Returns the target this configuration file is executed on. This is most often used to execute conditional code: if config_target() == :host do config :my_app, :debug, false end ### Config.import_config/1 (macro) Imports configuration from the given file. In case the file doesn't exist, an error is raised. If file is a relative, it will be expanded relatively to the directory the current configuration file is in. ### Examples - Config.import_config/1 (macro) This is often used to emulate configuration across environments: import_config "#{config_env()}.exs" Note, however, some configuration files, such as `config/runtime.exs` does not support imports, as they are meant to be copied across systems. ### Config.read_config/1 (function) Reads the configuration for the given root key. This function only reads the configuration from a previous `config/2` or `config/3` call. If `root_key` points to an application, it does not read its actual application environment. Its main use case is to make it easier to access and share configuration values across files. If the `root_key` was not configured, it returns `nil`. ### Examples - Config.read_config/1 (function) # In config/config.exs config :my_app, foo: :bar # In config/dev.exs config :another_app, foo: read_config(:my_app)[:foo] || raise "missing parent configuration" ### Config.Provider (behaviour) Specifies a provider API that loads configuration during boot. Config providers are typically used during releases to load external configuration while the system boots. This is done by starting the VM with the minimum amount of applications running, then invoking all of the providers, and then restarting the system. This requires a mutable configuration file on disk, as the results of the providers are written to the file system. For more information on runtime configuration, see `mix release`. ### Multiple config files - Config.Provider (behaviour) One common use of config providers is to specify multiple configuration files in a release. Elixir ships with one provider, called `Config.Reader`, which is capable of handling Elixir's built-in config files. For example, imagine you want to list some basic configuration on Mix's built-in `config/runtime.exs` file, but you also want to support additional configuration files. To do so, you can add this inside the `def project` portion of your `mix.exs`: releases: [ demo: [ config_providers: [ {Config.Reader, {:system, "RELEASE_ROOT", "/extra_config.exs"}} ] ] ] You can place this `extra_config.exs` file in your release in multiple ways: 1. If it is available on the host when assembling the release, you can place it on "rel/overlays/extra_config.exs" and it will be automatically copied to the release root 2. If it is available on the target during deployment, you can simply copy it to the release root as a step in your deployment Now once the system boots, it will load both `config/runtime.exs` and `extra_config.exs` early in the boot process. You can learn more options on `Config.Reader`. ### Custom config provider - Config.Provider (behaviour) You can also implement custom config providers, similar to how `Config.Reader` works. For example, imagine you need to load some configuration from a JSON file and load that into the system. Said configuration provider would look like: defmodule JSONConfigProvider do @behaviour Config.Provider # Let's pass the path to the JSON file as config @impl true def init(path) when is_binary(path), do: path @impl true def load(config, path) do # We need to start any app we may depend on. {:ok, _} = Application.ensure_all_started(:jason) json = path |> File.read!() |> Jason.decode!() Config.Reader.merge( config, my_app: [ some_value: json["my_app_some_value"], another_value: json["my_app_another_value"], ] ) end end Then, when specifying your release, you can specify the provider in the release configuration: releases: [ demo: [ config_providers: [ {JSONConfigProvider, "/etc/config.json"} ] ] ] ### Config.Provider.init/1 (callback) Invoked when initializing a config provider. A config provider is typically initialized on the machine where the system is assembled and not on the target machine. The `c:init/1` callback is useful to verify the arguments given to the provider and prepare the state that will be given to `c:load/2`. Furthermore, because the state returned by `c:init/1` can be written to text-based config files, it should be restricted only to simple data types, such as integers, strings, atoms, tuples, maps, and lists. Entries such as PIDs, references, and functions cannot be serialized. ### Config.Provider.load/2 (callback) Loads configuration (typically during system boot). It receives the current `config` and the `state` returned by `c:init/1`. Then, you typically read the extra configuration from an external source and merge it into the received `config`. Merging should be done with `Config.Reader.merge/2`, as it performs deep merge. It should return the updated config. Note that `c:load/2` is typically invoked very early in the boot process, therefore if you need to use an application in the provider, it is your responsibility to start it. ### Config.Provider.resolve_config_path!/1 (function) Resolves a `t:config_path/0` to an actual path. ### Config.Provider.validate_config_path!/1 (function) Validates a `t:config_path/0`. ### Config.Provider.config/0 (type) ### Config.Provider.config_path/0 (type) A path pointing to a configuration file. Since configuration files are often accessed on target machines, it can be expressed either as: * a binary representing an absolute path * a `{:system, system_var, path}` tuple where the config is the concatenation of the environment variable `system_var` with the given `path` ### Config.Provider.state/0 (type) ### Config.Reader (module) API for reading config files defined with `Config`. ### As a provider - Config.Reader (module) `Config.Reader` can also be used as a `Config.Provider`. A config provider is used during releases to customize how applications are configured. When used as a provider, it expects a single argument: the configuration path (as outlined in `t:Config.Provider.config_path/0`) for the file to be read and loaded during the system boot. For example, if you expect the target system to have a config file in an absolute path, you can add this inside the `def project` portion of your `mix.exs`: releases: [ demo: [ config_providers: [ {Config.Reader, "/etc/config.exs"} ] ] ] Or if you want to read a custom path inside the release: config_providers: [{Config.Reader, {:system, "RELEASE_ROOT", "/config.exs"}}] You can also pass a keyword list of options to the reader, where the `:path` is a required key: config_providers: [ {Config.Reader, path: "/etc/config.exs", env: :prod, imports: :disabled} ] Remember Mix already loads `config/runtime.exs` by default. For more examples and scenarios, see the `Config.Provider` module. ### Config.Reader.eval!/3 (function) Evaluates the configuration `contents` for the given `file`. Accepts the same options as `read!/2`. ### Config.Reader.merge/2 (function) Merges two configurations. The configurations are merged together with the values in the second one having higher preference than the first in case of conflicts. In case both values are set to keyword lists, it deep merges them. ### Examples - Config.Reader.merge/2 (function) iex> Config.Reader.merge([app: [k: :v1]], [app: [k: :v2]]) [app: [k: :v2]] iex> Config.Reader.merge([app: [k: [v1: 1, v2: 2]]], [app: [k: [v2: :a, v3: :b]]]) [app: [k: [v1: 1, v2: :a, v3: :b]]] iex> Config.Reader.merge([app1: []], [app2: []]) [app1: [], app2: []] ### Config.Reader.read!/2 (function) Reads the configuration file. ### Options - Config.Reader.read!/2 (function) * `:imports` - a list of already imported paths or `:disabled` to disable imports * `:env` - the environment the configuration file runs on. See `Config.config_env/0` for sample usage * `:target` - the target the configuration file runs on. See `Config.config_target/0` for sample usage ### Config.Reader.read_imports!/2 (function) Reads the given configuration file and returns the configuration with its imports. Accepts the same options as `read!/2`. Although note the `:imports` option cannot be disabled in `read_imports!/2`. ### DynamicSupervisor (behaviour) A supervisor optimized to only start children dynamically. The `Supervisor` module was designed to handle mostly static children that are started in the given order when the supervisor starts. A `DynamicSupervisor` starts with no children. Instead, children are started on demand via `start_child/2` and there is no ordering between children. This allows the `DynamicSupervisor` to hold millions of children by using efficient data structures and to execute certain operations, such as shutting down, concurrently. ### Examples - DynamicSupervisor (behaviour) A dynamic supervisor is started with no children and often a name: children = [ {DynamicSupervisor, name: MyApp.DynamicSupervisor, strategy: :one_for_one} ] Supervisor.start_link(children, strategy: :one_for_one) The options given in the child specification are documented in `start_link/1`. Once the dynamic supervisor is running, we can use it to start children on demand. Given this sample `GenServer`: defmodule Counter do use GenServer def start_link(initial) do GenServer.start_link(__MODULE__, initial) end def inc(pid) do GenServer.call(pid, :inc) end def init(initial) do {:ok, initial} end def handle_call(:inc, _, count) do {:reply, count, count + 1} end end We can use `start_child/2` with a child specification to start a `Counter` server: {:ok, counter1} = DynamicSupervisor.start_child(MyApp.DynamicSupervisor, {Counter, 0}) Counter.inc(counter1) #=> 0 {:ok, counter2} = DynamicSupervisor.start_child(MyApp.DynamicSupervisor, {Counter, 10}) Counter.inc(counter2) #=> 10 DynamicSupervisor.count_children(MyApp.DynamicSupervisor) #=> %{active: 2, specs: 2, supervisors: 0, workers: 2} ### Scalability and partitioning - DynamicSupervisor (behaviour) The `DynamicSupervisor` is a single process responsible for starting other processes. In some applications, the `DynamicSupervisor` may become a bottleneck. To address this, you can start multiple instances of the `DynamicSupervisor` and then pick a "random" instance to start the child on. Instead of: children = [ {DynamicSupervisor, name: MyApp.DynamicSupervisor} ] and: DynamicSupervisor.start_child(MyApp.DynamicSupervisor, {Counter, 0}) You can do this: children = [ {PartitionSupervisor, child_spec: DynamicSupervisor, name: MyApp.DynamicSupervisors} ] and then: DynamicSupervisor.start_child( {:via, PartitionSupervisor, {MyApp.DynamicSupervisors, self()}}, {Counter, 0} ) In the code above, we start a partition supervisor that will by default start a dynamic supervisor for each core in your machine. Then, instead of calling the `DynamicSupervisor` by name, you call it through the partition supervisor, using `self()` as the routing key. This means each process will be assigned one of the existing dynamic supervisors. Read the `PartitionSupervisor` docs for more information. ### Module-based supervisors - DynamicSupervisor (behaviour) Similar to `Supervisor`, dynamic supervisors also support module-based supervisors. defmodule MyApp.DynamicSupervisor do # Automatically defines child_spec/1 use DynamicSupervisor def start_link(init_arg) do DynamicSupervisor.start_link(__MODULE__, init_arg, name: __MODULE__) end @impl true def init(_init_arg) do DynamicSupervisor.init(strategy: :one_for_one) end end See the `Supervisor` docs for a discussion of when you may want to use module-based supervisors. A `@doc` annotation immediately preceding `use DynamicSupervisor` will be attached to the generated `child_spec/1` function. > #### `use DynamicSupervisor` {: .info} > > When you `use DynamicSupervisor`, the `DynamicSupervisor` module will > set `@behaviour DynamicSupervisor` and define a `child_spec/1` > function, so your module can be used as a child in a supervision tree. ### Name registration - DynamicSupervisor (behaviour) A supervisor is bound to the same name registration rules as a `GenServer`. Read more about these rules in the documentation for `GenServer`. ### Migrating from Supervisor's :simple_one_for_one - DynamicSupervisor (behaviour) In case you were using the deprecated `:simple_one_for_one` strategy from the `Supervisor` module, you can migrate to the `DynamicSupervisor` in few steps. Imagine the given "old" code: defmodule MySupervisor do use Supervisor def start_link(init_arg) do Supervisor.start_link(__MODULE__, init_arg, name: __MODULE__) end def start_child(foo, bar, baz) do # This will start child by calling MyWorker.start_link(init_arg, foo, bar, baz) Supervisor.start_child(__MODULE__, [foo, bar, baz]) end @impl true def init(init_arg) do children = [ # Or the deprecated: worker(MyWorker, [init_arg]) %{id: MyWorker, start: {MyWorker, :start_link, [init_arg]}} ] Supervisor.init(children, strategy: :simple_one_for_one) end end It can be upgraded to the DynamicSupervisor like this: defmodule MySupervisor do use DynamicSupervisor def start_link(init_arg) do DynamicSupervisor.start_link(__MODULE__, init_arg, name: __MODULE__) end def start_child(foo, bar, baz) do # If MyWorker is not using the new child specs, we need to pass a map: # spec = %{id: MyWorker, start: {MyWorker, :start_link, [foo, bar, baz]}} spec = {MyWorker, foo: foo, bar: bar, baz: baz} DynamicSupervisor.start_child(__MODULE__, spec) end @impl true def init(init_arg) do DynamicSupervisor.init( strategy: :one_for_one, extra_arguments: [init_arg] ) end end The difference is that the `DynamicSupervisor` expects the child specification at the moment `start_child/2` is called, and no longer on the init callback. If there are any initial arguments given on initialization, such as `[initial_arg]`, it can be given in the `:extra_arguments` flag on `DynamicSupervisor.init/1`. ### DynamicSupervisor.child_spec/1 (function) Returns a specification to start a dynamic supervisor under a supervisor. It accepts the same options as `start_link/1`. See `Supervisor` for more information about child specifications. ### DynamicSupervisor.count_children/1 (function) Returns a map containing count values for the supervisor. The map contains the following keys: * `:specs` - the number of children processes * `:active` - the count of all actively running child processes managed by this supervisor * `:supervisors` - the count of all supervisors whether or not the child process is still alive * `:workers` - the count of all workers, whether or not the child process is still alive ### DynamicSupervisor.init/1 (function) Receives a set of `options` that initializes a dynamic supervisor. This is typically invoked at the end of the `c:init/1` callback of module-based supervisors. See the "Module-based supervisors" section in the module documentation for more information. It accepts the same `options` as `start_link/1` (except for `:name`) and it returns a tuple containing the supervisor options. ### Examples - DynamicSupervisor.init/1 (function) def init(_arg) do DynamicSupervisor.init(max_children: 1000) end ### DynamicSupervisor.init/1 (callback) Callback invoked to start the supervisor and during hot code upgrades. Developers typically invoke `DynamicSupervisor.init/1` at the end of their init callback to return the proper supervision flags. ### DynamicSupervisor.start_child/2 (function) Dynamically adds a child specification to `supervisor` and starts that child. `child_spec` should be a valid child specification as detailed in the "Child specification" section of the documentation for `Supervisor`. The child process will be started as defined in the child specification. Note that while the `:id` field is still required in the spec, the value is ignored and therefore does not need to be unique. If the child process start function returns `{:ok, child}` or `{:ok, child, info}`, then child specification and PID are added to the supervisor and this function returns the same value. If the child process start function returns `:ignore`, then no child is added to the supervision tree and this function returns `:ignore` too. If the child process start function returns an error tuple or an erroneous value, or if it fails, the child specification is discarded and this function returns `{:error, error}` where `error` is the error or erroneous value returned from child process start function, or failure reason if it fails. If the supervisor already has N children in a way that N exceeds the amount of `:max_children` set on the supervisor initialization (see `init/1`), then this function returns `{:error, :max_children}`. ### DynamicSupervisor.start_link/1 (function) Starts a supervisor with the given options. This function is typically not invoked directly, instead it is invoked when using a `DynamicSupervisor` as a child of another supervisor: children = [ {DynamicSupervisor, name: MySupervisor} ] If the supervisor is successfully spawned, this function returns `{:ok, pid}`, where `pid` is the PID of the supervisor. If the supervisor is given a name and a process with the specified name already exists, the function returns `{:error, {:already_started, pid}}`, where `pid` is the PID of that process. Note that a supervisor started with this function is linked to the parent process and exits not only on crashes but also if the parent process exits with `:normal` reason. ### Options - DynamicSupervisor.start_link/1 (function) * `:name` - registers the supervisor under the given name. The supported values are described under the "Name registration" section in the `GenServer` module docs. * `:strategy` - the restart strategy option. The only supported value is `:one_for_one` which means that no other child is terminated if a child process terminates. You can learn more about strategies in the `Supervisor` module docs. * `:max_restarts` - the maximum number of restarts allowed in a time frame. Defaults to `3`. * `:max_seconds` - the time frame in which `:max_restarts` applies. Defaults to `5`. * `:max_children` - the maximum amount of children to be running under this supervisor at the same time. When `:max_children` is exceeded, `start_child/2` returns `{:error, :max_children}`. Defaults to `:infinity`. * `:extra_arguments` - arguments that are prepended to the arguments specified in the child spec given to `start_child/2`. Defaults to an empty list. * Any of the standard [GenServer options](`t:GenServer.option/0`) ### DynamicSupervisor.start_link/3 (function) Starts a module-based supervisor process with the given `module` and `init_arg`. To start the supervisor, the `c:init/1` callback will be invoked in the given `module`, with `init_arg` as its argument. The `c:init/1` callback must return a supervisor specification which can be created with the help of the `init/1` function. If the `c:init/1` callback returns `:ignore`, this function returns `:ignore` as well and the supervisor terminates with reason `:normal`. If it fails or returns an incorrect value, this function returns `{:error, term}` where `term` is a term with information about the error, and the supervisor terminates with reason `term`. The `:name` option can also be given in order to register a supervisor name, the supported values are described in the "Name registration" section in the `GenServer` module docs. If the supervisor is successfully spawned, this function returns `{:ok, pid}`, where `pid` is the PID of the supervisor. If the supervisor is given a name and a process with the specified name already exists, the function returns `{:error, {:already_started, pid}}`, where `pid` is the PID of that process. Note that a supervisor started with this function is linked to the parent process and exits not only on crashes but also if the parent process exits with `:normal` reason. ### Options - DynamicSupervisor.start_link/3 (function) This function accepts any regular [`GenServer` options](`t:GenServer.option/0`). Options specific to `DynamicSupervisor` must be returned from the `c:init/1` callback. ### DynamicSupervisor.stop/3 (function) Synchronously stops the given supervisor with the given `reason`. It returns `:ok` if the supervisor terminates with the given reason. If it terminates with another reason, the call exits. This function keeps OTP semantics regarding error reporting. If the reason is any other than `:normal`, `:shutdown` or `{:shutdown, _}`, an error report is logged. ### DynamicSupervisor.terminate_child/2 (function) Terminates the given child identified by `pid`. If successful, this function returns `:ok`. If there is no process with the given PID, this function returns `{:error, :not_found}`. ### DynamicSupervisor.which_children/1 (function) Returns a list with information about all children. Note that calling this function when supervising a large number of children under low memory conditions can cause an out of memory exception. This function returns a list of tuples containing: * `id` - it is always `:undefined` for dynamic supervisors * `child` - the PID of the corresponding child process or the atom `:restarting` if the process is about to be restarted * `type` - `:worker` or `:supervisor` as defined in the child specification * `modules` - as defined in the child specification ### DynamicSupervisor.init_option/0 (type) Options given to `start_link/1` and `init/1` functions ### DynamicSupervisor.on_start_child/0 (type) Return values of `start_child` functions ### DynamicSupervisor.strategy/0 (type) Supported strategies ### DynamicSupervisor.sup_flags/0 (type) The supervisor flags returned on init ### GenServer (behaviour) A behaviour module for implementing the server of a client-server relation. A GenServer is a process like any other Elixir process and it can be used to keep state, execute code asynchronously and so on. The advantage of using a generic server process (GenServer) implemented using this module is that it will have a standard set of interface functions and include functionality for tracing and error reporting. It will also fit into a supervision tree. ```mermaid graph BT C(Client #3) ~~~ B(Client #2) ~~~ A(Client #1) A & B & C -->|request| GenServer GenServer -.->|reply| A & B & C ``` ### Example - GenServer (behaviour) The GenServer behaviour abstracts the common client-server interaction. Developers are only required to implement the callbacks and functionality they are interested in. Let's start with a code example and then explore the available callbacks. Imagine we want to implement a service with a GenServer that works like a stack, allowing us to push and pop elements. We'll customize a generic GenServer with our own module by implementing three callbacks. `c:init/1` transforms our initial argument to the initial state for the GenServer. `c:handle_call/3` fires when the server receives a synchronous `pop` message, popping an element from the stack and returning it to the user. `c:handle_cast/2` will fire when the server receives an asynchronous `push` message, pushing an element onto the stack: defmodule Stack do use GenServer # Callbacks @impl true def init(elements) do initial_state = String.split(elements, ",", trim: true) {:ok, initial_state} end @impl true def handle_call(:pop, _from, state) do [to_caller | new_state] = state {:reply, to_caller, new_state} end @impl true def handle_cast({:push, element}, state) do new_state = [element | state] {:noreply, new_state} end end We leave the process machinery of startup, message passing, and the message loop to the GenServer behaviour and focus only on the stack implementation. We can now use the GenServer API to interact with the service by creating a process and sending it messages: # Start the server {:ok, pid} = GenServer.start_link(Stack, "hello,world") # This is the client GenServer.call(pid, :pop) #=> "hello" GenServer.cast(pid, {:push, "elixir"}) #=> :ok GenServer.call(pid, :pop) #=> "elixir" We start our `Stack` by calling `start_link/2`, passing the module with the server implementation and its initial argument with a comma-separated list of elements. The GenServer behaviour calls the `c:init/1` callback to establish the initial GenServer state. From this point on, the GenServer has control so we interact with it by sending two types of messages on the client. **call** messages expect a reply from the server (and are therefore synchronous) while **cast** messages do not. Each call to `GenServer.call/3` results in a message that must be handled by the `c:handle_call/3` callback in the GenServer. A `cast/2` message must be handled by `c:handle_cast/2`. `GenServer` supports 8 callbacks, but only `c:init/1` is required. > #### `use GenServer` {: .info} > > When you `use GenServer`, the `GenServer` module will > set `@behaviour GenServer` and define a `child_spec/1` > function, so your module can be used as a child > in a supervision tree. ### Client / Server APIs - GenServer (behaviour) Although in the example above we have used `GenServer.start_link/3` and friends to directly start and communicate with the server, most of the time we don't call the `GenServer` functions directly. Instead, we wrap the calls in new functions representing the public API of the server. These thin wrappers are called the **client API**. Here is a better implementation of our Stack module: defmodule Stack do use GenServer # Client def start_link(default) when is_binary(default) do GenServer.start_link(__MODULE__, default) end def push(pid, element) do GenServer.cast(pid, {:push, element}) end def pop(pid) do GenServer.call(pid, :pop) end # Server (callbacks) @impl true def init(elements) do initial_state = String.split(elements, ",", trim: true) {:ok, initial_state} end @impl true def handle_call(:pop, _from, state) do [to_caller | new_state] = state {:reply, to_caller, new_state} end @impl true def handle_cast({:push, element}, state) do new_state = [element | state] {:noreply, new_state} end end In practice, it is common to have both server and client functions in the same module. If the server and/or client implementations are growing complex, you may want to have them in different modules. The following diagram summarizes the interactions between client and server. Both Client and Server are processes and communication happens via messages (continuous line). The Server <-> Module interaction happens when the GenServer process calls your code (dotted lines): ```mermaid sequenceDiagram participant C as Client (Process) participant S as Server (Process) participant M as Module (Code) note right of C: Typically started by a supervisor C->>+S: GenServer.start_link(module, arg, options) S-->>+M: init(arg) M-->>-S: {:ok, state} | :ignore | {:error, reason} S->>-C: {:ok, pid} | :ignore | {:error, reason} note right of C: call is synchronous C->>+S: GenServer.call(pid, message) S-->>+M: handle_call(message, from, state) M-->>-S: {:reply, reply, state} | {:stop, reason, reply, state} S->>-C: reply note right of C: cast is asynchronous C-)S: GenServer.cast(pid, message) S-->>+M: handle_cast(message, state) M-->>-S: {:noreply, state} | {:stop, reason, state} note right of C: send is asynchronous C-)S: Kernel.send(pid, message) S-->>+M: handle_info(message, state) M-->>-S: {:noreply, state} | {:stop, reason, state} ``` ### How to supervise - GenServer (behaviour) A `GenServer` is most commonly started under a supervision tree. When we invoke `use GenServer`, it automatically defines a `child_spec/1` function that allows us to start the `Stack` directly under a supervisor. To start a default stack of `["hello", "world"]` under a supervisor, we can do: children = [ {Stack, "hello,world"} ] Supervisor.start_link(children, strategy: :one_for_all) Note that specifying a module `MyServer` would be the same as specifying the tuple `{MyServer, []}`. `use GenServer` also accepts a list of options which configures the child specification and therefore how it runs under a supervisor. The generated `child_spec/1` can be customized with the following options: * `:id` - the child specification identifier, defaults to the current module * `:restart` - when the child should be restarted, defaults to `:permanent` * `:shutdown` - how to shut down the child, either immediately or by giving it time to shut down For example: use GenServer, restart: :transient, shutdown: 10_000 See the "Child specification" section in the `Supervisor` module for more detailed information. The `@doc` annotation immediately preceding `use GenServer` will be attached to the generated `child_spec/1` function. When stopping the GenServer, for example by returning a `{:stop, reason, new_state}` tuple from a callback, the exit reason is used by the supervisor to determine whether the GenServer needs to be restarted. See the "Exit reasons and restarts" section in the `Supervisor` module. ### Name registration - GenServer (behaviour) Both `start_link/3` and `start/3` support the `GenServer` to register a name on start via the `:name` option. Registered names are also automatically cleaned up on termination. The supported values are: * an atom - the GenServer is registered locally (to the current node) with the given name using `Process.register/2`. * `{:global, term}` - the GenServer is registered globally with the given term using the functions in the [`:global` module](`:global`). * `{:via, module, term}` - the GenServer is registered with the given mechanism and name. The `:via` option expects a module that exports `register_name/2`, `unregister_name/1`, `whereis_name/1` and `send/2`. One such example is the [`:global` module](`:global`) which uses these functions for keeping the list of names of processes and their associated PIDs that are available globally for a network of Elixir nodes. Elixir also ships with a local, decentralized and scalable registry called `Registry` for locally storing names that are generated dynamically. For example, we could start and register our `Stack` server locally as follows: # Start the server and register it locally with name MyStack {:ok, _} = GenServer.start_link(Stack, "hello", name: MyStack) # Now messages can be sent directly to MyStack GenServer.call(MyStack, :pop) #=> "hello" Once the server is started, the remaining functions in this module (`call/3`, `cast/2`, and friends) will also accept an atom, or any `{:global, ...}` or `{:via, ...}` tuples. In general, the following formats are supported: * a PID * an atom if the server is locally registered * `{atom, node}` if the server is locally registered at another node * `{:global, term}` if the server is globally registered * `{:via, module, name}` if the server is registered through an alternative registry If there is an interest to register dynamic names locally, do not use atoms, as atoms are never garbage-collected and therefore dynamically generated atoms won't be garbage-collected. For such cases, you can set up your own local registry by using the `Registry` module. ### Receiving "regular" messages - GenServer (behaviour) The goal of a `GenServer` is to abstract the "receive" loop for developers, automatically handling system messages, supporting code change, synchronous calls and more. Therefore, you should never call your own "receive" inside the GenServer callbacks as doing so will cause the GenServer to misbehave. Besides the synchronous and asynchronous communication provided by `call/3` and `cast/2`, "regular" messages sent by functions such as `send/2`, `Process.send_after/4` and similar, can be handled inside the `c:handle_info/2` callback. `c:handle_info/2` can be used in many situations, such as handling monitor DOWN messages sent by `Process.monitor/1`. Another use case for `c:handle_info/2` is to perform periodic work, with the help of `Process.send_after/4`: defmodule MyApp.Periodically do use GenServer def start_link(_) do GenServer.start_link(__MODULE__, %{}) end @impl true def init(state) do # Schedule work to be performed on start schedule_work() {:ok, state} end @impl true def handle_info(:work, state) do # Do the desired work here # ... # Reschedule once more schedule_work() {:noreply, state} end defp schedule_work do # We schedule the work to happen in 2 hours (written in milliseconds). # Alternatively, one might write :timer.hours(2) Process.send_after(self(), :work, 2 * 60 * 60 * 1000) end end ### Timeouts - GenServer (behaviour) The return value of `c:init/1` or any of the `handle_*` callbacks may include a timeout value in milliseconds; if not, `:infinity` is assumed. The timeout can be used to detect a lull in incoming messages. The `timeout()` value is used as follows: * If the process has any message already waiting when the `timeout()` value is returned, the timeout is ignored and the waiting message is handled as usual. This means that even a timeout of `0` milliseconds is not guaranteed to execute (if you want to take another action immediately and unconditionally, use a `:continue` instruction instead). * If any message arrives before the specified number of milliseconds elapse, the timeout is cleared and that message is handled as usual. * Otherwise, when the specified number of milliseconds have elapsed with no message arriving, `handle_info/2` is called with `:timeout` as the first argument. ### When (not) to use a GenServer - GenServer (behaviour) So far, we have learned that a `GenServer` can be used as a supervised process that handles sync and async calls. It can also handle system messages, such as periodic messages and monitoring events. GenServer processes may also be named. A GenServer, or a process in general, must be used to model runtime characteristics of your system. A GenServer must never be used for code organization purposes. In Elixir, code organization is done by modules and functions, processes are not necessary. For example, imagine you are implementing a calculator and you decide to put all the calculator operations behind a GenServer: def add(a, b) do GenServer.call(__MODULE__, {:add, a, b}) end def subtract(a, b) do GenServer.call(__MODULE__, {:subtract, a, b}) end def handle_call({:add, a, b}, _from, state) do {:reply, a + b, state} end def handle_call({:subtract, a, b}, _from, state) do {:reply, a - b, state} end This is an anti-pattern not only because it convolutes the calculator logic but also because you put the calculator logic behind a single process that will potentially become a bottleneck in your system, especially as the number of calls grow. Instead just define the functions directly: def add(a, b) do a + b end def subtract(a, b) do a - b end If you don't need a process, then you don't need a process. Use processes only to model runtime properties, such as mutable state, concurrency and failures, never for code organization. ### Debugging with the :sys module - GenServer (behaviour) GenServers, as [special processes](https://www.erlang.org/doc/design_principles/spec_proc.html), can be debugged using the [`:sys` module](`:sys`). Through various hooks, this module allows developers to introspect the state of the process and trace system events that happen during its execution, such as received messages, sent replies and state changes. Let's explore the basic functions from the [`:sys` module](`:sys`) used for debugging: * `:sys.get_state/2` - allows retrieval of the state of the process. In the case of a GenServer process, it will be the callback module state, as passed into the callback functions as last argument. * `:sys.get_status/2` - allows retrieval of the status of the process. This status includes the process dictionary, if the process is running or is suspended, the parent PID, the debugger state, and the state of the behaviour module, which includes the callback module state (as returned by `:sys.get_state/2`). It's possible to change how this status is represented by defining the optional `c:GenServer.format_status/1` callback. * `:sys.trace/3` - prints all the system events to `:stdio`. * `:sys.statistics/3` - manages collection of process statistics. * `:sys.no_debug/2` - turns off all debug handlers for the given process. It is very important to switch off debugging once we're done. Excessive debug handlers or those that should be turned off, but weren't, can seriously damage the performance of the system. * `:sys.suspend/2` - allows to suspend a process so that it only replies to system messages but no other messages. A suspended process can be reactivated via `:sys.resume/2`. Let's see how we could use those functions for debugging the stack server we defined earlier. iex> {:ok, pid} = Stack.start_link("") iex> :sys.statistics(pid, true) # turn on collecting process statistics iex> :sys.trace(pid, true) # turn on event printing iex> Stack.push(pid, 1) *DBG* <0.122.0> got cast {push,1} *DBG* <0.122.0> new state [1] :ok iex> :sys.get_state(pid) [1] iex> Stack.pop(pid) *DBG* <0.122.0> got call pop from <0.80.0> *DBG* <0.122.0> sent 1 to <0.80.0>, new state [] 1 iex> :sys.statistics(pid, :get) {:ok, [ start_time: {{2016, 7, 16}, {12, 29, 41}}, current_time: {{2016, 7, 16}, {12, 29, 50}}, reductions: 117, messages_in: 2, messages_out: 0 ]} iex> :sys.no_debug(pid) # turn off all debug handlers :ok iex> :sys.get_status(pid) {:status, #PID<0.122.0>, {:module, :gen_server}, [ [ "$initial_call": {Stack, :init, 1}, # process dictionary "$ancestors": [#PID<0.80.0>, #PID<0.51.0>] ], :running, # :running | :suspended #PID<0.80.0>, # parent [], # debugger state [ header: 'Status for generic server <0.122.0>', # module status data: [ {'Status', :running}, {'Parent', #PID<0.80.0>}, {'Logged events', []} ], data: [{'State', [1]}] ] ]} ### Learn more - GenServer (behaviour) If you wish to find out more about GenServers, the Elixir Getting Started guide provides a tutorial-like introduction. The documentation and links in Erlang can also provide extra insight. * [GenServer - Elixir's Getting Started Guide](genservers.md) * [`:gen_server` module documentation](`:gen_server`) * [gen_server Behaviour - OTP Design Principles](https://www.erlang.org/doc/design_principles/gen_server_concepts.html) * [Clients and Servers - Learn You Some Erlang for Great Good!](http://learnyousomeerlang.com/clients-and-servers) ### GenServer.abcast/3 (function) Casts all servers locally registered as `name` at the specified nodes. This function returns immediately and ignores nodes that do not exist, or where the server name does not exist. See `multi_call/4` for more information. ### GenServer.call/3 (function) Makes a synchronous call to the `server` and waits for its reply. The client sends the given `request` to the server and waits until a reply arrives or a timeout occurs. `c:handle_call/3` will be called on the server to handle the request. `server` can be any of the values described in the "Name registration" section of the documentation for this module. ### Timeouts - GenServer.call/3 (function) `timeout` is an integer greater than zero which specifies how many milliseconds to wait for a reply, or the atom `:infinity` to wait indefinitely. The default value is `5000`. If no reply is received within the specified time, the function call fails and the caller exits. If the caller catches the failure and continues running, and the server is just late with the reply, it may arrive at any time later into the caller's message queue. The caller must in this case be prepared for this and discard any such garbage messages that are two-element tuples with a reference as the first element. ### GenServer.cast/2 (function) Casts a request to the `server` without waiting for a response. This function always returns `:ok` regardless of whether the destination `server` (or node) exists. Therefore it is unknown whether the destination `server` successfully handled the request. `server` can be any of the values described in the "Name registration" section of the documentation for this module. ### GenServer.code_change/3 (callback) Invoked to change the state of the `GenServer` when a different version of a module is loaded (hot code swapping) and the state's term structure should be changed. `old_vsn` is the previous version of the module (defined by the `@vsn` attribute) when upgrading. When downgrading the previous version is wrapped in a 2-tuple with first element `:down`. `state` is the current state of the `GenServer` and `extra` is any extra data required to change the state. Returning `{:ok, new_state}` changes the state to `new_state` and the code change is successful. Returning `{:error, reason}` fails the code change with reason `reason` and the state remains as the previous state. If `c:code_change/3` raises the code change fails and the loop will continue with its previous state. Therefore this callback does not usually contain side effects. This callback is optional. ### GenServer.format_status/1 (callback) This function is called by a `GenServer` process in the following situations: * [`:sys.get_status/1,2`](`:sys.get_status/1`) is invoked to get the `GenServer` status. * The `GenServer` process terminates abnormally and logs an error. This callback is used to limit the status of the process returned by [`:sys.get_status/1,2`](`:sys.get_status/1`) or sent to logger. The callback gets a map `status` describing the current status and shall return a map `new_status` with the same keys, but it may transform some values. Two possible use cases for this callback is to remove sensitive information from the state to prevent it from being printed in log files, or to compact large irrelevant status items that would only clutter the logs. ### Example - GenServer.format_status/1 (callback) @impl GenServer def format_status(status) do Map.new(status, fn {:state, state} -> {:state, Map.delete(state, :private_key)} {:message, {:password, _}} -> {:message, {:password, "redacted"}} key_value -> key_value end) end ### GenServer.format_status/2 (callback) ### GenServer.handle_call/3 (callback) Invoked to handle synchronous `call/3` messages. `call/3` will block until a reply is received (unless the call times out or nodes are disconnected). `request` is the request message sent by a `call/3`, `from` is a 2-tuple containing the caller's PID and a term that uniquely identifies the call, and `state` is the current state of the `GenServer`. Returning `{:reply, reply, new_state}` sends the response `reply` to the caller and continues the loop with new state `new_state`. Returning `{:reply, reply, new_state, timeout}` is similar to `{:reply, reply, new_state}` except that it also sets a timeout. See the "Timeouts" section in the module documentation for more information. Returning `{:reply, reply, new_state, :hibernate}` is similar to `{:reply, reply, new_state}` except the process is hibernated and will continue the loop once a message is in its message queue. However, if a message is already in the message queue, the process will continue the loop immediately. Hibernating a `GenServer` causes garbage collection and leaves a continuous heap that minimises the memory used by the process. Hibernating should not be used aggressively as too much time could be spent garbage collecting, which would delay the processing of incoming messages. Normally it should only be used when you are not expecting new messages to immediately arrive and minimising the memory of the process is shown to be beneficial. Returning `{:reply, reply, new_state, {:continue, continue_arg}}` is similar to `{:reply, reply, new_state}` except that `c:handle_continue/2` will be invoked immediately after with `continue_arg` as the first argument and `state` as the second one. Returning `{:noreply, new_state}` does not send a response to the caller and continues the loop with new state `new_state`. The response must be sent with `reply/2`. There are three main use cases for not replying using the return value: * To reply before returning from the callback because the response is known before calling a slow function. * To reply after returning from the callback because the response is not yet available. * To reply from another process, such as a task. When replying from another process the `GenServer` should exit if the other process exits without replying as the caller will be blocking awaiting a reply. Returning `{:noreply, new_state, timeout | :hibernate | {:continue, continue_arg}}` is similar to `{:noreply, new_state}` except a timeout, hibernation or continue occurs as with a `:reply` tuple. Returning `{:stop, reason, reply, new_state}` stops the loop and `c:terminate/2` is called with reason `reason` and state `new_state`. Then, the `reply` is sent as the response to call and the process exits with reason `reason`. Returning `{:stop, reason, new_state}` is similar to `{:stop, reason, reply, new_state}` except a reply is not sent. This callback is optional. If one is not implemented, the server will fail if a call is performed against it. ### GenServer.handle_cast/2 (callback) Invoked to handle asynchronous `cast/2` messages. `request` is the request message sent by a `cast/2` and `state` is the current state of the `GenServer`. Returning `{:noreply, new_state}` continues the loop with new state `new_state`. Returning `{:noreply, new_state, timeout}` is similar to `{:noreply, new_state}` except that it also sets a timeout. See the "Timeouts" section in the module documentation for more information. Returning `{:noreply, new_state, :hibernate}` is similar to `{:noreply, new_state}` except the process is hibernated before continuing the loop. See `c:handle_call/3` for more information. Returning `{:noreply, new_state, {:continue, continue_arg}}` is similar to `{:noreply, new_state}` except `c:handle_continue/2` will be invoked immediately after with `continue_arg` as the first argument and `state` as the second one. Returning `{:stop, reason, new_state}` stops the loop and `c:terminate/2` is called with the reason `reason` and state `new_state`. The process exits with reason `reason`. This callback is optional. If one is not implemented, the server will fail if a cast is performed against it. ### GenServer.handle_continue/2 (callback) Invoked to handle continue instructions. It is useful for performing work after initialization or for splitting the work in a callback in multiple steps, updating the process state along the way. Return values are the same as `c:handle_cast/2`. This callback is optional. If one is not implemented, the server will fail if a continue instruction is used. ### GenServer.handle_info/2 (callback) Invoked to handle all other messages. `msg` is the message and `state` is the current state of the `GenServer`. When a timeout occurs the message is `:timeout`. Return values are the same as `c:handle_cast/2`. This callback is optional. If one is not implemented, the received message will be logged. ### GenServer.init/1 (callback) Invoked when the server is started. `start_link/3` or `start/3` will block until it returns. `init_arg` is the argument term (second argument) passed to `start_link/3`. Returning `{:ok, state}` will cause `start_link/3` to return `{:ok, pid}` and the process to enter its loop. Returning `{:ok, state, timeout}` is similar to `{:ok, state}`, except that it also sets a timeout. See the "Timeouts" section in the module documentation for more information. Returning `{:ok, state, :hibernate}` is similar to `{:ok, state}` except the process is hibernated before entering the loop. See `c:handle_call/3` for more information on hibernation. Returning `{:ok, state, {:continue, continue_arg}}` is similar to `{:ok, state}` except that immediately after entering the loop, the `c:handle_continue/2` callback will be invoked with `continue_arg` as the first argument and `state` as the second one. Returning `:ignore` will cause `start_link/3` to return `:ignore` and the process will exit normally without entering the loop or calling `c:terminate/2`. If used when part of a supervision tree the parent supervisor will not fail to start nor immediately try to restart the `GenServer`. The remainder of the supervision tree will be started and so the `GenServer` should not be required by other processes. It can be started later with `Supervisor.restart_child/2` as the child specification is saved in the parent supervisor. The main use cases for this are: * The `GenServer` is disabled by configuration but might be enabled later. * An error occurred and it will be handled by a different mechanism than the `Supervisor`. Likely this approach involves calling `Supervisor.restart_child/2` after a delay to attempt a restart. Returning `{:stop, reason}` will cause `start_link/3` to return `{:error, reason}` and the process to exit with reason `reason` without entering the loop or calling `c:terminate/2`. ### GenServer.multi_call/4 (function) Calls all servers locally registered as `name` at the specified `nodes`. First, the `request` is sent to every node in `nodes`; then, the caller waits for the replies. This function returns a two-element tuple `{replies, bad_nodes}` where: * `replies` - is a list of `{node, reply}` tuples where `node` is the node that replied and `reply` is its reply * `bad_nodes` - is a list of nodes that either did not exist or where a server with the given `name` did not exist or did not reply `nodes` is a list of node names to which the request is sent. The default value is the list of all known nodes (including this node). ### Examples - GenServer.multi_call/4 (function) Assuming the `Stack` GenServer mentioned in the docs for the `GenServer` module is registered as `Stack` in the `:"foo@my-machine"` and `:"bar@my-machine"` nodes: GenServer.multi_call(Stack, :pop) #=> {[{:"foo@my-machine", :hello}, {:"bar@my-machine", :world}], []} ### GenServer.reply/2 (function) Replies to a client. This function can be used to explicitly send a reply to a client that called `call/3` or `multi_call/4` when the reply cannot be specified in the return value of `c:handle_call/3`. `client` must be the `from` argument (the second argument) accepted by `c:handle_call/3` callbacks. `reply` is an arbitrary term which will be given back to the client as the return value of the call. Note that `reply/2` can be called from any process, not just the GenServer that originally received the call (as long as that GenServer communicated the `from` argument somehow). This function always returns `:ok`. ### Examples - GenServer.reply/2 (function) def handle_call(:reply_in_one_second, from, state) do Process.send_after(self(), {:reply, from}, 1_000) {:noreply, state} end def handle_info({:reply, from}, state) do GenServer.reply(from, :one_second_has_passed) {:noreply, state} end ### GenServer.start/3 (function) Starts a `GenServer` process without links (outside of a supervision tree). See `start_link/3` for more information. ### GenServer.start_link/3 (function) Starts a `GenServer` process linked to the current process. This is often used to start the `GenServer` as part of a supervision tree. Once the server is started, the `c:init/1` function of the given `module` is called with `init_arg` as its argument to initialize the server. To ensure a synchronized start-up procedure, this function does not return until `c:init/1` has returned. Note that a `GenServer` started with `start_link/3` is linked to the parent process and will exit in case of crashes from the parent. The GenServer will also exit due to the `:normal` reasons in case it is configured to trap exits in the `c:init/1` callback. ### Options - GenServer.start_link/3 (function) * `:name` - used for name registration as described in the "Name registration" section in the documentation for `GenServer` * `:timeout` - if present, the server is allowed to spend the given number of milliseconds initializing or it will be terminated and the start function will return `{:error, :timeout}` * `:debug` - if present, the corresponding function in the [`:sys` module](`:sys`) is invoked * `:spawn_opt` - if present, its value is passed as options to the underlying process as in `Process.spawn/4` * `:hibernate_after` - if present, the GenServer process awaits any message for the given number of milliseconds and if no message is received, the process goes into hibernation automatically (by calling `:proc_lib.hibernate/3`). ### Return values - GenServer.start_link/3 (function) If the server is successfully created and initialized, this function returns `{:ok, pid}`, where `pid` is the PID of the server. If a process with the specified server name already exists, this function returns `{:error, {:already_started, pid}}` with the PID of that process. If the `c:init/1` callback fails with `reason`, this function returns `{:error, reason}`. Otherwise, if it returns `{:stop, reason}` or `:ignore`, the process is terminated and this function returns `{:error, reason}` or `:ignore`, respectively. ### GenServer.stop/3 (function) Synchronously stops the server with the given `reason`. The `c:terminate/2` callback of the given `server` will be invoked before exiting. This function returns `:ok` if the server terminates with the given reason; if it terminates with another reason, the call exits. This function keeps OTP semantics regarding error reporting. If the reason is any other than `:normal`, `:shutdown` or `{:shutdown, _}`, an error report is logged. ### GenServer.terminate/2 (callback) Invoked when the server is about to exit. It should do any cleanup required. `reason` is exit reason and `state` is the current state of the `GenServer`. The return value is ignored. `c:terminate/2` is useful for cleanup that requires access to the `GenServer`'s state. However, it is **not guaranteed** that `c:terminate/2` is called when a `GenServer` exits. Therefore, important cleanup should be done using process links and/or monitors. A monitoring process will receive the same exit `reason` that would be passed to `c:terminate/2`. `c:terminate/2` is called if: * the `GenServer` traps exits (using `Process.flag/2`) *and* the parent process (the one which called `start_link/1`) sends an exit signal * a callback (except `c:init/1`) does one of the following: * returns a `:stop` tuple * raises (via `raise/2`) or exits (via `exit/1`) * returns an invalid value If part of a supervision tree, a `GenServer` will receive an exit signal from its parent process (its supervisor) when the tree is shutting down. The exit signal is based on the shutdown strategy in the child's specification, where this value can be: * `:brutal_kill`: the `GenServer` is killed and so `c:terminate/2` is not called. * a timeout value, where the supervisor will send the exit signal `:shutdown` and the `GenServer` will have the duration of the timeout to terminate. If after duration of this timeout the process is still alive, it will be killed immediately. For a more in-depth explanation, please read the "Shutdown values (:shutdown)" section in the `Supervisor` module. If the `GenServer` receives an exit signal (that is not `:normal`) from any process when it is not trapping exits it will exit abruptly with the same reason and so not call `c:terminate/2`. Note that a process does *NOT* trap exits by default and an exit signal is sent when a linked process exits or its node is disconnected. `c:terminate/2` is only called after the `GenServer` finishes processing all messages which arrived in its mailbox prior to the exit signal. If it receives a `:kill` signal before it finishes processing those, `c:terminate/2` will not be called. If `c:terminate/2` is called, any messages received after the exit signal will still be in the mailbox. There is no cleanup needed when the `GenServer` controls a `port` (for example, `:gen_tcp.socket`) or `t:File.io_device/0`, because these will be closed on receiving a `GenServer`'s exit signal and do not need to be closed manually in `c:terminate/2`. If `reason` is neither `:normal`, `:shutdown`, nor `{:shutdown, term}` an error is logged. This callback is optional. ### GenServer.whereis/1 (function) Returns the `pid` or `{name, node}` of a GenServer process, `nil` otherwise. To be precise, `nil` is returned whenever a `pid` or `{name, node}` cannot be returned. Note there is no guarantee the returned `pid` or `{name, node}` is alive, as a process could terminate immediately after it is looked up. ### Examples - GenServer.whereis/1 (function) For example, to lookup a server process, monitor it and send a cast to it: process = GenServer.whereis(server) monitor = Process.monitor(process) GenServer.cast(process, :hello) ### GenServer.debug/0 (type) Debug options supported by the `start*` functions ### GenServer.from/0 (type) Tuple describing the client of a call request. `pid` is the PID of the caller and `tag` is a unique term used to identify the call. ### GenServer.name/0 (type) The GenServer name ### GenServer.on_start/0 (type) Return values of `start*` functions ### GenServer.option/0 (type) Option values used by the `start*` functions ### GenServer.options/0 (type) Options used by the `start*` functions ### GenServer.server/0 (type) The server reference. This is either a plain PID or a value representing a registered name. See the "Name registration" section of this document for more information. ### Node (module) Functions related to VM nodes. Some of the functions in this module are inlined by the compiler, similar to functions in the `Kernel` module and they are explicitly marked in their docs as "inlined by the compiler". For more information about inlined functions, check out the `Kernel` module. ### Node.alive?/0 (function) Returns `true` if the local node is alive. That is, if the node can be part of a distributed system. ### Node.connect/1 (function) Establishes a connection to `node`. Returns `true` if successful, `false` if not, and the atom `:ignored` if the local node is not alive. For more information, see `:net_kernel.connect_node/1`. ### Node.disconnect/1 (function) Forces the disconnection of a node. This will appear to the `node` as if the local node has crashed. This function is mainly used in the Erlang network authentication protocols. Returns `true` if disconnection succeeds, otherwise `false`. If the local node is not alive, the function returns `:ignored`. For more information, see `:erlang.disconnect_node/1`. ### Node.get_cookie/0 (function) Returns the magic cookie of the local node. Returns the cookie if the node is alive, otherwise `:nocookie`. ### Node.list/0 (function) Returns a list of all visible nodes in the system, excluding the local node. Same as `list(:visible)`. Inlined by the compiler. ### Node.list/1 (function) Returns a list of nodes according to argument given. The result returned when the argument is a list, is the list of nodes satisfying the disjunction(s) of the list elements. For more information, see `:erlang.nodes/1`. Inlined by the compiler. ### Node.monitor/2 (function) Monitors the status of the node. If `flag` is `true`, monitoring is turned on. If `flag` is `false`, monitoring is turned off. For more information, see `:erlang.monitor_node/2`. For monitoring status changes of all nodes, see `:net_kernel.monitor_nodes/2`. ### Node.monitor/3 (function) Behaves as `monitor/2` except that it allows an extra option to be given, namely `:allow_passive_connect`. For more information, see `:erlang.monitor_node/3`. For monitoring status changes of all nodes, see `:net_kernel.monitor_nodes/2`. ### Node.ping/1 (function) Tries to set up a connection to node. Returns `:pang` if it fails, or `:pong` if it is successful. ### Examples - Node.ping/1 (function) iex> Node.ping(:unknown_node) :pang ### Node.self/0 (function) Returns the current node. It returns the same as the built-in `node()`. ### Node.set_cookie/2 (function) Sets the magic cookie of `node` to the atom `cookie`. The default node is `Node.self/0`, the local node. If `node` is the local node, the function also sets the cookie of all other unknown nodes to `cookie`. This function will raise `FunctionClauseError` if the given `node` is not alive. ### Node.spawn/2 (function) Returns the PID of a new process started by the application of `fun` on `node`. If `node` does not exist, a useless PID is returned. For the list of available options, see `:erlang.spawn/2`. Inlined by the compiler. ### Node.spawn/3 (function) Returns the PID of a new process started by the application of `fun` on `node`. If `node` does not exist, a useless PID is returned. For the list of available options, see `:erlang.spawn_opt/3`. Inlined by the compiler. ### Node.spawn/4 (function) Returns the PID of a new process started by the application of `module.function(args)` on `node`. If `node` does not exist, a useless PID is returned. For the list of available options, see `:erlang.spawn/4`. Inlined by the compiler. ### Node.spawn/5 (function) Returns the PID of a new process started by the application of `module.function(args)` on `node`. If `node` does not exist, a useless PID is returned. For the list of available options, see `:erlang.spawn_opt/5`. Inlined by the compiler. ### Node.spawn_link/2 (function) Returns the PID of a new linked process started by the application of `fun` on `node`. A link is created between the calling process and the new process, atomically. If `node` does not exist, a useless PID is returned (and due to the link, an exit signal with exit reason `:noconnection` will be received). Inlined by the compiler. ### Node.spawn_link/4 (function) Returns the PID of a new linked process started by the application of `module.function(args)` on `node`. A link is created between the calling process and the new process, atomically. If `node` does not exist, a useless PID is returned (and due to the link, an exit signal with exit reason `:noconnection` will be received). Inlined by the compiler. ### Node.spawn_monitor/2 (function) Spawns the given function on a node, monitors it and returns its PID and monitoring reference. Inlined by the compiler. ### Node.spawn_monitor/4 (function) Spawns the given module and function passing the given args on a node, monitors it and returns its PID and monitoring reference. Inlined by the compiler. ### Node.start/3 (function) Turns a non-distributed node into a distributed node. This functionality starts the `:net_kernel` and other related processes. This function is rarely invoked in practice. Instead, nodes are named and started via the command line by using the `--sname` and `--name` flags. If you need to use this function to dynamically name a node, please make sure the `epmd` operating system process is running by calling `epmd -daemon`. Invoking this function when the distribution has already been started, either via the command line interface or dynamically, will return an error. ### Examples - Node.start/3 (function) {:ok, pid} = Node.start(:example, :shortnames, 15000) ### Node.stop/0 (function) Turns a distributed node into a non-distributed node. For other nodes in the network, this is the same as the node going down. Only possible when the node was started with `Node.start/3`, otherwise returns `{:error, :not_allowed}`. Returns `{:error, :not_found}` if the local node is not alive. ### Node.state/0 (type) ### Node.t/0 (type) ### PartitionSupervisor (module) A supervisor that starts multiple partitions of the same child. Certain processes may become bottlenecks in large systems. If those processes can have their state trivially partitioned, in a way there is no dependency between them, then they can use the `PartitionSupervisor` to create multiple isolated and independent partitions. Once the `PartitionSupervisor` starts, you can dispatch to its children using `{:via, PartitionSupervisor, {name, key}}`, where `name` is the name of the `PartitionSupervisor` and key is used for routing. This module was introduced in Elixir v1.14.0. ### Simple Example - PartitionSupervisor (module) Let's start with an example which is not useful per se, but shows how the partitions are started and how messages are routed to them. Here's a toy GenServer that simply collects the messages it's given. It prints them for easy illustration. defmodule Collector do use GenServer def start_link(args) do GenServer.start_link(__MODULE__, args) end def init(args) do IO.inspect([__MODULE__, " got args ", args, " in ", self()]) {:ok, _initial_state = []} end def collect(server, msg) do GenServer.call(server, {:collect, msg}) end def handle_call({:collect, msg}, _from, state) do new_state = [msg | state] IO.inspect(["current messages:", new_state, " in process", self()]) {:reply, :ok, new_state} end end To run multiple of these, we can start them under a `PartitionSupervisor` by placing this in our supervision tree: {PartitionSupervisor, child_spec: Collector.child_spec([some: :arg]), name: MyApp.PartitionSupervisor } We can send messages to them using a "via tuple": # The key is used to route our message to a particular instance. key = 1 Collector.collect({:via, PartitionSupervisor, {MyApp.PartitionSupervisor, key}}, :hi) # ["current messages:", [:hi], " in process", #PID<0.602.0>] :ok Collector.collect({:via, PartitionSupervisor, {MyApp.PartitionSupervisor, key}}, :ho) # ["current messages:", [:ho, :hi], " in process", #PID<0.602.0>] :ok # With a different key, the message will be routed to a different instance. key = 2 Collector.collect({:via, PartitionSupervisor, {MyApp.PartitionSupervisor, key}}, :a) # ["current messages:", [:a], " in process", #PID<0.603.0>] :ok Collector.collect({:via, PartitionSupervisor, {MyApp.PartitionSupervisor, key}}, :b) # ["current messages:", [:b, :a], " in process", #PID<0.603.0>] :ok Now let's move on to a useful example. ## `DynamicSupervisor` Example The `DynamicSupervisor` is a single process responsible for starting other processes. In some applications, the `DynamicSupervisor` may become a bottleneck. To address this, you can start multiple instances of the `DynamicSupervisor` through a `PartitionSupervisor`, and then pick a "random" instance to start the child on. Instead of starting a single `DynamicSupervisor`: children = [ {DynamicSupervisor, name: MyApp.DynamicSupervisor} ] Supervisor.start_link(children, strategy: :one_for_one) and starting children on that dynamic supervisor directly: DynamicSupervisor.start_child(MyApp.DynamicSupervisor, {Agent, fn -> %{} end}) You can start the dynamic supervisors under a `PartitionSupervisor`: children = [ {PartitionSupervisor, child_spec: DynamicSupervisor, name: MyApp.DynamicSupervisors} ] Supervisor.start_link(children, strategy: :one_for_one) and then: DynamicSupervisor.start_child( {:via, PartitionSupervisor, {MyApp.DynamicSupervisors, self()}}, {Agent, fn -> %{} end} ) In the code above, we start a partition supervisor that will by default start a dynamic supervisor for each core in your machine. Then, instead of calling the `DynamicSupervisor` by name, you call it through the partition supervisor using the `{:via, PartitionSupervisor, {name, key}}` format. We picked `self()` as the routing key, which means each process will be assigned one of the existing dynamic supervisors. See `start_link/1` to see all options supported by the `PartitionSupervisor`. ### Implementation notes - PartitionSupervisor (module) The `PartitionSupervisor` uses either an ETS table or a `Registry` to manage all of the partitions. Under the hood, the `PartitionSupervisor` generates a child spec for each partition and then acts as a regular supervisor. The ID of each child spec is the partition number. For routing, two strategies are used. If `key` is an integer, it is routed using `rem(abs(key), partitions)` where `partitions` is the number of partitions. Otherwise it uses `:erlang.phash2(key, partitions)`. The particular routing may change in the future, and therefore must not be relied on. If you want to retrieve a particular PID for a certain key, you can use `GenServer.whereis({:via, PartitionSupervisor, {name, key}})`. ### PartitionSupervisor.count_children/1 (function) Returns a map containing count values for the supervisor. The map contains the following keys: * `:specs` - the number of partitions (children processes) * `:active` - the count of all actively running child processes managed by this supervisor * `:supervisors` - the count of all supervisors whether or not the child process is still alive * `:workers` - the count of all workers, whether or not the child process is still alive ### PartitionSupervisor.partitions/1 (function) Returns the number of partitions for the partition supervisor. ### PartitionSupervisor.resize!/2 (function) Resizes the number of partitions in the PartitionSupervisor. This is done by starting or stopping a given number of partitions in the supervisor. All of the child specifications are kept in the `PartitionSupervisor` itself. The final number of partitions cannot be less than zero and cannot be more than the number of partitions the supervisor started with. ### PartitionSupervisor.start_link/1 (function) Starts a partition supervisor with the given options. This function is typically not invoked directly, instead it is invoked when using a `PartitionSupervisor` as a child of another supervisor: children = [ {PartitionSupervisor, child_spec: SomeChild, name: MyPartitionSupervisor} ] If the supervisor is successfully spawned, this function returns `{:ok, pid}`, where `pid` is the PID of the supervisor. If the given name for the partition supervisor is already assigned to a process, the function returns `{:error, {:already_started, pid}}`, where `pid` is the PID of that process. Note that a supervisor started with this function is linked to the parent process and exits not only on crashes but also if the parent process exits with `:normal` reason. ### Options - PartitionSupervisor.start_link/1 (function) * `:name` - an atom or via tuple representing the name of the partition supervisor (see `t:name/0`). * `:child_spec` - the child spec to be used when starting the partitions. * `:partitions` - a positive integer with the number of partitions. Defaults to `System.schedulers_online()` (typically the number of cores). * `:strategy` - the restart strategy option, defaults to `:one_for_one`. You can learn more about strategies in the `Supervisor` module docs. * `:max_restarts` - the maximum number of restarts allowed in a time frame. Defaults to `3`. * `:max_seconds` - the time frame in which `:max_restarts` applies. Defaults to `5`. * `:with_arguments` - a two-argument anonymous function that allows the partition to be given to the child starting function. See the `:with_arguments` section below. ## `:with_arguments` Sometimes you want each partition to know their partition assigned number. This can be done with the `:with_arguments` option. This function receives the value of the `:child_spec` option and an integer for the partition number. It must return a new list of arguments that will be used to start the partition process. For example, most processes are started by calling `start_link(opts)`, where `opts` is a keyword list. You could inject the partition into the options given to the child: with_arguments: fn [opts], partition -> [Keyword.put(opts, :partition, partition)] end ### PartitionSupervisor.stop/3 (function) Synchronously stops the given partition supervisor with the given `reason`. It returns `:ok` if the supervisor terminates with the given reason. If it terminates with another reason, the call exits. This function keeps OTP semantics regarding error reporting. If the reason is any other than `:normal`, `:shutdown` or `{:shutdown, _}`, an error report is logged. ### PartitionSupervisor.which_children/1 (function) Returns a list with information about all children. This function returns a list of tuples containing: * `id` - the partition number * `child` - the PID of the corresponding child process or the atom `:restarting` if the process is about to be restarted * `type` - `:worker` or `:supervisor` as defined in the child specification * `modules` - as defined in the child specification ### PartitionSupervisor.name/0 (type) The name of the `PartitionSupervisor`. ### Process (module) Conveniences for working with processes and the process dictionary. Besides the functions available in this module, the `Kernel` module exposes and auto-imports some basic functionality related to processes available through the following functions: * `Kernel.spawn/1` and `Kernel.spawn/3` * `Kernel.spawn_link/1` and `Kernel.spawn_link/3` * `Kernel.spawn_monitor/1` and `Kernel.spawn_monitor/3` * `Kernel.self/0` * `Kernel.send/2` While this module provides low-level conveniences to work with processes, developers typically use abstractions such as `Agent`, `GenServer`, `Registry`, `Supervisor` and `Task` for building their systems and resort to this module for gathering information, trapping exits, links and monitoring. ### Aliases - Process (module) Aliases are a feature introduced in Erlang/OTP 24. An alias is a way to refer to a PID in order to send messages to it. The advantage of using aliases is that they can be deactivated even if the aliased process is still running. If you send a message to a deactivated alias, nothing will happen. This makes request/response scenarios easier to implement. You can use `alias/0` or `alias/1` to set an alias, and then you can send messages to that alias like you do with PIDs using `send/2`. To deactivate an alias, you can use `unalias/1`. If you send a message to a deactivated alias, nothing will happen. For example, you could have a process that listens for `:ping` messages: def server do receive do {:ping, source_alias} -> send(source_alias, :pong) server() end end Now, another process might ping this process: server = spawn(&server/0) source_alias = Process.alias() send(server, {:ping, source_alias}) receive do :pong -> :pong end #=> :pong If now you deactivate the `source_alias` and ping the server again, you won't receive any response since the server will `send/2` the `:pong` response to a deactivated alias. Process.unalias(source_alias) send(server, {:ping, source_alias}) receive do :pong -> :pong after 1000 -> :timeout end #=> :timeout See also the [Process Aliases section](https://www.erlang.org/doc/reference_manual/processes.html#process-aliases) of the *Erlang reference manual*. ### Process.alias/0 (function) Creates a process alias. This is the same as calling `alias/1` as `alias([:explicit_unalias])`. See also `:erlang.alias/0`. Inlined by the compiler. ### Examples - Process.alias/0 (function) alias = Process.alias() ### Process.alias/1 (function) Creates a process alias. See [the module documentation](#module-aliases) for more information about aliases. See also `:erlang.alias/1`. Inlined by the compiler. ### Examples - Process.alias/1 (function) alias = Process.alias([:reply]) ### Process.alive?/1 (function) Tells whether the given process is alive on the local node. If the process identified by `pid` is alive (that is, it's not exiting and has not exited yet) than this function returns `true`. Otherwise, it returns `false`. `pid` must refer to a process running on the local node or `ArgumentError` is raised. To check whether a process on any node is alive you can use the [`:erpc`](`:erpc`) module. :erpc.call(node(pid), Process, :alive?, [pid]) Inlined by the compiler. ### Process.cancel_timer/2 (function) Cancels a timer returned by `send_after/3`. When the result is an integer, it represents the time in milliseconds left until the timer would have expired. When the result is `false`, a timer corresponding to `timer_ref` could not be found. This can happen either because the timer expired, because it has already been canceled, or because `timer_ref` never corresponded to a timer. Even if the timer had expired and the message was sent, this function does not tell you if the timeout message has arrived at its destination yet. Inlined by the compiler. ### Options - Process.cancel_timer/2 (function) * `:async` - (boolean) when `false`, the request for cancellation is synchronous. When `true`, the request for cancellation is asynchronous, meaning that the request to cancel the timer is issued and `:ok` is returned right away. Defaults to `false`. * `:info` - (boolean) whether to return information about the timer being cancelled. When the `:async` option is `false` and `:info` is `true`, then either an integer or `false` (like described above) is returned. If `:async` is `false` and `:info` is `false`, `:ok` is returned. If `:async` is `true` and `:info` is `true`, a message in the form `{:cancel_timer, timer_ref, result}` (where `result` is an integer or `false` like described above) is sent to the caller of this function when the cancellation has been performed. If `:async` is `true` and `:info` is `false`, no message is sent. Defaults to `true`. ### Process.delete/1 (function) Deletes the given `key` from the process dictionary. Returns the value that was under `key` in the process dictionary, or `nil` if `key` was not stored in the process dictionary. ### Examples - Process.delete/1 (function) iex> Process.put(:comments, ["comment", "other comment"]) iex> Process.delete(:comments) ["comment", "other comment"] iex> Process.delete(:comments) nil ### Process.demonitor/2 (function) Demonitors the monitor identified by the given `reference`. If `monitor_ref` is a reference which the calling process obtained by calling `monitor/1`, that monitoring is turned off. If the monitoring is already turned off, nothing happens. See `:erlang.demonitor/2` for more information. Inlined by the compiler. ### Examples - Process.demonitor/2 (function) pid = spawn(fn -> 1 + 2 end) ref = Process.monitor(pid) Process.demonitor(ref) #=> true ### Process.exit/2 (function) Sends an exit signal with the given `reason` to `pid`. The following behavior applies if `reason` is any term except `:normal` or `:kill`: 1. If `pid` is not trapping exits, `pid` will exit with the given `reason`. 2. If `pid` is trapping exits, the exit signal is transformed into a message `{:EXIT, from, reason}` and delivered to the message queue of `pid`. If `reason` is the atom `:normal`, `pid` will not exit (unless `pid` is the calling process, in which case it will exit with the reason `:normal`). If it is trapping exits, the exit signal is transformed into a message `{:EXIT, from, :normal}` and delivered to its message queue. If `reason` is the atom `:kill`, that is if `Process.exit(pid, :kill)` is called, an untrappable exit signal is sent to `pid` which will unconditionally exit with reason `:killed`. Inlined by the compiler. ### Examples - Process.exit/2 (function) Process.exit(pid, :kill) #=> true ### Process.flag/2 (function) Sets the given `flag` to `value` for the calling process. Returns the old value of `flag`. See `:erlang.process_flag/2` for more information. Inlined by the compiler. ### Process.flag/3 (function) Sets the given `flag` to `value` for the given process `pid`. Returns the old value of `flag`. It raises `ArgumentError` if `pid` is not a local process. The allowed values for `flag` are only a subset of those allowed in `flag/2`, namely `:save_calls`. See `:erlang.process_flag/3` for more information. Inlined by the compiler. ### Process.get/0 (function) Returns all key-value pairs in the process dictionary. Inlined by the compiler. ### Process.get/2 (function) Returns the value for the given `key` in the process dictionary, or `default` if `key` is not set. ### Examples - Process.get/2 (function) # Assuming :locale was not set iex> Process.get(:locale, "pt") "pt" iex> Process.put(:locale, "fr") nil iex> Process.get(:locale, "pt") "fr" ### Process.get_keys/0 (function) Returns all keys in the process dictionary. Inlined by the compiler. ### Examples - Process.get_keys/0 (function) # Assuming :locale was not set iex> :locale in Process.get_keys() false iex> Process.put(:locale, "pt") nil iex> :locale in Process.get_keys() true ### Process.get_keys/1 (function) Returns all keys in the process dictionary that have the given `value`. Inlined by the compiler. ### Process.group_leader/0 (function) Returns the PID of the group leader for the calling process. Inlined by the compiler. ### Examples - Process.group_leader/0 (function) Process.group_leader() #=> #PID<0.53.0> ### Process.group_leader/2 (function) Sets the group leader of the given `pid` to `leader`. Typically, this is used when a process started from a certain shell should have a group leader other than `:init`. Inlined by the compiler. ### Process.hibernate/3 (function) Puts the calling process into a "hibernation" state. The calling process is put into a waiting state where its memory allocation has been reduced as much as possible, which is useful if the process does not expect to receive any messages in the near future. See `:erlang.hibernate/3` for more information. Inlined by the compiler. ### Process.info/1 (function) Returns information about the process identified by `pid`, or returns `nil` if the process is not alive. Use this only for debugging information. See `:erlang.process_info/1` for more information. ### Process.info/2 (function) Returns information about the process identified by `pid`, or returns `nil` if the process is not alive. See `:erlang.process_info/2` for more information. ### Process.link/1 (function) Creates a link between the calling process and the given item (process or port). Links are bidirectional. Linked processes can be unlinked by using `unlink/1`. If such a link exists already, this function does nothing since there can only be one link between two given processes. If a process tries to create a link to itself, nothing will happen. When two processes are linked, each one receives exit signals from the other (see also `exit/2`). Let's assume `pid1` and `pid2` are linked. If `pid2` exits with a reason other than `:normal` (which is also the exit reason used when a process finishes its job) and `pid1` is not trapping exits (see `flag/2`), then `pid1` will exit with the same reason as `pid2` and in turn emit an exit signal to all its other linked processes. The behavior when `pid1` is trapping exits is described in `exit/2`. See `:erlang.link/1` for more information. Inlined by the compiler. ### Process.list/0 (function) Returns a list of PIDs corresponding to all the processes currently existing on the local node. Note that if a process is exiting, it is considered to exist but not be alive. This means that for such process, `alive?/1` will return `false` but its PID will be part of the list of PIDs returned by this function. See `:erlang.processes/0` for more information. Inlined by the compiler. ### Examples - Process.list/0 (function) Process.list() #=> [#PID<0.0.0>, #PID<0.1.0>, #PID<0.2.0>, #PID<0.3.0>, ...] ### Process.monitor/1 (function) Starts monitoring the given `item` from the calling process. Once the monitored process dies, a message is delivered to the monitoring process in the shape of: {:DOWN, ref, :process, object, reason} where: * `ref` is a monitor reference returned by this function; * `object` is either a `pid` of the monitored process (if monitoring a PID) or `{name, node}` (if monitoring a remote or local name); * `reason` is the exit reason. If the process is already dead when calling `Process.monitor/1`, a `:DOWN` message is delivered immediately. See ["The need for monitoring"](genservers.md#the-need-for-monitoring) for an example. See `:erlang.monitor/2` for more information. Inlined by the compiler. ### Examples - Process.monitor/1 (function) pid = spawn(fn -> 1 + 2 end) #=> #PID<0.118.0> Process.monitor(pid) #=> #Reference<0.906660723.3006791681.40191> Process.exit(pid, :kill) #=> true receive do msg -> msg end #=> {:DOWN, #Reference<0.906660723.3006791681.40191>, :process, #PID<0.118.0>, :noproc} ### Process.monitor/2 (function) Starts monitoring the given `item` from the calling process. This function is similar to `monitor/1`, but accepts options to customize how `item` is monitored. See `:erlang.monitor/3` for documentation on those options. Inlined by the compiler. ### Examples - Process.monitor/2 (function) pid = spawn(fn -> receive do {:ping, source_alias} -> send(source_alias, :pong) end end) #=> #PID<0.118.0> ref_and_alias = Process.monitor(pid, alias: :reply_demonitor) #=> #Reference<0.906660723.3006791681.40191> send(pid, {:ping, ref_and_alias}) receive do: (msg -> msg) #=> :pong ref_and_alias = Process.monitor(pid, alias: :reply_demonitor) #=> #Reference<0.906660723.3006791681.40191> send(pid, {:ping, ref_and_alias}) receive do: (msg -> msg) #=> {:DOWN, #Reference<0.906660723.3006791681.40191>, :process, #PID<0.118.0>, :noproc} ### Process.put/2 (function) Stores the given `key`-`value` pair in the process dictionary. The return value of this function is the value that was previously stored under `key`, or `nil` in case no value was stored under it. ### Examples - Process.put/2 (function) # Assuming :locale was not set iex> Process.put(:locale, "en") nil iex> Process.put(:locale, "fr") "en" ### Process.read_timer/1 (function) Reads a timer created by `send_after/3`. When the result is an integer, it represents the time in milliseconds left until the timer will expire. When the result is `false`, a timer corresponding to `timer_ref` could not be found. This can be either because the timer expired, because it has already been canceled, or because `timer_ref` never corresponded to a timer. Even if the timer had expired and the message was sent, this function does not tell you if the timeout message has arrived at its destination yet. Inlined by the compiler. ### Process.register/2 (function) Registers the given `pid_or_port` under the given `name` on the local node. `name` must be an atom and can then be used instead of the PID/port identifier when sending messages with `Kernel.send/2`. `register/2` will fail with `ArgumentError` in any of the following cases: * the PID/Port is not existing locally and alive * the name is already registered * the `pid_or_port` is already registered under a different `name` The following names are reserved and cannot be assigned to processes nor ports: * `nil` * `false` * `true` * `:undefined` ### Examples - Process.register/2 (function) Process.register(self(), :test) #=> true send(:test, :hello) #=> :hello send(:wrong_name, :hello) ** (ArgumentError) argument error ### Process.registered/0 (function) Returns a list of names which have been registered using `register/2`. Inlined by the compiler. ### Examples - Process.registered/0 (function) Process.register(self(), :test) Process.registered() #=> [:test, :elixir_config, :inet_db, ...] ### Process.send/3 (function) Sends a message to the given `dest`. `dest` may be a remote or local PID, a local port, a locally registered name, or a tuple in the form of `{registered_name, node}` for a registered name at another node. Inlined by the compiler. ### Options - Process.send/3 (function) * `:noconnect` - when used, if sending the message would require an auto-connection to another node the message is not sent and `:noconnect` is returned. * `:nosuspend` - when used, if sending the message would cause the sender to be suspended the message is not sent and `:nosuspend` is returned. Otherwise the message is sent and `:ok` is returned. ### Examples - Process.send/3 (function) iex> Process.send({:name, :node_that_does_not_exist}, :hi, [:noconnect]) :noconnect ### Process.send_after/4 (function) Sends `msg` to `dest` after `time` milliseconds. If `dest` is a PID, it must be the PID of a local process, dead or alive. If `dest` is an atom, it must be the name of a registered process which is looked up at the time of delivery. No error is produced if the name does not refer to a process. The message is not sent immediately. Therefore, `dest` can receive other messages in-between even when `time` is `0`. This function returns a timer reference, which can be read with `read_timer/1` or canceled with `cancel_timer/1`. The timer will be automatically canceled if the given `dest` is a PID which is not alive or when the given PID exits. Note that timers will not be automatically canceled when `dest` is an atom (as the atom resolution is done on delivery). Inlined by the compiler. ### Options - Process.send_after/4 (function) * `:abs` - (boolean) when `false`, `time` is treated as relative to the current monotonic time. When `true`, `time` is the absolute value of the Erlang monotonic time at which `msg` should be delivered to `dest`. To read more about Erlang monotonic time and other time-related concepts, look at the documentation for the `System` module. Defaults to `false`. ### Examples - Process.send_after/4 (function) timer_ref = Process.send_after(pid, :hi, 1000) ### Process.set_label/1 (function) Add a descriptive term to the current process. The term does not need to be unique, and in Erlang/OTP 27+ will be shown in Observer and in crash logs. This label may be useful for identifying a process as one of multiple in a given role, such as `:queue_worker` or `{:live_chat, user_id}`. ### Examples - Process.set_label/1 (function) Process.set_label(:worker) #=> :ok Process.set_label({:any, "term"}) #=> :ok ### Process.sleep/1 (function) Sleeps the current process for the given `timeout`. `timeout` is either the number of milliseconds to sleep as an integer or the atom `:infinity`. When `:infinity` is given, the current process will sleep forever, and not consume or reply to messages. > #### Sleeping limit {: .info } > > Before Elixir v1.18, `sleep/1` did not accept integer timeout values greater > than `16#ffffffff`, that is, `2^32-1`. Since Elixir v1.18, arbitrarily-high integer > values are accepted. **Use this function with extreme care**. For almost all situations where you would use `sleep/1` in Elixir, there is likely a more correct, faster and precise way of achieving the same with message passing. For example, if you are waiting for a process to perform some action, it is better to communicate the progress of such action with messages. In other words, **do not**: Task.start_link(fn -> do_something() ... end) # Wait until work is done Process.sleep(2000) But **do**: parent = self() Task.start_link(fn -> do_something() send(parent, :work_is_done) ... end) receive do :work_is_done -> :ok after # Optional timeout 30_000 -> :timeout end For cases like the one above, `Task.async/1` and `Task.await/2` are preferred. Similarly, if you are waiting for a process to terminate, monitor that process instead of sleeping. **Do not**: Task.start_link(fn -> ... end) # Wait until task terminates Process.sleep(2000) Instead **do**: {:ok, pid} = Task.start_link(fn -> ... end) ref = Process.monitor(pid) receive do {:DOWN, ^ref, _, _, _} -> :task_is_down after # Optional timeout 30_000 -> :timeout end ### Process.spawn/2 (function) Spawns the given function according to the given options. The result depends on the given options. In particular, if `:monitor` is given as an option, it will return a tuple containing the PID and the monitoring reference, otherwise just the spawned process PID. More options are available; for the comprehensive list of available options check `:erlang.spawn_opt/4`. Inlined by the compiler. ### Examples - Process.spawn/2 (function) Process.spawn(fn -> 1 + 2 end, [:monitor]) #=> {#PID<0.93.0>, #Reference<0.18808174.1939079169.202418>} Process.spawn(fn -> 1 + 2 end, [:link]) #=> #PID<0.95.0> ### Process.spawn/4 (function) Spawns the given function `fun` from module `mod`, passing the given `args` according to the given options. The result depends on the given options. In particular, if `:monitor` is given as an option, it will return a tuple containing the PID and the monitoring reference, otherwise just the spawned process PID. It also accepts extra options, for the list of available options check `:erlang.spawn_opt/4`. Inlined by the compiler. ### Process.unalias/1 (function) Explicitly deactivates a process alias. Returns `true` if `alias` was a currently-active alias for current processes, or `false` otherwise. See [the module documentation](#module-aliases) for more information about aliases. See also `:erlang.unalias/1`. Inlined by the compiler. ### Examples - Process.unalias/1 (function) alias = Process.alias() Process.unalias(alias) #=> true ### Process.unlink/1 (function) Removes the link between the calling process and the given item (process or port). If there is no such link, this function does nothing. If `pid_or_port` does not exist, this function does not produce any errors and simply does nothing. The return value of this function is always `true`. See `:erlang.unlink/1` for more information. Inlined by the compiler. ### Process.unregister/1 (function) Removes the registered `name`, associated with a PID or a port identifier. Fails with `ArgumentError` if the name is not registered to any PID or port. Inlined by the compiler. ### Examples - Process.unregister/1 (function) Process.register(self(), :test) #=> true Process.unregister(:test) #=> true Process.unregister(:wrong_name) ** (ArgumentError) argument error ### Process.whereis/1 (function) Returns the PID or port identifier registered under `name` or `nil` if the name is not registered. See `:erlang.whereis/1` for more information. ### Examples - Process.whereis/1 (function) Process.register(self(), :test) Process.whereis(:test) #=> #PID<0.84.0> Process.whereis(:wrong_name) #=> nil ### Process.alias/0 (type) An alias returned by `alias/0` or `alias/1`. See [the module documentation](#module-aliases) for more information about aliases. ### Process.alias_opt/0 (type) ### Process.dest/0 (type) A process destination. A remote or local PID, a local port, a locally registered name, or a tuple in the form of `{registered_name, node}` for a registered name at another node. ### Process.process_info_item/0 (type) ### Process.process_info_result_item/0 (type) ### Process.spawn_opt/0 (type) ### Process.spawn_opts/0 (type) ### Registry (module) A local, decentralized and scalable key-value process storage. It allows developers to lookup one or more processes with a given key. If the registry has `:unique` keys, a key points to 0 or 1 process. If the registry allows `:duplicate` keys, a single key may point to any number of processes. In both cases, different keys could identify the same process. Each entry in the registry is associated to the process that has registered the key. If the process crashes, the keys associated to that process are automatically removed. All key comparisons in the registry are done using the match operation (`===/2`). The registry can be used for different purposes, such as name lookups (using the `:via` option), storing properties, custom dispatching rules, or a pubsub implementation. We explore some of those use cases below. The registry may also be transparently partitioned, which provides more scalable behavior for running registries on highly concurrent environments with thousands or millions of entries. ### Using in `:via` - Registry (module) Once the registry is started with a given name using `Registry.start_link/1`, it can be used to register and access named processes using the `{:via, Registry, {registry, key}}` tuple: {:ok, _} = Registry.start_link(keys: :unique, name: MyApp.Registry) name = {:via, Registry, {MyApp.Registry, "agent"}} {:ok, _} = Agent.start_link(fn -> 0 end, name: name) Agent.get(name, & &1) #=> 0 Agent.update(name, &(&1 + 1)) Agent.get(name, & &1) #=> 1 In the previous example, we were not interested in associating a value to the process: Registry.lookup(MyApp.Registry, "agent") #=> [{self(), nil}] However, in some cases it may be desired to associate a value to the process using the alternate `{:via, Registry, {registry, key, value}}` tuple: {:ok, _} = Registry.start_link(keys: :unique, name: MyApp.Registry) name = {:via, Registry, {MyApp.Registry, "agent", :hello}} {:ok, agent_pid} = Agent.start_link(fn -> 0 end, name: name) Registry.lookup(MyApp.Registry, "agent") #=> [{agent_pid, :hello}] To this point, we have been starting `Registry` using `start_link/1`. Typically the registry is started as part of a supervision tree though: {Registry, keys: :unique, name: MyApp.Registry} Only registries with unique keys can be used in `:via`. If the name is already taken, the case-specific `start_link` function (`Agent.start_link/2` in the example above) will return `{:error, {:already_started, current_pid}}`. ### Using as a dispatcher - Registry (module) `Registry` has a dispatch mechanism that allows developers to implement custom dispatch logic triggered from the caller. For example, let's say we have a duplicate registry started as so: {:ok, _} = Registry.start_link(keys: :duplicate, name: Registry.DispatcherTest) By calling `register/3`, different processes can register under a given key and associate any value under that key. In this case, let's register the current process under the key `"hello"` and attach the `{IO, :inspect}` tuple to it: {:ok, _} = Registry.register(Registry.DispatcherTest, "hello", {IO, :inspect}) Now, an entity interested in dispatching events for a given key may call `dispatch/3` passing in the key and a callback. This callback will be invoked with a list of all the values registered under the requested key, alongside the PID of the process that registered each value, in the form of `{pid, value}` tuples. In our example, `value` will be the `{module, function}` tuple in the code above: Registry.dispatch(Registry.DispatcherTest, "hello", fn entries -> for {pid, {module, function}} <- entries, do: apply(module, function, [pid]) end) # Prints #PID<...> where the PID is for the process that called register/3 above #=> :ok Dispatching happens in the process that calls `dispatch/3` either serially or concurrently in case of multiple partitions (via spawned tasks). The registered processes are not involved in dispatching unless involving them is done explicitly (for example, by sending them a message in the callback). Furthermore, if there is a failure when dispatching, due to a bad registration, dispatching will always fail and the registered process will not be notified. Therefore let's make sure we at least wrap and report those errors: require Logger Registry.dispatch(Registry.DispatcherTest, "hello", fn entries -> for {pid, {module, function}} <- entries do try do apply(module, function, [pid]) catch kind, reason -> formatted = Exception.format(kind, reason, __STACKTRACE__) Logger.error("Registry.dispatch/3 failed with #{formatted}") end end end) # Prints #PID<...> #=> :ok You could also replace the whole `apply` system by explicitly sending messages. That's the example we will see next. ### Using as a PubSub - Registry (module) Registries can also be used to implement a local, non-distributed, scalable PubSub by relying on the `dispatch/3` function, similarly to the previous section: in this case, however, we will send messages to each associated process, instead of invoking a given module-function. In this example, we will also set the number of partitions to the number of schedulers online, which will make the registry more performant on highly concurrent environments: {:ok, _} = Registry.start_link( keys: :duplicate, name: Registry.PubSubTest, partitions: System.schedulers_online() ) {:ok, _} = Registry.register(Registry.PubSubTest, "hello", []) Registry.dispatch(Registry.PubSubTest, "hello", fn entries -> for {pid, _} <- entries, do: send(pid, {:broadcast, "world"}) end) #=> :ok The example above broadcasted the message `{:broadcast, "world"}` to all processes registered under the "topic" (or "key" as we called it until now) `"hello"`. The third argument given to `register/3` is a value associated to the current process. While in the previous section we used it when dispatching, in this particular example we are not interested in it, so we have set it to an empty list. You could store a more meaningful value if necessary. ### Registrations - Registry (module) Looking up, dispatching and registering are efficient and immediate at the cost of delayed unsubscription. For example, if a process crashes, its keys are automatically removed from the registry but the change may not propagate immediately. This means certain operations may return processes that are already dead. When such may happen, it will be explicitly stated in the function documentation. However, keep in mind those cases are typically not an issue. After all, a process referenced by a PID may crash at any time, including between getting the value from the registry and sending it a message. Many parts of the standard library are designed to cope with that, such as `Process.monitor/1` which will deliver the `:DOWN` message immediately if the monitored process is already dead and `send/2` which acts as a no-op for dead processes. ### ETS - Registry (module) Note that the registry uses one ETS table plus two ETS tables per partition. ### Registry.child_spec/1 (function) Returns a specification to start a registry under a supervisor. See `Supervisor`. ### Registry.count/1 (function) Returns the number of registered keys in a registry. It runs in constant time. ### Examples - Registry.count/1 (function) In the example below we register the current process and ask for the number of keys in the registry: iex> Registry.start_link(keys: :unique, name: Registry.UniqueCountTest) iex> Registry.count(Registry.UniqueCountTest) 0 iex> {:ok, _} = Registry.register(Registry.UniqueCountTest, "hello", :world) iex> {:ok, _} = Registry.register(Registry.UniqueCountTest, "world", :world) iex> Registry.count(Registry.UniqueCountTest) 2 The same applies to duplicate registries: iex> Registry.start_link(keys: :duplicate, name: Registry.DuplicateCountTest) iex> Registry.count(Registry.DuplicateCountTest) 0 iex> {:ok, _} = Registry.register(Registry.DuplicateCountTest, "hello", :world) iex> {:ok, _} = Registry.register(Registry.DuplicateCountTest, "hello", :world) iex> Registry.count(Registry.DuplicateCountTest) 2 ### Registry.count_match/4 (function) Returns the number of `{pid, value}` pairs under the given `key` in `registry` that match `pattern`. Pattern must be an atom or a tuple that will match the structure of the value stored in the registry. The atom `:_` can be used to ignore a given value or tuple element, while the atom `:"$1"` can be used to temporarily assign part of pattern to a variable for a subsequent comparison. Optionally, it is possible to pass a list of guard conditions for more precise matching. Each guard is a tuple, which describes checks that should be passed by assigned part of pattern. For example the `$1 > 1` guard condition would be expressed as the `{:>, :"$1", 1}` tuple. Please note that guard conditions will work only for assigned variables like `:"$1"`, `:"$2"`, and so forth. Avoid usage of special match variables `:"$_"` and `:"$$"`, because it might not work as expected. Zero will be returned if there is no match. For unique registries, a single partition lookup is necessary. For duplicate registries, all partitions must be looked up. ### Examples - Registry.count_match/4 (function) In the example below we register the current process under the same key in a duplicate registry but with different values: iex> Registry.start_link(keys: :duplicate, name: Registry.CountMatchTest) iex> {:ok, _} = Registry.register(Registry.CountMatchTest, "hello", {1, :atom, 1}) iex> {:ok, _} = Registry.register(Registry.CountMatchTest, "hello", {2, :atom, 2}) iex> Registry.count_match(Registry.CountMatchTest, "hello", {1, :_, :_}) 1 iex> Registry.count_match(Registry.CountMatchTest, "hello", {2, :_, :_}) 1 iex> Registry.count_match(Registry.CountMatchTest, "hello", {:_, :atom, :_}) 2 iex> Registry.count_match(Registry.CountMatchTest, "hello", {:"$1", :_, :"$1"}) 2 iex> Registry.count_match(Registry.CountMatchTest, "hello", {:_, :_, :"$1"}, [{:>, :"$1", 1}]) 1 iex> Registry.count_match(Registry.CountMatchTest, "hello", {:_, :"$1", :_}, [{:is_atom, :"$1"}]) 2 ### Registry.count_select/2 (function) Works like `select/2`, but only returns the number of matching records. ### Examples - Registry.count_select/2 (function) In the example below we register the current process under different keys in a unique registry but with the same value: iex> Registry.start_link(keys: :unique, name: Registry.CountSelectTest) iex> {:ok, _} = Registry.register(Registry.CountSelectTest, "hello", :value) iex> {:ok, _} = Registry.register(Registry.CountSelectTest, "world", :value) iex> Registry.count_select(Registry.CountSelectTest, [{{:_, :_, :value}, [], [true]}]) 2 ### Registry.delete_meta/2 (function) Deletes registry metadata for the given `key` in `registry`. ### Examples - Registry.delete_meta/2 (function) iex> Registry.start_link(keys: :unique, name: Registry.DeleteMetaTest) iex> Registry.put_meta(Registry.DeleteMetaTest, :custom_key, "custom_value") :ok iex> Registry.meta(Registry.DeleteMetaTest, :custom_key) {:ok, "custom_value"} iex> Registry.delete_meta(Registry.DeleteMetaTest, :custom_key) :ok iex> Registry.meta(Registry.DeleteMetaTest, :custom_key) :error ### Registry.dispatch/4 (function) Invokes the callback with all entries under `key` in each partition for the given `registry`. The list of `entries` is a non-empty list of two-element tuples where the first element is the PID and the second element is the value associated to the PID. If there are no entries for the given key, the callback is never invoked. If the registry is partitioned, the callback is invoked multiple times per partition. If the registry is partitioned and `parallel: true` is given as an option, the dispatching happens in parallel. In both cases, the callback is only invoked if there are entries for that partition. See the module documentation for examples of using the `dispatch/3` function for building custom dispatching or a pubsub system. ### Registry.keys/2 (function) Returns the known keys for the given `pid` in `registry` in no particular order. If the registry is unique, the keys are unique. Otherwise they may contain duplicates if the process was registered under the same key multiple times. The list will be empty if the process is dead or it has no keys in this registry. ### Examples - Registry.keys/2 (function) Registering under a unique registry does not allow multiple entries: iex> Registry.start_link(keys: :unique, name: Registry.UniqueKeysTest) iex> Registry.keys(Registry.UniqueKeysTest, self()) [] iex> {:ok, _} = Registry.register(Registry.UniqueKeysTest, "hello", :world) iex> Registry.register(Registry.UniqueKeysTest, "hello", :later) # registry is :unique {:error, {:already_registered, self()}} iex> Registry.keys(Registry.UniqueKeysTest, self()) ["hello"] Such is possible for duplicate registries though: iex> Registry.start_link(keys: :duplicate, name: Registry.DuplicateKeysTest) iex> Registry.keys(Registry.DuplicateKeysTest, self()) [] iex> {:ok, _} = Registry.register(Registry.DuplicateKeysTest, "hello", :world) iex> {:ok, _} = Registry.register(Registry.DuplicateKeysTest, "hello", :world) iex> Registry.keys(Registry.DuplicateKeysTest, self()) ["hello", "hello"] ### Registry.lock/3 (function) Out-of-band locking of the given `lock_key` for the duration of `function`. Only one function can execute under the same `lock_key` at a given time. The given function always runs in the caller process. The `lock_key` has its own namespace and therefore does not clash or overlap with the regular registry keys. In other words, locking works out-of-band from the regular Registry operations. See the "Use cases" section below. Locking behaves the same regardless of the registry type. ### Use cases - Registry.lock/3 (function) The Registry is safe and concurrent out-of-the-box. You are not required to use this function when interacting with the Registry. Furthermore, `Registry` with `:unique` keys can already act as a process-lock for any given key. For example, you can ensure only one process runs at a given time for a given `:key` by doing: name = {:via, Registry, {MyApp.Registry, :key, :value}} # Do not attempt to start if we are already running if pid = GenServer.whereis(name) do pid else case GenServer.start_link(__MODULE__, :ok, name: name) do {:ok, pid} -> pid {:error, {:already_started, pid}} -> pid end end Process locking gives you plenty of flexibility and fault isolation and is enough for most cases. This function is useful only when spawning processes is not an option, for example, when copying the data to another process could be too expensive. Or when the work must be done within the current process for other reasons. In such cases, this function provides a scalable mechanism for managing locks on top of the registry's infrastructure. ### Examples - Registry.lock/3 (function) iex> Registry.start_link(keys: :unique, name: Registry.LockTest) iex> Registry.lock(Registry.LockTest, :hello, fn -> :ok end) :ok iex> Registry.lock(Registry.LockTest, :world, fn -> self() end) self() ### Registry.lookup/2 (function) Finds the `{pid, value}` pair for the given `key` in `registry` in no particular order. An empty list if there is no match. For unique registries, a single partition lookup is necessary. For duplicate registries, all partitions must be looked up. ### Examples - Registry.lookup/2 (function) In the example below we register the current process and look it up both from itself and other processes: iex> Registry.start_link(keys: :unique, name: Registry.UniqueLookupTest) iex> Registry.lookup(Registry.UniqueLookupTest, "hello") [] iex> {:ok, _} = Registry.register(Registry.UniqueLookupTest, "hello", :world) iex> Registry.lookup(Registry.UniqueLookupTest, "hello") [{self(), :world}] iex> Task.async(fn -> Registry.lookup(Registry.UniqueLookupTest, "hello") end) |> Task.await() [{self(), :world}] The same applies to duplicate registries: iex> Registry.start_link(keys: :duplicate, name: Registry.DuplicateLookupTest) iex> Registry.lookup(Registry.DuplicateLookupTest, "hello") [] iex> {:ok, _} = Registry.register(Registry.DuplicateLookupTest, "hello", :world) iex> Registry.lookup(Registry.DuplicateLookupTest, "hello") [{self(), :world}] iex> {:ok, _} = Registry.register(Registry.DuplicateLookupTest, "hello", :another) iex> Enum.sort(Registry.lookup(Registry.DuplicateLookupTest, "hello")) [{self(), :another}, {self(), :world}] ### Registry.match/4 (function) Returns `{pid, value}` pairs under the given `key` in `registry` that match `pattern`. Pattern must be an atom or a tuple that will match the structure of the value stored in the registry. The atom `:_` can be used to ignore a given value or tuple element, while the atom `:"$1"` can be used to temporarily assign part of pattern to a variable for a subsequent comparison. Optionally, it is possible to pass a list of guard conditions for more precise matching. Each guard is a tuple, which describes checks that should be passed by assigned part of pattern. For example the `$1 > 1` guard condition would be expressed as the `{:>, :"$1", 1}` tuple. Please note that guard conditions will work only for assigned variables like `:"$1"`, `:"$2"`, and so forth. Avoid usage of special match variables `:"$_"` and `:"$$"`, because it might not work as expected. An empty list will be returned if there is no match. For unique registries, a single partition lookup is necessary. For duplicate registries, all partitions must be looked up. ### Examples - Registry.match/4 (function) In the example below we register the current process under the same key in a duplicate registry but with different values: iex> Registry.start_link(keys: :duplicate, name: Registry.MatchTest) iex> {:ok, _} = Registry.register(Registry.MatchTest, "hello", {1, :atom, 1}) iex> {:ok, _} = Registry.register(Registry.MatchTest, "hello", {2, :atom, 2}) iex> Registry.match(Registry.MatchTest, "hello", {1, :_, :_}) [{self(), {1, :atom, 1}}] iex> Registry.match(Registry.MatchTest, "hello", {2, :_, :_}) [{self(), {2, :atom, 2}}] iex> Registry.match(Registry.MatchTest, "hello", {:_, :atom, :_}) |> Enum.sort() [{self(), {1, :atom, 1}}, {self(), {2, :atom, 2}}] iex> Registry.match(Registry.MatchTest, "hello", {:"$1", :_, :"$1"}) |> Enum.sort() [{self(), {1, :atom, 1}}, {self(), {2, :atom, 2}}] iex> guards = [{:>, :"$1", 1}] iex> Registry.match(Registry.MatchTest, "hello", {:_, :_, :"$1"}, guards) [{self(), {2, :atom, 2}}] iex> guards = [{:is_atom, :"$1"}] iex> Registry.match(Registry.MatchTest, "hello", {:_, :"$1", :_}, guards) |> Enum.sort() [{self(), {1, :atom, 1}}, {self(), {2, :atom, 2}}] ### Registry.meta/2 (function) Reads registry metadata given on `start_link/1`. Atoms and tuples are allowed as keys. ### Examples - Registry.meta/2 (function) iex> Registry.start_link(keys: :unique, name: Registry.MetaTest, meta: [custom_key: "custom_value"]) iex> Registry.meta(Registry.MetaTest, :custom_key) {:ok, "custom_value"} iex> Registry.meta(Registry.MetaTest, :unknown_key) :error ### Registry.put_meta/3 (function) Stores registry metadata. Atoms and tuples are allowed as keys. ### Examples - Registry.put_meta/3 (function) iex> Registry.start_link(keys: :unique, name: Registry.PutMetaTest) iex> Registry.put_meta(Registry.PutMetaTest, :custom_key, "custom_value") :ok iex> Registry.meta(Registry.PutMetaTest, :custom_key) {:ok, "custom_value"} iex> Registry.put_meta(Registry.PutMetaTest, {:tuple, :key}, "tuple_value") :ok iex> Registry.meta(Registry.PutMetaTest, {:tuple, :key}) {:ok, "tuple_value"} ### Registry.register/3 (function) Registers the current process under the given `key` in `registry`. A value to be associated with this registration must also be given. This value will be retrieved whenever dispatching or doing a key lookup. This function returns `{:ok, owner}` or `{:error, reason}`. The `owner` is the PID in the registry partition responsible for the PID. The owner is automatically linked to the caller. If the registry has unique keys, it will return `{:ok, owner}` unless the key is already associated to a PID, in which case it returns `{:error, {:already_registered, pid}}`. If the registry has duplicate keys, multiple registrations from the current process under the same key are allowed. If the registry has listeners specified via the `:listeners` option in `start_link/1`, those listeners will be notified of the registration and will receive a message of type `t:listener_message/0`. ### Examples - Registry.register/3 (function) Registering under a unique registry does not allow multiple entries: iex> Registry.start_link(keys: :unique, name: Registry.UniqueRegisterTest) iex> {:ok, _} = Registry.register(Registry.UniqueRegisterTest, "hello", :world) iex> Registry.register(Registry.UniqueRegisterTest, "hello", :later) {:error, {:already_registered, self()}} iex> Registry.keys(Registry.UniqueRegisterTest, self()) ["hello"] Such is possible for duplicate registries though: iex> Registry.start_link(keys: :duplicate, name: Registry.DuplicateRegisterTest) iex> {:ok, _} = Registry.register(Registry.DuplicateRegisterTest, "hello", :world) iex> {:ok, _} = Registry.register(Registry.DuplicateRegisterTest, "hello", :world) iex> Registry.keys(Registry.DuplicateRegisterTest, self()) ["hello", "hello"] ### Registry.select/2 (function) Select key, pid, and values registered using full match specs. The `spec` consists of a list of three part tuples, in the shape of `[{match_pattern, guards, body}]`. The first part, the match pattern, must be a tuple that will match the structure of the the data stored in the registry, which is `{key, pid, value}`. The atom `:_` can be used to ignore a given value or tuple element, while the atom `:"$1"` can be used to temporarily assign part of pattern to a variable for a subsequent comparison. This can be combined like `{:"$1", :_, :_}`. The second part, the guards, is a list of conditions that allow filtering the results. Each guard is a tuple, which describes checks that should be passed by assigned part of pattern. For example the `$1 > 1` guard condition would be expressed as the `{:>, :"$1", 1}` tuple. Please note that guard conditions will work only for assigned variables like `:"$1"`, `:"$2"`, and so forth. The third part, the body, is a list of shapes of the returned entries. Like guards, you have access to assigned variables like `:"$1"`, which you can combine with hard-coded values to freely shape entries Note that tuples have to be wrapped in an additional tuple. To get a result format like `%{key: key, pid: pid, value: value}`, assuming you bound those variables in order in the match part, you would provide a body like `[%{key: :"$1", pid: :"$2", value: :"$3"}]`. Like guards, you can use some operations like `:element` to modify the output format. Do not use special match variables `:"$_"` and `:"$$"`, because they might not work as expected. Note that for large registries with many partitions this will be costly as it builds the result by concatenating all the partitions. ### Examples - Registry.select/2 (function) This example shows how to get everything from the registry: iex> Registry.start_link(keys: :unique, name: Registry.SelectAllTest) iex> {:ok, _} = Registry.register(Registry.SelectAllTest, "hello", :value) iex> {:ok, _} = Registry.register(Registry.SelectAllTest, "world", :value) iex> Registry.select(Registry.SelectAllTest, [{{:"$1", :"$2", :"$3"}, [], [{{:"$1", :"$2", :"$3"}}]}]) |> Enum.sort() [{"hello", self(), :value}, {"world", self(), :value}] If you want to get keys, you can pass a separate selector: iex> Registry.start_link(keys: :unique, name: Registry.SelectKeysTest) iex> {:ok, _} = Registry.register(Registry.SelectKeysTest, "hello", :value) iex> {:ok, _} = Registry.register(Registry.SelectKeysTest, "world", :value) iex> Registry.select(Registry.SelectKeysTest, [{{:"$1", :_, :_}, [], [:"$1"]}]) |> Enum.sort() ["hello", "world"] ### Registry.start_link/1 (function) Starts the registry as a supervisor process. Manually it can be started as: Registry.start_link(keys: :unique, name: MyApp.Registry) In your supervisor tree, you would write: Supervisor.start_link([ {Registry, keys: :unique, name: MyApp.Registry} ], strategy: :one_for_one) For intensive workloads, the registry may also be partitioned (by specifying the `:partitions` option). If partitioning is required then a good default is to set the number of partitions to the number of schedulers available: Registry.start_link( keys: :unique, name: MyApp.Registry, partitions: System.schedulers_online() ) or: Supervisor.start_link([ {Registry, keys: :unique, name: MyApp.Registry, partitions: System.schedulers_online()} ], strategy: :one_for_one) ### Options - Registry.start_link/1 (function) The registry requires the following keys: * `:keys` - chooses if keys are `:unique` or `:duplicate` * `:name` - the name of the registry and its tables The following keys are optional: * `:partitions` - the number of partitions in the registry. Defaults to `1`. * `:listeners` - a list of named processes which are notified of register and unregister events. The registered process must be monitored by the listener if the listener wants to be notified if the registered process crashes. Messages sent to listeners are of type `t:listener_message/0`. * `:meta` - a keyword list of metadata to be attached to the registry. ### Registry.unregister/2 (function) Unregisters all entries for the given `key` associated to the current process in `registry`. Always returns `:ok` and automatically unlinks the current process from the owner if there are no more keys associated to the current process. See also `register/3` to read more about the "owner". If the registry has listeners specified via the `:listeners` option in `start_link/1`, those listeners will be notified of the unregistration and will receive a message of type `t:listener_message/0`. ### Examples - Registry.unregister/2 (function) For unique registries: iex> Registry.start_link(keys: :unique, name: Registry.UniqueUnregisterTest) iex> Registry.register(Registry.UniqueUnregisterTest, "hello", :world) iex> Registry.keys(Registry.UniqueUnregisterTest, self()) ["hello"] iex> Registry.unregister(Registry.UniqueUnregisterTest, "hello") :ok iex> Registry.keys(Registry.UniqueUnregisterTest, self()) [] For duplicate registries: iex> Registry.start_link(keys: :duplicate, name: Registry.DuplicateUnregisterTest) iex> Registry.register(Registry.DuplicateUnregisterTest, "hello", :world) iex> Registry.register(Registry.DuplicateUnregisterTest, "hello", :world) iex> Registry.keys(Registry.DuplicateUnregisterTest, self()) ["hello", "hello"] iex> Registry.unregister(Registry.DuplicateUnregisterTest, "hello") :ok iex> Registry.keys(Registry.DuplicateUnregisterTest, self()) [] ### Registry.unregister_match/4 (function) Unregisters entries for keys matching a pattern associated to the current process in `registry`. ### Examples - Registry.unregister_match/4 (function) For unique registries it can be used to conditionally unregister a key on the basis of whether or not it matches a particular value. iex> Registry.start_link(keys: :unique, name: Registry.UniqueUnregisterMatchTest) iex> Registry.register(Registry.UniqueUnregisterMatchTest, "hello", :world) iex> Registry.keys(Registry.UniqueUnregisterMatchTest, self()) ["hello"] iex> Registry.unregister_match(Registry.UniqueUnregisterMatchTest, "hello", :foo) :ok iex> Registry.keys(Registry.UniqueUnregisterMatchTest, self()) ["hello"] iex> Registry.unregister_match(Registry.UniqueUnregisterMatchTest, "hello", :world) :ok iex> Registry.keys(Registry.UniqueUnregisterMatchTest, self()) [] For duplicate registries: iex> Registry.start_link(keys: :duplicate, name: Registry.DuplicateUnregisterMatchTest) iex> Registry.register(Registry.DuplicateUnregisterMatchTest, "hello", :world_a) iex> Registry.register(Registry.DuplicateUnregisterMatchTest, "hello", :world_b) iex> Registry.register(Registry.DuplicateUnregisterMatchTest, "hello", :world_c) iex> Registry.keys(Registry.DuplicateUnregisterMatchTest, self()) ["hello", "hello", "hello"] iex> Registry.unregister_match(Registry.DuplicateUnregisterMatchTest, "hello", :world_a) :ok iex> Registry.keys(Registry.DuplicateUnregisterMatchTest, self()) ["hello", "hello"] iex> Registry.lookup(Registry.DuplicateUnregisterMatchTest, "hello") [{self(), :world_b}, {self(), :world_c}] ### Registry.update_value/3 (function) Updates the value for `key` for the current process in the unique `registry`. Returns a `{new_value, old_value}` tuple or `:error` if there is no such key assigned to the current process. If a non-unique registry is given, an error is raised. ### Examples - Registry.update_value/3 (function) iex> Registry.start_link(keys: :unique, name: Registry.UpdateTest) iex> {:ok, _} = Registry.register(Registry.UpdateTest, "hello", 1) iex> Registry.lookup(Registry.UpdateTest, "hello") [{self(), 1}] iex> Registry.update_value(Registry.UpdateTest, "hello", &(&1 + 1)) {2, 1} iex> Registry.lookup(Registry.UpdateTest, "hello") [{self(), 2}] ### Registry.values/3 (function) Reads the values for the given `key` for `pid` in `registry`. For unique registries, it is either an empty list or a list with a single element. For duplicate registries, it is a list with zero, one, or multiple elements. ### Examples - Registry.values/3 (function) In the example below we register the current process and look it up both from itself and other processes: iex> Registry.start_link(keys: :unique, name: Registry.UniqueValuesTest) iex> Registry.values(Registry.UniqueValuesTest, "hello", self()) [] iex> {:ok, _} = Registry.register(Registry.UniqueValuesTest, "hello", :world) iex> Registry.values(Registry.UniqueValuesTest, "hello", self()) [:world] iex> Task.async(fn -> Registry.values(Registry.UniqueValuesTest, "hello", self()) end) |> Task.await() [] iex> parent = self() iex> Task.async(fn -> Registry.values(Registry.UniqueValuesTest, "hello", parent) end) |> Task.await() [:world] The same applies to duplicate registries: iex> Registry.start_link(keys: :duplicate, name: Registry.DuplicateValuesTest) iex> Registry.values(Registry.DuplicateValuesTest, "hello", self()) [] iex> {:ok, _} = Registry.register(Registry.DuplicateValuesTest, "hello", :world) iex> Registry.values(Registry.DuplicateValuesTest, "hello", self()) [:world] iex> {:ok, _} = Registry.register(Registry.DuplicateValuesTest, "hello", :another) iex> Enum.sort(Registry.values(Registry.DuplicateValuesTest, "hello", self())) [:another, :world] ### Registry.body/0 (type) A pattern used to representing the output format part of a match spec ### Registry.guard/0 (type) A guard to be evaluated when matching on objects in a registry ### Registry.guards/0 (type) A list of guards to be evaluated when matching on objects in a registry ### Registry.key/0 (type) The type of keys allowed on registration ### Registry.keys/0 (type) The type of the registry ### Registry.listener_message/0 (type) The message that the registry sends to listeners when a process registers or unregisters. See the `:listeners` option in `start_link/1`. ### Registry.match_pattern/0 (type) A pattern to match on objects in a registry ### Registry.meta_key/0 (type) The type of registry metadata keys ### Registry.meta_value/0 (type) The type of registry metadata values ### Registry.registry/0 (type) The registry identifier ### Registry.spec/0 (type) A full match spec used when selecting objects in the registry ### Registry.start_option/0 (type) Options used for `child_spec/1` and `start_link/1` ### Registry.value/0 (type) The type of values allowed on registration ### Supervisor (behaviour) A behaviour module for implementing supervisors. A supervisor is a process which supervises other processes, which we refer to as *child processes*. Supervisors are used to build a hierarchical process structure called a *supervision tree*. Supervision trees provide fault-tolerance and encapsulate how our applications start and shutdown. A supervisor may be started directly with a list of child specifications via `start_link/2` or you may define a module-based supervisor that implements the required callbacks. The sections below use `start_link/2` to start supervisors in most examples, but it also includes a specific section on module-based ones. ### Examples - Supervisor (behaviour) In order to start a supervisor, we need to first define a child process that will be supervised. As an example, we will define a `GenServer`, a generic server, that keeps a counter. Other processes can then send messages to this process to read the counter and bump its value. > #### Disclaimer {: .neutral} > > In practice you would not define a counter as a GenServer. Instead, > if you need a counter, you would pass it around as inputs and outputs to > the functions that need it. The reason we picked a counter in this example > is due to its simplicity, as it allows us to focus on how supervisors work. defmodule Counter do use GenServer def start_link(arg) when is_integer(arg) do GenServer.start_link(__MODULE__, arg, name: __MODULE__) end ### Callbacks - Supervisor (behaviour) @impl true def init(counter) do {:ok, counter} end @impl true def handle_call(:get, _from, counter) do {:reply, counter, counter} end def handle_call({:bump, value}, _from, counter) do {:reply, counter, counter + value} end end The `Counter` receives an argument on `start_link`. This argument is passed to the `init/1` callback which becomes the initial value of the counter. Our counter handles two operations (known as calls): `:get`, to get the current counter value, and `:bump`, that bumps the counter by the given `value` and returns the old counter. We can now start a supervisor that will start and supervise our counter process. The first step is to define a list of **child specifications** that control how each child behaves. Each child specification is a map, as shown below: children = [ # The Counter is a child started via Counter.start_link(0) %{ id: Counter, start: {Counter, :start_link, [0]} } ] # Now we start the supervisor with the children and a strategy {:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one) # After started, we can query the supervisor for information Supervisor.count_children(pid) #=> %{active: 1, specs: 1, supervisors: 0, workers: 1} Note that when starting the GenServer, we are registering it with name `Counter` via the `name: __MODULE__` option. This allows us to call it directly and get its value: GenServer.call(Counter, :get) #=> 0 GenServer.call(Counter, {:bump, 3}) #=> 0 GenServer.call(Counter, :get) #=> 3 However, there is a bug in our counter server. If we call `:bump` with a non-numeric value, it is going to crash: GenServer.call(Counter, {:bump, "oops"}) ** (exit) exited in: GenServer.call(Counter, {:bump, "oops"}, 5000) Luckily, since the server is being supervised by a supervisor, the supervisor will automatically start a new one, reset back to its initial value of `0`: GenServer.call(Counter, :get) #=> 0 Supervisors support different strategies; in the example above, we have chosen `:one_for_one`. Furthermore, each supervisor can have many workers and/or supervisors as children, with each one having its own configuration (as outlined in the "Child specification" section). The rest of this document will cover how child processes are specified, how they can be started and stopped, different supervision strategies and more. ### Child specification - Supervisor (behaviour) The child specification describes how the supervisor starts, shuts down, and restarts child processes. The child specification is a map containing up to 6 elements. The first two keys in the following list are required, and the remaining ones are optional: * `:id` - any term used to identify the child specification internally by the supervisor; defaults to the given module. This key is required. For supervisors, in the case of conflicting `:id` values, the supervisor will refuse to initialize and require explicit IDs. This is not the case for [dynamic supervisors](`DynamicSupervisor`) though. * `:start` - a tuple with the module-function-args to be invoked to start the child process. This key is required. * `:restart` - an atom that defines when a terminated child process should be restarted (see the "Restart values" section below). This key is optional and defaults to `:permanent`. * `:shutdown` - an integer or atom that defines how a child process should be terminated (see the "Shutdown values" section below). This key is optional and defaults to `5_000` if the type is `:worker` or `:infinity` if the type is `:supervisor`. * `:type` - specifies that the child process is a `:worker` or a `:supervisor`. This key is optional and defaults to `:worker`. * `:modules` - a list of modules used by hot code upgrade mechanisms to determine which processes are using certain modules. It is typically set to the callback module of behaviours like `GenServer`, `Supervisor`, and such. It is set automatically based on the `:start` value and it is rarely changed in practice. * `:significant` - a boolean indicating if the child process should be considered significant with regard to automatic shutdown. Only `:transient` and `:temporary` child processes can be marked as significant. This key is optional and defaults to `false`. See section "Automatic shutdown" below for more details. Let's understand what the `:shutdown` and `:restart` options control. ### Shutdown values (:shutdown) - Supervisor (behaviour) The following shutdown values are supported in the `:shutdown` option: * `:brutal_kill` - the child process is unconditionally and immediately terminated using `Process.exit(child, :kill)`. * any integer >= 0 - the amount of time in milliseconds that the supervisor will wait for its children to terminate after emitting a `Process.exit(child, :shutdown)` signal. If the child process is not trapping exits, the initial `:shutdown` signal will terminate the child process immediately. If the child process is trapping exits, it has the given amount of time to terminate. If it doesn't terminate within the specified time, the child process is unconditionally terminated by the supervisor via `Process.exit(child, :kill)`. * `:infinity` - works as an integer except the supervisor will wait indefinitely for the child to terminate. If the child process is a supervisor, the recommended value is `:infinity` to give the supervisor and its children enough time to shut down. This option can be used with regular workers but doing so is discouraged and requires extreme care. If not used carefully, the child process will never terminate, preventing your application from terminating as well. ### Restart values (:restart) - Supervisor (behaviour) The `:restart` option controls what the supervisor should consider to be a successful termination or not. If the termination is successful, the supervisor won't restart the child. If the child process crashed, the supervisor will start a new one. The following restart values are supported in the `:restart` option: * `:permanent` - the child process is always restarted. * `:temporary` - the child process is never restarted, regardless of the supervision strategy: any termination (even abnormal) is considered successful. * `:transient` - the child process is restarted only if it terminates abnormally, i.e., with an exit reason other than `:normal`, `:shutdown`, or `{:shutdown, term}`. For a more complete understanding of the exit reasons and their impact, see the "Exit reasons and restarts" section. ## `child_spec/1` function When starting a supervisor, we may pass a list of child specifications. Those specifications are maps that tell how the supervisor should start, stop and restart each of its children: %{ id: Counter, start: {Counter, :start_link, [0]} } The map above defines a child with `:id` of `Counter` that is started by calling `Counter.start_link(0)`. However, defining the child specification for each child as a map can be quite error prone, as we may change the `Counter` implementation and forget to update its specification. That's why Elixir allows you to pass a tuple with the module name and the `start_link` argument instead of the specification: children = [ {Counter, 0} ] The supervisor will then invoke `Counter.child_spec(0)` to retrieve a child specification. Now the `Counter` module is responsible for building its own specification, for example, we could write: def child_spec(arg) do %{ id: Counter, start: {Counter, :start_link, [arg]} } end Then the supervisor will call `Counter.start_link(arg)` to start the child process. This flow is summarized in the diagram below. Caller is a process which spawns the Supervisor process. The Supervisor then proceeds to call your code (Module) to spawn its child process: ```mermaid sequenceDiagram participant C as Caller (Process) participant S as Supervisor (Process) participant M as Module (Code) note right of C: child is a {module, arg} specification C->>+S: Supervisor.start_link([child]) S-->>+M: module.child_spec(arg) M-->>-S: %{id: term, start: {module, :start_link, [arg]}} S-->>+M: module.start_link(arg) M->>M: Spawns child process (child_pid) M-->>-S: {:ok, child_pid} | :ignore | {:error, reason} S->>-C: {:ok, supervisor_pid} | {:error, reason} ``` Luckily for us, `use GenServer` already defines a `Counter.child_spec/1` exactly like above, so you don't need to write the definition above yourself. If you want to customize the automatically generated `child_spec/1` function, you can pass the options directly to `use GenServer`: use GenServer, restart: :transient Finally, note it is also possible to simply pass the `Counter` module as a child: children = [ Counter ] When only the module name is given, it is equivalent to `{Counter, []}`, which in our case would be invalid, which is why we always pass the initial counter explicitly. By replacing the child specification with `{Counter, 0}`, we keep it encapsulated in the `Counter` module. We could now share our `Counter` implementation with other developers and they can add it directly to their supervision tree without worrying about the low-level details of the counter. Overall, a child specification can be one of the following: * a map representing the child specification itself - as outlined in the "Child specification" section * a tuple with a module as first element and the start argument as second - such as `{Counter, 0}`. In this case, `Counter.child_spec(0)` is called to retrieve the child specification * a module - such as `Counter`. In this case, `Counter.child_spec([])` would be called, which is invalid for the counter, but it is useful in many other cases, especially when you want to pass a list of options to the child process If you need to convert a `{module, arg}` tuple or a module child specification to a [child specification](`t:child_spec/0`) or modify a child specification itself, you can use the `Supervisor.child_spec/2` function. For example, to run the counter with a different `:id` and a `:shutdown` value of 10 seconds (10_000 milliseconds): children = [ Supervisor.child_spec({Counter, 0}, id: MyCounter, shutdown: 10_000) ] ### Supervisor strategies and options - Supervisor (behaviour) So far we have started the supervisor passing a single child as a tuple as well as a strategy called `:one_for_one`: children = [ {Counter, 0} ] Supervisor.start_link(children, strategy: :one_for_one) The first argument given to `start_link/2` is a list of child specifications as defined in the "child_spec/1" section above. The second argument is a keyword list of options: * `:strategy` - the supervision strategy option. It can be either `:one_for_one`, `:rest_for_one` or `:one_for_all`. Required. See the "Strategies" section. * `:max_restarts` - the maximum number of restarts allowed in a time frame. Defaults to `3`. * `:max_seconds` - the time frame in which `:max_restarts` applies. Defaults to `5`. * `:auto_shutdown` - the automatic shutdown option. It can be `:never`, `:any_significant`, or `:all_significant`. Optional. See the "Automatic shutdown" section. * `:name` - a name to register the supervisor process. Supported values are explained in the "Name registration" section in the documentation for `GenServer`. Optional. ### Strategies - Supervisor (behaviour) Supervisors support different supervision strategies (through the `:strategy` option, as seen above): * `:one_for_one` - if a child process terminates, only that process is restarted. * `:one_for_all` - if a child process terminates, all other child processes are terminated and then all child processes (including the terminated one) are restarted. * `:rest_for_one` - if a child process terminates, the terminated child process and the rest of the children started after it, are terminated and restarted. In the above, process termination refers to unsuccessful termination, which is determined by the `:restart` option. To efficiently supervise children started dynamically, see `DynamicSupervisor`. ### Automatic shutdown - Supervisor (behaviour) Supervisors have the ability to automatically shut themselves down when child processes marked as `:significant` exit. Supervisors support different automatic shutdown options (through the `:auto_shutdown` option, as seen above): * `:never` - this is the default, automatic shutdown is disabled. * `:any_significant` - if any significant child process exits, the supervisor will automatically shut down its children, then itself. * `:all_significant` - when all significant child processes have exited, the supervisor will automatically shut down its children, then itself. Only `:transient` and `:temporary` child processes can be marked as significant, and this configuration affects the behavior. Significant `:transient` child processes must exit normally for automatic shutdown to be considered, where `:temporary` child processes may exit for any reason. ### Name registration - Supervisor (behaviour) A supervisor is bound to the same name registration rules as a `GenServer`. Read more about these rules in the documentation for `GenServer`. ### Module-based supervisors - Supervisor (behaviour) In the example so far, the supervisor was started by passing the supervision structure to `start_link/2`. However, supervisors can also be created by explicitly defining a supervision module: defmodule MyApp.Supervisor do # Automatically defines child_spec/1 use Supervisor def start_link(init_arg) do Supervisor.start_link(__MODULE__, init_arg, name: __MODULE__) end @impl true def init(_init_arg) do children = [ {Counter, 0} ] Supervisor.init(children, strategy: :one_for_one) end end The difference between the two approaches is that a module-based supervisor gives you more direct control over how the supervisor is initialized. Instead of calling `Supervisor.start_link/2` with a list of child specifications that are implicitly initialized for us, we must explicitly initialize the children by calling `Supervisor.init/2` inside its `c:init/1` callback. `Supervisor.init/2` accepts the same `:strategy`, `:max_restarts`, and `:max_seconds` options as `start_link/2`. > #### `use Supervisor` {: .info} > > When you `use Supervisor`, the `Supervisor` module will > set `@behaviour Supervisor` and define a `child_spec/1` > function, so your module can be used as a child > in a supervision tree. `use Supervisor` also defines a `child_spec/1` function which allows us to run `MyApp.Supervisor` as a child of another supervisor or at the top of your supervision tree as: children = [ MyApp.Supervisor ] Supervisor.start_link(children, strategy: :one_for_one) A general guideline is to use the supervisor without a callback module only at the top of your supervision tree, generally in the `c:Application.start/2` callback. We recommend using module-based supervisors for any other supervisor in your application, so they can run as a child of another supervisor in the tree. The `child_spec/1` generated automatically by `Supervisor` can be customized with the following options: * `:id` - the child specification identifier, defaults to the current module * `:restart` - when the supervisor should be restarted, defaults to `:permanent` The `@doc` annotation immediately preceding `use Supervisor` will be attached to the generated `child_spec/1` function. ### Start and shutdown - Supervisor (behaviour) When the supervisor starts, it traverses all child specifications and then starts each child in the order they are defined. This is done by calling the function defined under the `:start` key in the child specification and typically defaults to `start_link/1`. The `start_link/1` (or a custom) is then called for each child process. The `start_link/1` function must return `{:ok, pid}` where `pid` is the process identifier of a new process that is linked to the supervisor. The child process usually starts its work by executing the `c:init/1` callback. Generally speaking, the `init` callback is where we initialize and configure the child process. The shutdown process happens in reverse order. When a supervisor shuts down, it terminates all children in the opposite order they are listed. The termination happens by sending a shutdown exit signal, via `Process.exit(child_pid, :shutdown)`, to the child process and then awaiting for a time interval for the child process to terminate. This interval defaults to 5000 milliseconds. If the child process does not terminate in this interval, the supervisor abruptly terminates the child with reason `:kill`. The shutdown time can be configured in the child specification which is fully detailed in the next section. If the child process is not trapping exits, it will shutdown immediately when it receives the first exit signal. If the child process is trapping exits, then the `terminate` callback is invoked, and the child process must terminate in a reasonable time interval before being abruptly terminated by the supervisor. In other words, if it is important that a process cleans after itself when your application or the supervision tree is shutting down, then this process must trap exits and its child specification should specify the proper `:shutdown` value, ensuring it terminates within a reasonable interval. ### Exit reasons and restarts - Supervisor (behaviour) A supervisor restarts a child process depending on its `:restart` configuration. For example, when `:restart` is set to `:transient`, the supervisor does not restart the child in case it exits with reason `:normal`, `:shutdown` or `{:shutdown, term}`. Those exits also impact logging. By default, behaviours such as GenServers do not emit error logs when the exit reason is `:normal`, `:shutdown` or `{:shutdown, term}`. So one may ask: which exit reason should I choose? There are three options: * `:normal` - in such cases, the exit won't be logged, there is no restart in transient mode, and linked processes do not exit * `:shutdown` or `{:shutdown, term}` - in such cases, the exit won't be logged, there is no restart in transient mode, and linked processes exit with the same reason unless they're trapping exits * any other term - in such cases, the exit will be logged, there are restarts in transient mode, and linked processes exit with the same reason unless they're trapping exits Generally speaking, if you are exiting for expected reasons, you want to use `:shutdown` or `{:shutdown, term}`. Note that the supervisor that reaches maximum restart intensity will exit with `:shutdown` reason. In this case the supervisor will only be restarted if its child specification was defined with the `:restart` option set to `:permanent` (the default). ### Supervisor.child_spec/2 (function) Builds and overrides a child specification. Similar to `start_link/2` and `init/2`, it expects a module, `{module, arg}`, or a [child specification](`t:child_spec/0`). If a two-element tuple in the shape of `{module, arg}` is given, the child specification is retrieved by calling `module.child_spec(arg)`. If a module is given, the child specification is retrieved by calling `module.child_spec([])`. After the child specification is retrieved, the fields on `overrides` are directly applied to the child spec. If `overrides` has keys that do not map to any child specification field, an error is raised. See the "Child specification" section in the module documentation for all of the available keys for overriding. ### Examples - Supervisor.child_spec/2 (function) This function is often used to set an `:id` option when the same module needs to be started multiple times in the supervision tree: Supervisor.child_spec({Agent, fn -> :ok end}, id: {Agent, 1}) #=> %{id: {Agent, 1}, #=> start: {Agent, :start_link, [fn -> :ok end]}} ### Supervisor.count_children/1 (function) Returns a map containing count values for the given supervisor. The map contains the following keys: * `:specs` - the total count of children, dead or alive * `:active` - the count of all actively running child processes managed by this supervisor * `:supervisors` - the count of all supervisors whether or not these child supervisors are still alive * `:workers` - the count of all workers, whether or not these child workers are still alive ### Supervisor.delete_child/2 (function) Deletes the child specification identified by `child_id`. The corresponding child process must not be running; use `terminate_child/2` to terminate it if it's running. If successful, this function returns `:ok`. This function may return an error with an appropriate error tuple if the `child_id` is not found, or if the current process is running or being restarted. ### Supervisor.init/1 (callback) Callback invoked to start the supervisor and during hot code upgrades. Developers typically invoke `Supervisor.init/2` at the end of their init callback to return the proper supervision flags. ### Supervisor.init/2 (function) Receives a list of child specifications to initialize and a set of `options`. This is typically invoked at the end of the `c:init/1` callback of module-based supervisors. See the sections "Supervisor strategies and options" and "Module-based supervisors" in the module documentation for more information. This function returns a tuple containing the supervisor flags and child specifications. ### Examples - Supervisor.init/2 (function) def init(_init_arg) do children = [ {Counter, 0} ] Supervisor.init(children, strategy: :one_for_one) end ### Options - Supervisor.init/2 (function) * `:strategy` - the supervision strategy option. It can be either `:one_for_one`, `:rest_for_one`, or `:one_for_all` * `:max_restarts` - the maximum number of restarts allowed in a time frame. Defaults to `3`. * `:max_seconds` - the time frame in seconds in which `:max_restarts` applies. Defaults to `5`. * `:auto_shutdown` - the automatic shutdown option. It can be either `:never`, `:any_significant`, or `:all_significant` The `:strategy` option is required and by default a maximum of 3 restarts is allowed within 5 seconds. Check the `Supervisor` module for a detailed description of the available strategies. ### Supervisor.restart_child/2 (function) Restarts a child process identified by `child_id`. The child specification must exist and the corresponding child process must not be running. Note that for temporary children, the child specification is automatically deleted when the child terminates, and thus it is not possible to restart such children. If the child process start function returns `{:ok, child}` or `{:ok, child, info}`, the PID is added to the supervisor and this function returns the same value. If the child process start function returns `:ignore`, the PID remains set to `:undefined` and this function returns `{:ok, :undefined}`. This function may return an error with an appropriate error tuple if the `child_id` is not found, or if the current process is running or being restarted. If the child process start function returns an error tuple or an erroneous value, or if it fails, this function returns `{:error, error}`. ### Supervisor.start_child/2 (function) Adds a child specification to `supervisor` and starts that child. `child_spec` should be a valid child specification. The child process will be started as defined in the child specification. If a child specification with the specified ID already exists, `child_spec` is discarded and this function returns an error with `:already_started` or `:already_present` if the corresponding child process is running or not, respectively. If the child process start function returns `{:ok, child}` or `{:ok, child, info}`, then child specification and PID are added to the supervisor and this function returns the same value. If the child process start function returns `:ignore`, the child specification is added to the supervisor, the PID is set to `:undefined` and this function returns `{:ok, :undefined}`. If the child process start function returns an error tuple or an erroneous value, or if it fails, the child specification is discarded and this function returns `{:error, error}` where `error` is a term containing information about the error and child specification. ### Supervisor.start_link/2 (function) Starts a supervisor with the given children. `children` is a list of the following forms: * a child specification (see `t:child_spec/0`) * a module, where the supervisor calls `module.child_spec([])` to retrieve the child specification (see `t:module_spec/0`) * a `{module, arg}` tuple, where the supervisor calls `module.child_spec(arg)` to retrieve the child specification (see `t:module_spec/0`) * a (old) Erlang-style child specification (see [`:supervisor.child_spec()`](`t::supervisor.child_spec/0`)) A strategy is required to be provided through the `:strategy` option. See "Supervisor strategies and options" for examples and other options. The options can also be used to register a supervisor name. The supported values are described under the "Name registration" section in the `GenServer` module docs. If the supervisor and all child processes are successfully spawned (if the start function of each child process returns `{:ok, child}`, `{:ok, child, info}`, or `:ignore`), this function returns `{:ok, pid}`, where `pid` is the PID of the supervisor. If the supervisor is given a name and a process with the specified name already exists, the function returns `{:error, {:already_started, pid}}`, where `pid` is the PID of that process. If the start function of any of the child processes fails or returns an error tuple or an erroneous value, the supervisor first terminates with reason `:shutdown` all the child processes that have already been started, and then terminates itself and returns `{:error, {:shutdown, reason}}`. Note that a supervisor started with this function is linked to the parent process and exits not only on crashes but also if the parent process exits with `:normal` reason. ### Supervisor.start_link/3 (function) Starts a module-based supervisor process with the given `module` and `init_arg`. To start the supervisor, the `c:init/1` callback will be invoked in the given `module`, with `init_arg` as its argument. The `c:init/1` callback must return a supervisor specification which can be created with the help of the `init/2` function. If the `c:init/1` callback returns `:ignore`, this function returns `:ignore` as well and the supervisor terminates with reason `:normal`. If it fails or returns an incorrect value, this function returns `{:error, term}` where `term` is a term with information about the error, and the supervisor terminates with reason `term`. The `:name` option can also be given in order to register a supervisor name, the supported values are described in the "Name registration" section in the `GenServer` module docs. ### Supervisor.stop/3 (function) Synchronously stops the given supervisor with the given `reason`. It returns `:ok` if the supervisor terminates with the given reason. If it terminates with another reason, the call exits. This function keeps OTP semantics regarding error reporting. If the reason is any other than `:normal`, `:shutdown` or `{:shutdown, _}`, an error report is logged. ### Supervisor.terminate_child/2 (function) Terminates the given child identified by `child_id`. The process is terminated, if there's one. The child specification is kept unless the child is temporary. A non-temporary child process may later be restarted by the supervisor. The child process can also be restarted explicitly by calling `restart_child/2`. Use `delete_child/2` to remove the child specification. If successful, this function returns `:ok`. If there is no child specification for the given child ID, this function returns `{:error, :not_found}`. ### Supervisor.which_children/1 (function) Returns a list with information about all children of the given supervisor. Note that calling this function when supervising a large number of children under low memory conditions can cause an out of memory exception. This function returns a list of `{id, child, type, modules}` tuples, where: * `id` - as defined in the child specification * `child` - the PID of the corresponding child process, `:restarting` if the process is about to be restarted, or `:undefined` if there is no such process * `type` - `:worker` or `:supervisor`, as specified by the child specification * `modules` - as specified by the child specification ### Supervisor.auto_shutdown/0 (type) Supported automatic shutdown options. ### Supervisor.child/0 (type) A child process. It can be a PID when the child process was started, or `:undefined` when the child was created by a [dynamic supervisor](`DynamicSupervisor`). ### Supervisor.child_spec/0 (type) The supervisor child specification. It defines how the supervisor should start, stop and restart each of its children. ### Supervisor.init_option/0 (type) Options given to `start_link/2` and `init/2`. ### Supervisor.module_spec/0 (type) A module-based child spec. This is a form of child spec that you can pass to functions such as `child_spec/2`, `start_child/2`, and `start_link/2`, in addition to the normalized `t:child_spec/0`. A module-based child spec can be: * a **module** — the supervisor calls `module.child_spec([])` to retrieve the child specification * a **two-element tuple** in the shape of `{module, arg}` — the supervisor calls `module.child_spec(arg)` to retrieve the child specification ### Supervisor.name/0 (type) The supervisor name. ### Supervisor.on_start/0 (type) Return values of `start_link/2` and `start_link/3`. ### Supervisor.on_start_child/0 (type) Return values of `start_child/2`. ### Supervisor.option/0 (type) Option values used by the `start_link/2` and `start_link/3` functions. ### Supervisor.restart/0 (type) Supported restart options. ### Supervisor.shutdown/0 (type) Supported shutdown options. ### Supervisor.strategy/0 (type) Supported strategies. ### Supervisor.sup_flags/0 (type) The supervisor flags returned on init. ### Supervisor.supervisor/0 (type) The supervisor reference. ### Supervisor.type/0 (type) Type of a supervised child. Whether the supervised child is a worker or a supervisor. ### Task (module) Conveniences for spawning and awaiting tasks. Tasks are processes meant to execute one particular action throughout their lifetime, often with little or no communication with other processes. The most common use case for tasks is to convert sequential code into concurrent code by computing a value asynchronously: task = Task.async(fn -> do_some_work() end) res = do_some_other_work() res + Task.await(task) Tasks spawned with `async` can be awaited on by their caller process (and only their caller) as shown in the example above. They are implemented by spawning a process that sends a message to the caller once the given computation is performed. Compared to plain processes, started with `spawn/1`, tasks include monitoring metadata and logging in case of errors. Besides `async/1` and `await/2`, tasks can also be started as part of a supervision tree and dynamically spawned on remote nodes. We will explore these scenarios next. ### async and await - Task (module) One of the common uses of tasks is to convert sequential code into concurrent code with `Task.async/1` while keeping its semantics. When invoked, a new process will be created, linked and monitored by the caller. Once the task action finishes, a message will be sent to the caller with the result. `Task.await/2` is used to read the message sent by the task. There are two important things to consider when using `async`: 1. If you are using async tasks, you **must await** a reply as they are *always* sent. If you are not expecting a reply, consider using `Task.start_link/1` as detailed below. 2. Async tasks link the caller and the spawned process. This means that, if the caller crashes, the task will crash too and vice-versa. This is on purpose: if the process meant to receive the result no longer exists, there is no purpose in completing the computation. If this is not desired, you will want to use supervised tasks, described in a subsequent section. ### Tasks are processes - Task (module) Tasks are processes and so data will need to be completely copied to them. Take the following code as an example: large_data = fetch_large_data() task = Task.async(fn -> do_some_work(large_data) end) res = do_some_other_work() res + Task.await(task) The code above copies over all of `large_data`, which can be resource intensive depending on the size of the data. There are two ways to address this. First, if you need to access only part of `large_data`, consider extracting it before the task: large_data = fetch_large_data() subset_data = large_data.some_field task = Task.async(fn -> do_some_work(subset_data) end) Alternatively, if you can move the data loading altogether to the task, it may be even better: task = Task.async(fn -> large_data = fetch_large_data() do_some_work(large_data) end) ### Dynamically supervised tasks - Task (module) The `Task.Supervisor` module allows developers to dynamically create multiple supervised tasks. A short example is: {:ok, pid} = Task.Supervisor.start_link() task = Task.Supervisor.async(pid, fn -> # Do something end) Task.await(task) However, in the majority of cases, you want to add the task supervisor to your supervision tree: Supervisor.start_link([ {Task.Supervisor, name: MyApp.TaskSupervisor} ], strategy: :one_for_one) And now you can use async/await by passing the name of the supervisor instead of the pid: Task.Supervisor.async(MyApp.TaskSupervisor, fn -> # Do something end) |> Task.await() We encourage developers to rely on supervised tasks as much as possible. Supervised tasks improve the visibility of how many tasks are running at a given moment and enable a variety of patterns that give you explicit control on how to handle the results, errors, and timeouts. Here is a summary: * Using `Task.Supervisor.start_child/2` allows you to start a fire-and-forget task when you don't care about its results or if it completes successfully or not. * Using `Task.Supervisor.async/2` + `Task.await/2` allows you to execute tasks concurrently and retrieve its result. If the task fails, the caller will also fail. * Using `Task.Supervisor.async_nolink/2` + `Task.yield/2` + `Task.shutdown/2` allows you to execute tasks concurrently and retrieve their results or the reason they failed within a given time frame. If the task fails, the caller won't fail. You will receive the error reason either on `yield` or `shutdown`. Furthermore, the supervisor guarantees all tasks terminate within a configurable shutdown period when your application shuts down. See the `Task.Supervisor` module for details on the supported operations. ### Distributed tasks - Task (module) With `Task.Supervisor`, it is easy to dynamically start tasks across nodes: # First on the remote node named :remote@local Task.Supervisor.start_link(name: MyApp.DistSupervisor) # Then on the local client node supervisor = {MyApp.DistSupervisor, :remote@local} Task.Supervisor.async(supervisor, MyMod, :my_fun, [arg1, arg2, arg3]) Note that, as above, when working with distributed tasks, one should use the `Task.Supervisor.async/5` function that expects explicit module, function, and arguments, instead of `Task.Supervisor.async/3` that works with anonymous functions. That's because anonymous functions expect the same module version to exist on all involved nodes. Check the `Agent` module documentation for more information on distributed processes as the limitations described there apply to the whole ecosystem. ### Statically supervised tasks - Task (module) The `Task` module implements the `child_spec/1` function, which allows it to be started directly under a regular `Supervisor` - instead of a `Task.Supervisor` - by passing a tuple with a function to run: Supervisor.start_link([ {Task, fn -> :some_work end} ], strategy: :one_for_one) This is often useful when you need to execute some steps while setting up your supervision tree. For example: to warm up caches, log the initialization status, and such. If you don't want to put the Task code directly under the `Supervisor`, you can wrap the `Task` in its own module, similar to how you would do with a `GenServer` or an `Agent`: defmodule MyTask do use Task def start_link(arg) do Task.start_link(__MODULE__, :run, [arg]) end def run(arg) do # ... end end And then passing it to the supervisor: Supervisor.start_link([ {MyTask, arg} ], strategy: :one_for_one) Since these tasks are supervised and not directly linked to the caller, they cannot be awaited on. By default, the functions `Task.start/1` and `Task.start_link/1` are for fire-and-forget tasks, where you don't care about the results or if it completes successfully or not. > #### `use Task` {: .info} > > When you `use Task`, the `Task` module will define a > `child_spec/1` function, so your module can be used > as a child in a supervision tree. `use Task` defines a `child_spec/1` function, allowing the defined module to be put under a supervision tree. The generated `child_spec/1` can be customized with the following options: * `:id` - the child specification identifier, defaults to the current module * `:restart` - when the child should be restarted, defaults to `:temporary` * `:shutdown` - how to shut down the child, either immediately or by giving it time to shut down Opposite to `GenServer`, `Agent` and `Supervisor`, a Task has a default `:restart` of `:temporary`. This means the task will not be restarted even if it crashes. If you desire the task to be restarted for non-successful exits, do: use Task, restart: :transient If you want the task to always be restarted: use Task, restart: :permanent See the "Child specification" section in the `Supervisor` module for more detailed information. The `@doc` annotation immediately preceding `use Task` will be attached to the generated `child_spec/1` function. ### Ancestor and Caller Tracking - Task (module) Whenever you start a new process, Elixir annotates the parent of that process through the `$ancestors` key in the process dictionary. This is often used to track the hierarchy inside a supervision tree. For example, we recommend developers to always start tasks under a supervisor. This provides more visibility and allows you to control how those tasks are terminated when a node shuts down. That might look something like `Task.Supervisor.start_child(MySupervisor, task_function)`. This means that, although your code is the one invoking the task, the actual ancestor of the task is the supervisor, as the supervisor is the one effectively starting it. To track the relationship between your code and the task, we use the `$callers` key in the process dictionary. Therefore, assuming the `Task.Supervisor` call above, we have: [your code] -- calls --> [supervisor] ---- spawns --> [task] Which means we store the following relationships: [your code] [supervisor] <-- ancestor -- [task] ^ | |--------------------- caller ---------------------| The list of callers of the current process can be retrieved from the Process dictionary with `Process.get(:"$callers")`. This will return either `nil` or a list `[pid_n, ..., pid2, pid1]` with at least one entry where `pid_n` is the PID that called the current process, `pid2` called `pid_n`, and `pid2` was called by `pid1`. If a task crashes, the callers field is included as part of the log message metadata under the `:callers` key. ### Task.__struct__/0 (function) The Task struct. It contains these fields: * `:mfa` - a three-element tuple containing the module, function name, and arity invoked to start the task in `async/1` and `async/3` * `:owner` - the PID of the process that started the task * `:pid` - the PID of the task process; `nil` if there is no process specifically assigned for the task * `:ref` - an opaque term used as the task monitor reference ### Task.async/1 (function) Starts a task that must be awaited on. `fun` must be a zero-arity anonymous function. This function spawns a process that is linked to and monitored by the caller process. A `Task` struct is returned containing the relevant information. If you start an `async`, you **must await**. This is either done by calling `Task.await/2` or `Task.yield/2` followed by `Task.shutdown/2` on the returned task. Alternatively, if you spawn a task inside a `GenServer`, then the `GenServer` will automatically await for you and call `c:GenServer.handle_info/2` with the task response and associated `:DOWN` message. Read the `Task` module documentation for more information about the general usage of async tasks. ### Linking - Task.async/1 (function) This function spawns a process that is linked to and monitored by the caller process. The linking part is important because it aborts the task if the parent process dies. It also guarantees the code before async/await has the same properties after you add the async call. For example, imagine you have this: x = heavy_fun() y = some_fun() x + y Now you want to make the `heavy_fun()` async: x = Task.async(&heavy_fun/0) y = some_fun() Task.await(x) + y As before, if `heavy_fun/0` fails, the whole computation will fail, including the caller process. If you don't want the task to fail then you must change the `heavy_fun/0` code in the same way you would achieve it if you didn't have the async call. For example, to either return `{:ok, val} | :error` results or, in more extreme cases, by using `try/rescue`. In other words, an asynchronous task should be thought of as an extension of the caller process rather than a mechanism to isolate it from all errors. If you don't want to link the caller to the task, then you must use a supervised task with `Task.Supervisor` and call `Task.Supervisor.async_nolink/2`. In any case, avoid any of the following: * Setting `:trap_exit` to `true` - trapping exits should be used only in special circumstances as it would make your process immune to not only exits from the task but from any other processes. Moreover, even when trapping exits, calling `await` will still exit if the task has terminated without sending its result back. * Unlinking the task process started with `async`/`await`. If you unlink the processes and the task does not belong to any supervisor, you may leave dangling tasks in case the caller process dies. ### Metadata - Task.async/1 (function) The task created with this function stores `:erlang.apply/2` in its `:mfa` metadata field, which is used internally to apply the anonymous function. Use `async/3` if you want another function to be used as metadata. ### Task.async/3 (function) Starts a task that must be awaited on. Similar to `async/1` except the function to be started is specified by the given `module`, `function_name`, and `args`. The `module`, `function_name`, and its arity are stored as a tuple in the `:mfa` field for reflection purposes. ### Task.async_stream/3 (function) Returns a stream that runs the given function `fun` concurrently on each element in `enumerable`. Works the same as `async_stream/5` but with an anonymous function instead of a module-function-arguments tuple. `fun` must be a one-arity anonymous function. Each `enumerable` element is passed as argument to the given function `fun` and processed by its own task. The tasks will be linked to the caller process, similarly to `async/1`. ### Example - Task.async_stream/3 (function) Count the code points in each string asynchronously, then add the counts together using reduce. iex> strings = ["long string", "longer string", "there are many of these"] iex> stream = Task.async_stream(strings, fn text -> text |> String.codepoints() |> Enum.count() end) iex> Enum.sum_by(stream, fn {:ok, num} -> num end) 47 See `async_stream/5` for discussion, options, and more examples. ### Task.async_stream/5 (function) Returns a stream where the given function (`module` and `function_name`) is mapped concurrently on each element in `enumerable`. Each element of `enumerable` will be prepended to the given `args` and processed by its own task. Those tasks will be linked to an intermediate process that is then linked to the caller process. This means a failure in a task terminates the caller process and a failure in the caller process terminates all tasks. When streamed, each task will emit `{:ok, value}` upon successful completion or `{:exit, reason}` if the caller is trapping exits. It's possible to have `{:exit, {element, reason}}` for exits using the `:zip_input_on_exit` option. The order of results depends on the value of the `:ordered` option. The level of concurrency and the time tasks are allowed to run can be controlled via options (see the "Options" section below). Consider using `Task.Supervisor.async_stream/6` to start tasks under a supervisor. If you find yourself trapping exits to ensure errors in the tasks do not terminate the caller process, consider using `Task.Supervisor.async_stream_nolink/6` to start tasks that are not linked to the caller process. ### Options - Task.async_stream/5 (function) * `:max_concurrency` - sets the maximum number of tasks to run at the same time. Defaults to `System.schedulers_online/0`. * `:ordered` - whether the results should be returned in the same order as the input stream. When the output is ordered, Elixir may need to buffer results to emit them in the original order. Setting this option to false disables the need to buffer at the cost of removing ordering. This is also useful when you're using the tasks only for the side effects. Note that regardless of what `:ordered` is set to, the tasks will process asynchronously. If you need to process elements in order, consider using `Enum.map/2` or `Enum.each/2` instead. Defaults to `true`. * `:timeout` - the maximum amount of time (in milliseconds or `:infinity`) each task is allowed to execute for. Defaults to `5000`. * `:on_timeout` - what to do when a task times out. The possible values are: * `:exit` (default) - the caller (the process that spawned the tasks) exits. * `:kill_task` - the task that timed out is killed. The value emitted for that task is `{:exit, :timeout}`. * `:zip_input_on_exit` - (since v1.14.0) adds the original input to `:exit` tuples. The value emitted for that task is `{:exit, {input, reason}}`, where `input` is the collection element that caused an exit during processing. Defaults to `false`. ### Example - Task.async_stream/5 (function) Let's build a stream and then enumerate it: stream = Task.async_stream(collection, Mod, :expensive_fun, []) Enum.to_list(stream) The concurrency can be increased or decreased using the `:max_concurrency` option. For example, if the tasks are IO heavy, the value can be increased: max_concurrency = System.schedulers_online() * 2 stream = Task.async_stream(collection, Mod, :expensive_fun, [], max_concurrency: max_concurrency) Enum.to_list(stream) If you do not care about the results of the computation, you can run the stream with `Stream.run/1`. Also set `ordered: false`, as you don't care about the order of the results either: stream = Task.async_stream(collection, Mod, :expensive_fun, [], ordered: false) Stream.run(stream) ### First async tasks to complete - Task.async_stream/5 (function) You can also use `async_stream/3` to execute M tasks and find the N tasks to complete. For example: [ &heavy_call_1/0, &heavy_call_2/0, &heavy_call_3/0 ] |> Task.async_stream(fn fun -> fun.() end, ordered: false, max_concurrency: 3) |> Stream.filter(&match?({:ok, _}, &1)) |> Enum.take(2) In the example above, we are executing three tasks and waiting for the first 2 to complete. We use `Stream.filter/2` to restrict ourselves only to successfully completed tasks, and then use `Enum.take/2` to retrieve N items. Note it is important to set both `ordered: false` and `max_concurrency: M`, where M is the number of tasks, to make sure all calls execute concurrently. ### Attention: unbound async + take - Task.async_stream/5 (function) If you want to potentially process a high number of items and keep only part of the results, you may end-up processing more items than desired. Let's see an example: 1..100 |> Task.async_stream(fn i -> Process.sleep(100) IO.puts(to_string(i)) end) |> Enum.take(10) Running the example above in a machine with 8 cores will process 16 items, even though you want only 10 elements, since `async_stream/3` process items concurrently. That's because it will process 8 elements at once. Then all 8 elements complete at roughly the same time, causing 8 elements to be kicked off for processing. Out of these extra 8, only 2 will be used, and the rest will be terminated. Depending on the problem, you can filter or limit the number of elements upfront: 1..100 |> Stream.take(10) |> Task.async_stream(fn i -> Process.sleep(100) IO.puts(to_string(i)) end) |> Enum.to_list() In other cases, you likely want to tweak `:max_concurrency` to limit how many elements may be over processed at the cost of reducing concurrency. You can also set the number of elements to take to be a multiple of `:max_concurrency`. For instance, setting `max_concurrency: 5` in the example above. ### Task.await/2 (function) Awaits a task reply and returns it. In case the task process dies, the caller process will exit with the same reason as the task. A timeout, in milliseconds or `:infinity`, can be given with a default value of `5000`. If the timeout is exceeded, then the caller process will exit. If the task process is linked to the caller process which is the case when a task is started with `async`, then the task process will also exit. If the task process is trapping exits or not linked to the caller process, then it will continue to run. This function assumes the task's monitor is still active or the monitor's `:DOWN` message is in the message queue. If it has been demonitored, or the message already received, this function will wait for the duration of the timeout awaiting the message. This function can only be called once for any given task. If you want to be able to check multiple times if a long-running task has finished its computation, use `yield/2` instead. ### Examples - Task.await/2 (function) iex> task = Task.async(fn -> 1 + 1 end) iex> Task.await(task) 2 ### Compatibility with OTP behaviours - Task.await/2 (function) It is not recommended to `await` a long-running task inside an OTP behaviour such as `GenServer`. Instead, you should match on the message coming from a task inside your `c:GenServer.handle_info/2` callback. A GenServer will receive two messages on `handle_info/2`: * `{ref, result}` - the reply message where `ref` is the monitor reference returned by the `task.ref` and `result` is the task result * `{:DOWN, ref, :process, pid, reason}` - since all tasks are also monitored, you will also receive the `:DOWN` message delivered by `Process.monitor/1`. If you receive the `:DOWN` message without a a reply, it means the task crashed Another consideration to have in mind is that tasks started by `Task.async/1` are always linked to their callers and you may not want the GenServer to crash if the task crashes. Therefore, it is preferable to instead use `Task.Supervisor.async_nolink/3` inside OTP behaviours. For completeness, here is an example of a GenServer that start tasks and handles their results: defmodule GenServerTaskExample do use GenServer def start_link(opts) do GenServer.start_link(__MODULE__, :ok, opts) end def init(_opts) do # We will keep all running tasks in a map {:ok, %{tasks: %{}}} end # Imagine we invoke a task from the GenServer to access a URL... def handle_call(:some_message, _from, state) do url = ... task = Task.Supervisor.async_nolink(MyApp.TaskSupervisor, fn -> fetch_url(url) end) # After we start the task, we store its reference and the url it is fetching state = put_in(state.tasks[task.ref], url) {:reply, :ok, state} end # If the task succeeds... def handle_info({ref, result}, state) do # The task succeed so we can demonitor its reference Process.demonitor(ref, [:flush]) {url, state} = pop_in(state.tasks[ref]) IO.puts("Got #{inspect(result)} for URL #{inspect url}") {:noreply, state} end # If the task fails... def handle_info({:DOWN, ref, _, _, reason}, state) do {url, state} = pop_in(state.tasks[ref]) IO.puts("URL #{inspect url} failed with reason #{inspect(reason)}") {:noreply, state} end end With the server defined, you will want to start the task supervisor above and the GenServer in your supervision tree: children = [ {Task.Supervisor, name: MyApp.TaskSupervisor}, {GenServerTaskExample, name: MyApp.GenServerTaskExample} ] Supervisor.start_link(children, strategy: :one_for_one) ### Task.await_many/2 (function) Awaits replies from multiple tasks and returns them. This function receives a list of tasks and waits for their replies in the given time interval. It returns a list of the results, in the same order as the tasks supplied in the `tasks` input argument. If any of the task processes dies, the caller process will exit with the same reason as that task. A timeout, in milliseconds or `:infinity`, can be given with a default value of `5000`. If the timeout is exceeded, then the caller process will exit. Any task processes that are linked to the caller process (which is the case when a task is started with `async`) will also exit. Any task processes that are trapping exits or not linked to the caller process will continue to run. This function assumes the tasks' monitors are still active or the monitor's `:DOWN` message is in the message queue. If any tasks have been demonitored, or the message already received, this function will wait for the duration of the timeout. This function can only be called once for any given task. If you want to be able to check multiple times if a long-running task has finished its computation, use `yield_many/2` instead. ### Compatibility with OTP behaviours - Task.await_many/2 (function) It is not recommended to `await` long-running tasks inside an OTP behaviour such as `GenServer`. See `await/2` for more information. ### Examples - Task.await_many/2 (function) iex> tasks = [ ...> Task.async(fn -> 1 + 1 end), ...> Task.async(fn -> 2 + 3 end) ...> ] iex> Task.await_many(tasks) [2, 5] ### Task.child_spec/1 (function) Returns a specification to start a task under a supervisor. `arg` is passed as the argument to `Task.start_link/1` in the `:start` field of the spec. For more information, see the `Supervisor` module, the `Supervisor.child_spec/2` function and the `t:Supervisor.child_spec/0` type. ### Task.completed/1 (function) Starts a task that immediately completes with the given `result`. Unlike `async/1`, this task does not spawn a linked process. It can be awaited or yielded like any other task. ### Usage - Task.completed/1 (function) In some cases, it is useful to create a "completed" task that represents a task that has already run and generated a result. For example, when processing data you may be able to determine that certain inputs are invalid before dispatching them for further processing: def process(data) do tasks = for entry <- data do if invalid_input?(entry) do Task.completed({:error, :invalid_input}) else Task.async(fn -> further_process(entry) end) end end Task.await_many(tasks) end In many cases, `Task.completed/1` may be avoided in favor of returning the result directly. You should generally only require this variant when working with mixed asynchrony, when a group of inputs will be handled partially synchronously and partially asynchronously. ### Task.ignore/1 (function) Ignores an existing task. This means the task will continue running, but it will be unlinked and you can no longer yield, await or shut it down. Returns `{:ok, reply}` if the reply is received before ignoring the task, `{:exit, reason}` if the task died before ignoring it, otherwise `nil`. Important: avoid using [`Task.async/1,3`](`async/1`) and then immediately ignoring the task. If you want to start tasks you don't care about their results, use `Task.Supervisor.start_child/2` instead. ### Task.shutdown/2 (function) Unlinks and shuts down the task, and then checks for a reply. Returns `{:ok, reply}` if the reply is received while shutting down the task, `{:exit, reason}` if the task died, otherwise `nil`. Once shut down, you can no longer await or yield it. The second argument is either a timeout or `:brutal_kill`. In case of a timeout, a `:shutdown` exit signal is sent to the task process and if it does not exit within the timeout, it is killed. With `:brutal_kill` the task is killed straight away. In case the task terminates abnormally (possibly killed by another process), this function will exit with the same reason. It is not required to call this function when terminating the caller, unless exiting with reason `:normal` or if the task is trapping exits. If the caller is exiting with a reason other than `:normal` and the task is not trapping exits, the caller's exit signal will stop the task. The caller can exit with reason `:shutdown` to shut down all of its linked processes, including tasks, that are not trapping exits without generating any log messages. If there is no process linked to the task, such as tasks started by `Task.completed/1`, we check for a response or error accordingly, but without shutting a process down. If a task's monitor has already been demonitored or received and there is not a response waiting in the message queue this function will return `{:exit, :noproc}` as the result or exit reason can not be determined. ### Task.start/1 (function) Starts a task. `fun` must be a zero-arity anonymous function. This should only used when the task is used for side-effects (like I/O) and you have no interest on its results nor if it completes successfully. If the current node is shutdown, the node will terminate even if the task was not completed. For this reason, we recommend to use `Task.Supervisor.start_child/2` instead, which allows you to control the shutdown time via the `:shutdown` option. ### Task.start/3 (function) Starts a task. This should only used when the task is used for side-effects (like I/O) and you have no interest on its results nor if it completes successfully. If the current node is shutdown, the node will terminate even if the task was not completed. For this reason, we recommend to use `Task.Supervisor.start_child/2` instead, which allows you to control the shutdown time via the `:shutdown` option. ### Task.start_link/1 (function) Starts a task as part of a supervision tree with the given `fun`. `fun` must be a zero-arity anonymous function. This is used to start a statically supervised task under a supervision tree. ### Task.start_link/3 (function) Starts a task as part of a supervision tree with the given `module`, `function`, and `args`. This is used to start a statically supervised task under a supervision tree. ### Task.yield/2 (function) Temporarily blocks the caller process waiting for a task reply. Returns `{:ok, reply}` if the reply is received, `nil` if no reply has arrived, or `{:exit, reason}` if the task has already exited. Keep in mind that normally a task failure also causes the process owning the task to exit. Therefore this function can return `{:exit, reason}` if at least one of the conditions below apply: * the task process exited with the reason `:normal` * the task isn't linked to the caller (the task was started with `Task.Supervisor.async_nolink/2` or `Task.Supervisor.async_nolink/4`) * the caller is trapping exits A timeout, in milliseconds or `:infinity`, can be given with a default value of `5000`. If the time runs out before a message from the task is received, this function will return `nil` and the monitor will remain active. Therefore `yield/2` can be called multiple times on the same task. This function assumes the task's monitor is still active or the monitor's `:DOWN` message is in the message queue. If it has been demonitored or the message already received, this function will wait for the duration of the timeout awaiting the message. If you intend to shut the task down if it has not responded within `timeout` milliseconds, you should chain this together with `shutdown/1`, like so: case Task.yield(task, timeout) || Task.shutdown(task) do {:ok, result} -> result nil -> Logger.warning("Failed to get a result in #{timeout}ms") nil end If you intend to check on the task but leave it running after the timeout, you can chain this together with `ignore/1`, like so: case Task.yield(task, timeout) || Task.ignore(task) do {:ok, result} -> result nil -> Logger.warning("Failed to get a result in #{timeout}ms") nil end That ensures that if the task completes after the `timeout` but before `shutdown/1` has been called, you will still get the result, since `shutdown/1` is designed to handle this case and return the result. ### Task.yield_many/2 (function) Yields to multiple tasks in the given time interval. This function receives a list of tasks and waits for their replies in the given time interval. It returns a list of two-element tuples, with the task as the first element and the yielded result as the second. The tasks in the returned list will be in the same order as the tasks supplied in the `tasks` input argument. Similarly to `yield/2`, each task's result will be * `{:ok, term}` if the task has successfully reported its result back in the given time interval * `{:exit, reason}` if the task has died * `nil` if the task keeps running, either because a limit has been reached or past the timeout Check `yield/2` for more information. ### Example - Task.yield_many/2 (function) `Task.yield_many/2` allows developers to spawn multiple tasks and retrieve the results received in a given time frame. If we combine it with `Task.shutdown/2` (or `Task.ignore/1`), it allows us to gather those results and cancel (or ignore) the tasks that have not replied in time. Let's see an example. tasks = for i <- 1..10 do Task.async(fn -> Process.sleep(i * 1000) i end) end tasks_with_results = Task.yield_many(tasks, timeout: 5000) results = Enum.map(tasks_with_results, fn {task, res} -> # Shut down the tasks that did not reply nor exit res || Task.shutdown(task, :brutal_kill) end) # Here we are matching only on {:ok, value} and # ignoring {:exit, _} (crashed tasks) and `nil` (no replies) for {:ok, value} <- results do IO.inspect(value) end In the example above, we create tasks that sleep from 1 up to 10 seconds and return the number of seconds they slept for. If you execute the code all at once, you should see 1 up to 5 printed, as those were the tasks that have replied in the given time. All other tasks will have been shut down using the `Task.shutdown/2` call. As a convenience, you can achieve a similar behavior to above by specifying the `:on_timeout` option to be `:kill_task` (or `:ignore`). See `Task.await_many/2` if you would rather exit the caller process on timeout. ### Options - Task.yield_many/2 (function) The second argument is either a timeout or options, which defaults to this: * `:limit` - the maximum amount of tasks to wait for. If the limit is reached before the timeout, this function returns immediately without triggering the `:on_timeout` behaviour * `:timeout` - the maximum amount of time (in milliseconds or `:infinity`) each task is allowed to execute for. Defaults to `5000`. * `:on_timeout` - what to do when a task times out. The possible values are: * `:nothing` - do nothing (default). The tasks can still be awaited on, yielded on, ignored, or shut down later. * `:ignore` - the results of the task will be ignored. * `:kill_task` - the task that timed out is killed. ### Task.async_stream_option/0 (type) Options given to `async_stream` functions. ### Task.t/0 (type) The Task type. See [`%Task{}`](`__struct__/0`) for information about each field of the structure. ### Task.Supervisor (module) A task supervisor. This module defines a supervisor which can be used to dynamically supervise tasks. A task supervisor is started with no children, often under a supervisor and a name: children = [ {Task.Supervisor, name: MyApp.TaskSupervisor} ] Supervisor.start_link(children, strategy: :one_for_one) The options given in the child specification are documented in `start_link/1`. Once started, you can start tasks directly under the supervisor, for example: task = Task.Supervisor.async(MyApp.TaskSupervisor, fn -> :do_some_work end) See the `Task` module for more examples. ### Scalability and partitioning - Task.Supervisor (module) The `Task.Supervisor` is a single process responsible for starting other processes. In some applications, the `Task.Supervisor` may become a bottleneck. To address this, you can start multiple instances of the `Task.Supervisor` and then pick a random instance to start the task on. Instead of: children = [ {Task.Supervisor, name: MyApp.TaskSupervisor} ] and: Task.Supervisor.async(MyApp.TaskSupervisor, fn -> :do_some_work end) You can do this: children = [ {PartitionSupervisor, child_spec: Task.Supervisor, name: MyApp.TaskSupervisors} ] and then: Task.Supervisor.async( {:via, PartitionSupervisor, {MyApp.TaskSupervisors, self()}}, fn -> :do_some_work end ) In the code above, we start a partition supervisor that will by default start a dynamic supervisor for each core in your machine. Then, instead of calling the `Task.Supervisor` by name, you call it through the partition supervisor using the `{:via, PartitionSupervisor, {name, key}}` format, where `name` is the name of the partition supervisor and `key` is the routing key. We picked `self()` as the routing key, which means each process will be assigned one of the existing task supervisors. Read the `PartitionSupervisor` docs for more information. ### Name registration - Task.Supervisor (module) A `Task.Supervisor` is bound to the same name registration rules as a `GenServer`. Read more about them in the `GenServer` docs. ### Task.Supervisor.async/3 (function) Starts a task that can be awaited on. The `supervisor` must be a reference as defined in `Supervisor`. The task will still be linked to the caller, see `Task.async/1` for more information and `async_nolink/3` for a non-linked variant. Raises an error if `supervisor` has reached the maximum number of children. ### Options - Task.Supervisor.async/3 (function) * `:shutdown` - `:brutal_kill` if the tasks must be killed directly on shutdown or an integer indicating the timeout value, defaults to 5000 milliseconds. The tasks must trap exits for the timeout to have an effect. ### Task.Supervisor.async/5 (function) Starts a task that can be awaited on. The `supervisor` must be a reference as defined in `Supervisor`. The task will still be linked to the caller, see `Task.async/1` for more information and `async_nolink/3` for a non-linked variant. Raises an error if `supervisor` has reached the maximum number of children. ### Options - Task.Supervisor.async/5 (function) * `:shutdown` - `:brutal_kill` if the tasks must be killed directly on shutdown or an integer indicating the timeout value, defaults to 5000 milliseconds. The tasks must trap exits for the timeout to have an effect. ### Task.Supervisor.async_nolink/3 (function) Starts a task that can be awaited on. The `supervisor` must be a reference as defined in `Supervisor`. The task won't be linked to the caller, see `Task.async/1` for more information. Raises an error if `supervisor` has reached the maximum number of children. Note this function requires the task supervisor to have `:temporary` as the `:restart` option (the default), as `async_nolink/3` keeps a direct reference to the task which is lost if the task is restarted. ### Options - Task.Supervisor.async_nolink/3 (function) * `:shutdown` - `:brutal_kill` if the tasks must be killed directly on shutdown or an integer indicating the timeout value, defaults to 5000 milliseconds. The tasks must trap exits for the timeout to have an effect. ### Compatibility with OTP behaviours - Task.Supervisor.async_nolink/3 (function) If you create a task using `async_nolink` inside an OTP behaviour like `GenServer`, you should match on the message coming from the task inside your `c:GenServer.handle_info/2` callback. The reply sent by the task will be in the format `{ref, result}`, where `ref` is the monitor reference held by the task struct and `result` is the return value of the task function. Keep in mind that, regardless of how the task created with `async_nolink` terminates, the caller's process will always receive a `:DOWN` message with the same `ref` value that is held by the task struct. If the task terminates normally, the reason in the `:DOWN` message will be `:normal`. ### Examples - Task.Supervisor.async_nolink/3 (function) Typically, you use `async_nolink/3` when there is a reasonable expectation that the task may fail, and you don't want it to take down the caller. Let's see an example where a `GenServer` is meant to run a single task and track its status: defmodule MyApp.Server do use GenServer # ... def start_task do GenServer.call(__MODULE__, :start_task) end # In this case the task is already running, so we just return :ok. def handle_call(:start_task, _from, %{ref: ref} = state) when is_reference(ref) do {:reply, :ok, state} end # The task is not running yet, so let's start it. def handle_call(:start_task, _from, %{ref: nil} = state) do task = Task.Supervisor.async_nolink(MyApp.TaskSupervisor, fn -> ... end) # We return :ok and the server will continue running {:reply, :ok, %{state | ref: task.ref}} end # The task completed successfully def handle_info({ref, answer}, %{ref: ref} = state) do # We don't care about the DOWN message now, so let's demonitor and flush it Process.demonitor(ref, [:flush]) # Do something with the result and then return {:noreply, %{state | ref: nil}} end # The task failed def handle_info({:DOWN, ref, :process, _pid, _reason}, %{ref: ref} = state) do # Log and possibly restart the task... {:noreply, %{state | ref: nil}} end end ### Task.Supervisor.async_nolink/5 (function) Starts a task that can be awaited on. The `supervisor` must be a reference as defined in `Supervisor`. The task won't be linked to the caller, see `Task.async/1` for more information. Raises an error if `supervisor` has reached the maximum number of children. Note this function requires the task supervisor to have `:temporary` as the `:restart` option (the default), as `async_nolink/5` keeps a direct reference to the task which is lost if the task is restarted. ### Task.Supervisor.async_stream/4 (function) Returns a stream that runs the given function `fun` concurrently on each element in `enumerable`. Each element in `enumerable` is passed as argument to the given function `fun` and processed by its own task. The tasks will be spawned under the given `supervisor` and linked to the caller process, similarly to `async/3`. See `async_stream/6` for discussion, options, and examples. ### Task.Supervisor.async_stream/6 (function) Returns a stream where the given function (`module` and `function`) is mapped concurrently on each element in `enumerable`. Each element will be prepended to the given `args` and processed by its own task. The tasks will be spawned under the given `supervisor` and linked to the caller process, similarly to `async/5`. When streamed, each task will emit `{:ok, value}` upon successful completion or `{:exit, reason}` if the caller is trapping exits. The order of results depends on the value of the `:ordered` option. The level of concurrency and the time tasks are allowed to run can be controlled via options (see the "Options" section below). If you find yourself trapping exits to handle exits inside the async stream, consider using `async_stream_nolink/6` to start tasks that are not linked to the calling process. ### Options - Task.Supervisor.async_stream/6 (function) * `:max_concurrency` - sets the maximum number of tasks to run at the same time. Defaults to `System.schedulers_online/0`. * `:ordered` - whether the results should be returned in the same order as the input stream. This option is useful when you have large streams and don't want to buffer results before they are delivered. This is also useful when you're using the tasks for side effects. Defaults to `true`. * `:timeout` - the maximum amount of time to wait (in milliseconds) without receiving a task reply (across all running tasks). Defaults to `5000`. * `:on_timeout` - what do to when a task times out. The possible values are: * `:exit` (default) - the process that spawned the tasks exits. * `:kill_task` - the task that timed out is killed. The value emitted for that task is `{:exit, :timeout}`. * `:zip_input_on_exit` - (since v1.14.0) adds the original input to `:exit` tuples. The value emitted for that task is `{:exit, {input, reason}}`, where `input` is the collection element that caused an exited during processing. Defaults to `false`. * `:shutdown` - `:brutal_kill` if the tasks must be killed directly on shutdown or an integer indicating the timeout value. Defaults to `5000` milliseconds. The tasks must trap exits for the timeout to have an effect. ### Examples - Task.Supervisor.async_stream/6 (function) Let's build a stream and then enumerate it: stream = Task.Supervisor.async_stream(MySupervisor, collection, Mod, :expensive_fun, []) Enum.to_list(stream) ### Task.Supervisor.async_stream_nolink/4 (function) Returns a stream that runs the given `function` concurrently on each element in `enumerable`. Each element in `enumerable` is passed as argument to the given function `fun` and processed by its own task. The tasks will be spawned under the given `supervisor` and will not be linked to the caller process, similarly to `async_nolink/3`. See `async_stream/6` for discussion and examples. ### Error handling and cleanup - Task.Supervisor.async_stream_nolink/4 (function) Even if tasks are not linked to the caller, there is no risk of leaving dangling tasks running after the stream halts. Consider the following example: Task.Supervisor.async_stream_nolink(MySupervisor, collection, fun, on_timeout: :kill_task, ordered: false) |> Enum.each(fn {:ok, _} -> :ok {:exit, reason} -> raise "Task exited: #{Exception.format_exit(reason)}" end) If one task raises or times out: 1. the second clause gets called 2. an exception is raised 3. the stream halts 4. all ongoing tasks will be shut down Here is another example: Task.Supervisor.async_stream_nolink(MySupervisor, collection, fun, on_timeout: :kill_task, ordered: false) |> Stream.filter(&match?({:ok, _}, &1)) |> Enum.take(3) This will return the three first tasks to succeed, ignoring timeouts and errors, and shut down every ongoing task. Just running the stream with `Stream.run/1` on the other hand would ignore errors and process the whole stream. ### Task.Supervisor.async_stream_nolink/6 (function) Returns a stream where the given function (`module` and `function`) is mapped concurrently on each element in `enumerable`. Each element in `enumerable` will be prepended to the given `args` and processed by its own task. The tasks will be spawned under the given `supervisor` and will not be linked to the caller process, similarly to `async_nolink/5`. See `async_stream/6` for discussion, options, and examples. ### Task.Supervisor.children/1 (function) Returns all children PIDs except those that are restarting. Note that calling this function when supervising a large number of children under low memory conditions can cause an out of memory exception. ### Task.Supervisor.start_child/3 (function) Starts a task as a child of the given `supervisor`. Task.Supervisor.start_child(MyTaskSupervisor, fn -> IO.puts("I am running in a task") end) Note that the spawned process is not linked to the caller, but only to the supervisor. This command is useful in case the task needs to perform side-effects (like I/O) and you have no interest in its results nor if it completes successfully. ### Options - Task.Supervisor.start_child/3 (function) * `:restart` - the restart strategy, may be `:temporary` (the default), `:transient` or `:permanent`. `:temporary` means the task is never restarted, `:transient` means it is restarted if the exit is not `:normal`, `:shutdown` or `{:shutdown, reason}`. A `:permanent` restart strategy means it is always restarted. * `:shutdown` - `:brutal_kill` if the task must be killed directly on shutdown or an integer indicating the timeout value, defaults to 5000 milliseconds. The task must trap exits for the timeout to have an effect. ### Task.Supervisor.start_child/5 (function) Starts a task as a child of the given `supervisor`. Similar to `start_child/3` except the task is specified by the given `module`, `fun` and `args`. ### Task.Supervisor.start_link/1 (function) Starts a new supervisor. ### Examples - Task.Supervisor.start_link/1 (function) A task supervisor is typically started under a supervision tree using the tuple format: {Task.Supervisor, name: MyApp.TaskSupervisor} You can also start it by calling `start_link/1` directly: Task.Supervisor.start_link(name: MyApp.TaskSupervisor) But this is recommended only for scripting and should be avoided in production code. Generally speaking, processes should always be started inside supervision trees. ### Options - Task.Supervisor.start_link/1 (function) * `:name` - used to register a supervisor name, the supported values are described under the `Name Registration` section in the `GenServer` module docs; * `:max_restarts`, `:max_seconds`, and `:max_children` - as specified in `DynamicSupervisor`; This function could also receive `:restart` and `:shutdown` as options but those two options have been deprecated and it is now preferred to give them directly to `start_child`. ### Task.Supervisor.terminate_child/2 (function) Terminates the child with the given `pid`. ### Task.Supervisor.async_stream_option/0 (type) Options given to `async_stream` and `async_stream_nolink` functions. ### Task.Supervisor.option/0 (type) Option values used by `start_link` ### Collectable (protocol) A protocol to traverse data structures. The `Enum.into/2` function uses this protocol to insert an enumerable into a collection: iex> Enum.into([a: 1, b: 2], %{}) %{a: 1, b: 2} ### Why Collectable? - Collectable (protocol) The `Enumerable` protocol is useful to take values out of a collection. In order to support a wide range of values, the functions provided by the `Enumerable` protocol do not keep shape. For example, passing a map to `Enum.map/2` always returns a list. This design is intentional. `Enumerable` was designed to support infinite collections, resources and other structures with fixed shape. For example, it doesn't make sense to insert values into a `Range`, as it has a fixed shape where only the range limits and step are stored. The `Collectable` module was designed to fill the gap left by the `Enumerable` protocol. `Collectable.into/1` can be seen as the opposite of `Enumerable.reduce/3`. If the functions in `Enumerable` are about taking values out, then `Collectable.into/1` is about collecting those values into a structure. ### Examples - Collectable (protocol) To show how to manually use the `Collectable` protocol, let's play with a simplified implementation for `MapSet`. iex> {initial_acc, collector_fun} = Collectable.into(MapSet.new()) iex> updated_acc = Enum.reduce([1, 2, 3], initial_acc, fn elem, acc -> ...> collector_fun.(acc, {:cont, elem}) ...> end) iex> collector_fun.(updated_acc, :done) MapSet.new([1, 2, 3]) To show how the protocol can be implemented, we can again look at the simplified implementation for `MapSet`. In this implementation "collecting" elements simply means inserting them in the set through `MapSet.put/2`. defimpl Collectable, for: MapSet do def into(map_set) do collector_fun = fn map_set_acc, {:cont, elem} -> MapSet.put(map_set_acc, elem) map_set_acc, :done -> map_set_acc _map_set_acc, :halt -> :ok end initial_acc = map_set {initial_acc, collector_fun} end end So now we can call `Enum.into/2`: iex> Enum.into([1, 2, 3], MapSet.new()) MapSet.new([1, 2, 3]) ### Collectable.into/1 (function) Returns an initial accumulator and a "collector" function. Receives a `collectable` which can be used as the initial accumulator that will be passed to the function. The collector function receives a term and a command and injects the term into the collectable accumulator on every `{:cont, term}` command. `:done` is passed as a command when no further values will be injected. This is useful when there's a need to close resources or normalizing values. A collectable must be returned when the command is `:done`. If injection is suddenly interrupted, `:halt` is passed and the function can return any value as it won't be used. For examples on how to use the `Collectable` protocol and `into/1` see the module documentation. ### Collectable.command/0 (type) ### Collectable.t/0 (type) All the types that implement this protocol. ### Enumerable (protocol) Enumerable protocol used by `Enum` and `Stream` modules. When you invoke a function in the `Enum` module, the first argument is usually a collection that must implement this protocol. For example, the expression `Enum.map([1, 2, 3], &(&1 * 2))` invokes `Enumerable.reduce/3` to perform the reducing operation that builds a mapped list by calling the mapping function `&(&1 * 2)` on every element in the collection and consuming the element with an accumulated list. Internally, `Enum.map/2` is implemented as follows: def map(enumerable, fun) do reducer = fn x, acc -> {:cont, [fun.(x) | acc]} end Enumerable.reduce(enumerable, {:cont, []}, reducer) |> elem(1) |> :lists.reverse() end Note that the user-supplied function is wrapped into a `t:reducer/0` function. The `t:reducer/0` function must return a tagged tuple after each step, as described in the `t:acc/0` type. At the end, `Enumerable.reduce/3` returns `t:result/0`. This protocol uses tagged tuples to exchange information between the reducer function and the data type that implements the protocol. This allows enumeration of resources, such as files, to be done efficiently while also guaranteeing the resource will be closed at the end of the enumeration. This protocol also allows suspension of the enumeration, which is useful when interleaving between many enumerables is required (as in the `zip/1` and `zip/2` functions). This protocol requires four functions to be implemented, `reduce/3`, `count/1`, `member?/2`, and `slice/1`. The core of the protocol is the `reduce/3` function. All other functions exist as optimizations paths for data structures that can implement certain properties in better than linear time. ### Enumerable.count/1 (function) Retrieves the number of elements in the `enumerable`. It should return `{:ok, count}` if you can count the number of elements in `enumerable` in a faster way than fully traversing it. Otherwise it should return `{:error, __MODULE__}` and a default algorithm built on top of `reduce/3` that runs in linear time will be used. ### Enumerable.member?/2 (function) Checks if an `element` exists within the `enumerable`. It should return `{:ok, boolean}` if you can check the membership of a given element in `enumerable` with `===/2` without traversing the whole of it. Otherwise it should return `{:error, __MODULE__}` and a default algorithm built on top of `reduce/3` that runs in linear time will be used. When called outside guards, the [`in`](`in/2`) and [`not in`](`in/2`) operators work by using this function. ### Enumerable.reduce/3 (function) Reduces the `enumerable` into an element. Most of the operations in `Enum` are implemented in terms of reduce. This function should apply the given `t:reducer/0` function to each element in the `enumerable` and proceed as expected by the returned accumulator. See the documentation of the types `t:result/0` and `t:acc/0` for more information. ### Examples - Enumerable.reduce/3 (function) As an example, here is the implementation of `reduce` for lists: def reduce(_list, {:halt, acc}, _fun), do: {:halted, acc} def reduce(list, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(list, &1, fun)} def reduce([], {:cont, acc}, _fun), do: {:done, acc} def reduce([head | tail], {:cont, acc}, fun), do: reduce(tail, fun.(head, acc), fun) ### Enumerable.slice/1 (function) Returns a function that slices the data structure contiguously. It should return either: * `{:ok, size, slicing_fun}` - if the `enumerable` has a known bound and can access a position in the `enumerable` without traversing all previous elements. The `slicing_fun` will receive a `start` position, the `amount` of elements to fetch, and a `step`. * `{:ok, size, to_list_fun}` - if the `enumerable` has a known bound and can access a position in the `enumerable` by first converting it to a list via `to_list_fun`. * `{:error, __MODULE__}` - the enumerable cannot be sliced efficiently and a default algorithm built on top of `reduce/3` that runs in linear time will be used. ### Differences to `count/1` - Enumerable.slice/1 (function) The `size` value returned by this function is used for boundary checks, therefore it is extremely important that this function only returns `:ok` if retrieving the `size` of the `enumerable` is cheap, fast, and takes constant time. Otherwise the simplest of operations, such as `Enum.at(enumerable, 0)`, will become too expensive. On the other hand, the `count/1` function in this protocol should be implemented whenever you can count the number of elements in the collection without traversing it. ### Enumerable.acc/0 (type) The accumulator value for each step. It must be a tagged tuple with one of the following "tags": * `:cont` - the enumeration should continue * `:halt` - the enumeration should halt immediately * `:suspend` - the enumeration should be suspended immediately Depending on the accumulator value, the result returned by `Enumerable.reduce/3` will change. Please check the `t:result/0` type documentation for more information. In case a `t:reducer/0` function returns a `:suspend` accumulator, it must be explicitly handled by the caller and never leak. ### Enumerable.continuation/0 (type) A partially applied reduce function. The continuation is the closure returned as a result when the enumeration is suspended. When invoked, it expects a new accumulator and it returns the result. A continuation can be trivially implemented as long as the reduce function is defined in a tail recursive fashion. If the function is tail recursive, all the state is passed as arguments, so the continuation is the reducing function partially applied. ### Enumerable.reducer/0 (type) The reducer function. Should be called with the `enumerable` element and the accumulator contents. Returns the accumulator for the next enumeration step. ### Enumerable.result/0 (type) The result of the reduce operation. It may be *done* when the enumeration is finished by reaching its end, or *halted*/*suspended* when the enumeration was halted or suspended by the tagged accumulator. In case the tagged `:halt` accumulator is given, the `:halted` tuple with the accumulator must be returned. Functions like `Enum.take_while/2` use `:halt` underneath and can be used to test halting enumerables. In case the tagged `:suspend` accumulator is given, the caller must return the `:suspended` tuple with the accumulator and a continuation. The caller is then responsible of managing the continuation and the caller must always call the continuation, eventually halting or continuing until the end. `Enum.zip/2` uses suspension, so it can be used to test whether your implementation handles suspension correctly. You can also use `Stream.zip/2` with `Enum.take_while/2` to test the combination of `:suspend` with `:halt`. ### Enumerable.slicing_fun/0 (type) A slicing function that receives the initial position, the number of elements in the slice, and the step. The `start` position is a number `>= 0` and guaranteed to exist in the `enumerable`. The length is a number `>= 1` in a way that `start + length * step <= count`, where `count` is the maximum amount of elements in the enumerable. The function should return a non empty list where the amount of elements is equal to `length`. ### Enumerable.t/0 (type) All the types that implement this protocol. ### Enumerable.t/1 (type) An enumerable of elements of type `element`. This type is equivalent to `t:t/0` but is especially useful for documentation. For example, imagine you define a function that expects an enumerable of integers and returns an enumerable of strings: @spec integers_to_strings(Enumerable.t(integer())) :: Enumerable.t(String.t()) def integers_to_strings(integers) do Stream.map(integers, &Integer.to_string/1) end ### Enumerable.to_list_fun/0 (type) Receives an enumerable and returns a list. ### Inspect (protocol) The `Inspect` protocol converts an Elixir data structure into an algebra document. This is typically done when you want to customize how your own structs are inspected in logs and the terminal. This documentation refers to implementing the `Inspect` protocol for your own data structures. To learn more about using inspect, see `Kernel.inspect/2` and `IO.inspect/2`. ### Inspect representation - Inspect (protocol) There are typically three choices of inspect representation. In order to understand them, let's imagine we have the following `User` struct: defmodule User do defstruct [:id, :name, :address] end Our choices are: 1. Print the struct using Elixir's struct syntax, for example: `%User{address: "Earth", id: 13, name: "Jane"}`. This is the default representation and best choice if all struct fields are public. 2. Print using the `#User<...>` notation, for example: `#User `. This notation does not emit valid Elixir code and is typically used when the struct has private fields (for example, you may want to hide the field `:address` to redact person identifiable information). 3. Print the struct using the expression syntax, for example: `User.new(13, "Jane", "Earth")`. This assumes there is a `User.new/3` function. This option is mostly used as an alternative to option 2 for representing custom data structures, such as `MapSet`, `Date.Range`, and others. You can implement the Inspect protocol for your own structs while adhering to the conventions above. Option 1 is the default representation and you can quickly achieve option 2 by deriving the `Inspect` protocol. For option 3, you need your custom implementation. ### Deriving - Inspect (protocol) The `Inspect` protocol can be derived to customize the order of fields (the default is alphabetical) and hide certain fields from structs, so they don't show up in logs, inspects and similar. The latter is especially useful for fields containing private information. The supported options are: * `:only` - only include the given fields when inspecting. * `:except` - remove the given fields when inspecting. * `:optional` - (since v1.14.0) do not include a field if it matches its default value. This can be used to simplify the struct representation at the cost of hiding information. Whenever `:only` or `:except` are used to restrict fields, the struct will be printed using the `#User<...>` notation, as the struct can no longer be copy and pasted as valid Elixir code. Let's see an example: defmodule User do @derive {Inspect, only: [:id, :name]} defstruct [:id, :name, :address] end inspect(%User{id: 1, name: "Jane", address: "Earth"}) #=> #User If you use only the `:optional` option, the struct will still be printed as `%User{...}`. ### Custom implementation - Inspect (protocol) You can also define your custom protocol implementation by defining the `inspect/2` function. The function receives the entity to be inspected followed by the inspecting options, represented by the struct `Inspect.Opts`. Building of the algebra document is done with `Inspect.Algebra`. Many times, inspecting a structure can be implemented in function of existing entities. For example, here is `MapSet`'s `inspect/2` implementation: defimpl Inspect, for: MapSet do import Inspect.Algebra def inspect(map_set, opts) do concat(["MapSet.new(", Inspect.List.inspect(MapSet.to_list(map_set), opts), ")"]) end end The [`concat/1`](`Inspect.Algebra.concat/1`) function comes from `Inspect.Algebra` and it concatenates algebra documents together. In the example above it is concatenating the string `"MapSet.new("`, the document returned by `Inspect.Algebra.to_doc/2`, and the final string `")"`. Therefore, the MapSet with the numbers 1, 2, and 3 will be printed as: iex> MapSet.new([1, 2, 3], fn x -> x * 2 end) MapSet.new([2, 4, 6]) In other words, `MapSet`'s inspect representation returns an expression that, when evaluated, builds the `MapSet` itself. ### Error handling - Inspect (protocol) In case there is an error while your structure is being inspected, Elixir will raise an `ArgumentError` error and will automatically fall back to a raw representation for printing the structure. Furthermore, you must be careful when debugging your own Inspect implementation, as calls to `IO.inspect/2` or `dbg/1` may trigger an infinite loop (as in order to inspect/debug the data structure, you must call `inspect` itself). Here are some tips: * For debugging, use `IO.inspect/2` with the `structs: false` option, which disables custom printing and avoids calling the Inspect implementation recursively * To access the underlying error on your custom `Inspect` implementation, you may invoke the protocol directly. For example, we could invoke the `Inspect.MapSet` implementation above as: Inspect.MapSet.inspect(MapSet.new(), %Inspect.Opts{}) ### Inspect.inspect/2 (function) Converts `term` into an algebra document. This function shouldn't be invoked directly, unless when implementing a custom `inspect_fun` to be given to `Inspect.Opts`. Everywhere else, `Inspect.Algebra.to_doc/2` should be preferred as it handles structs and exceptions. ### Inspect.t/0 (type) All the types that implement this protocol. ### Inspect.Algebra (module) A set of functions for creating and manipulating algebra documents. This module implements the functionality described in ["Strictly Pretty" (2000) by Christian Lindig][0] with small additions, like support for binary nodes and a break mode that maximises use of horizontal space. iex> Inspect.Algebra.empty() :doc_nil iex> "foo" "foo" With the functions in this module, we can concatenate different elements together and render them: iex> doc = Inspect.Algebra.concat(Inspect.Algebra.empty(), "foo") iex> Inspect.Algebra.format(doc, 80) ["foo"] The functions `nest/2`, `space/2` and `line/2` help you put the document together into a rigid structure. However, the document algebra gets interesting when using functions like `glue/3` and `group/1`. A glue inserts a break between two documents. A group indicates a document that must fit the current line, otherwise breaks are rendered as new lines. Let's glue two docs together with a break, group it and then render it: iex> doc = Inspect.Algebra.glue("a", " ", "b") iex> doc = Inspect.Algebra.group(doc) iex> Inspect.Algebra.format(doc, 80) ["a", " ", "b"] Note that the break was represented as is, because we haven't reached a line limit. Once we do, it is replaced by a newline: iex> doc = Inspect.Algebra.glue(String.duplicate("a", 20), " ", "b") iex> doc = Inspect.Algebra.group(doc) iex> Inspect.Algebra.format(doc, 10) ["aaaaaaaaaaaaaaaaaaaa", "\n", "b"] This module uses the byte size to compute how much space there is left. If your document contains strings, then those need to be wrapped in `string/1`, which then relies on `String.length/1` to precompute the document size. Finally, this module also contains Elixir related functions, a bit tied to Elixir formatting, such as `to_doc/2`. ### Implementation details - Inspect.Algebra (module) The implementation of `Inspect.Algebra` is based on the Strictly Pretty paper by [Lindig][0] which builds on top of previous pretty printing algorithms but is tailored to strict languages, such as Elixir. The core idea in the paper is the use of explicit document groups which are rendered as flat (breaks as spaces) or as break (breaks as newlines). This implementation provides two types of breaks: `:strict` and `:flex`. When a group does not fit, all strict breaks are treated as newlines. Flex breaks, however, are re-evaluated on every occurrence and may still be rendered flat. See `break/1` and `flex_break/1` for more information. This implementation also adds `force_unfit/1` and `next_break_fits/2` which give more control over the document fitting. [0]: https://lindig.github.io/papers/strictly-pretty-2000.pdf ### Inspect.Algebra.break/1 (function) Returns a break document based on the given `string`. This break can be rendered as a linebreak or as the given `string`, depending on the `mode` of the chosen layout. ### Examples - Inspect.Algebra.break/1 (function) Let's create a document by concatenating two strings with a break between them: iex> doc = Inspect.Algebra.concat(["a", Inspect.Algebra.break("\t"), "b"]) iex> Inspect.Algebra.format(doc, 80) ["a", "\t", "b"] Note that the break was represented with the given string, because we didn't reach a line limit. Once we do, it is replaced by a newline: iex> break = Inspect.Algebra.break("\t") iex> doc = Inspect.Algebra.concat([String.duplicate("a", 20), break, "b"]) iex> doc = Inspect.Algebra.group(doc) iex> Inspect.Algebra.format(doc, 10) ["aaaaaaaaaaaaaaaaaaaa", "\n", "b"] ### Inspect.Algebra.collapse_lines/1 (function) Collapse any new lines and whitespace following this node, emitting up to `max` new lines. ### Inspect.Algebra.color/2 (function) Colors a document with the given color (preceding the document itself). ### Inspect.Algebra.color/3 (function) ### Inspect.Algebra.color_doc/3 (function) Colors a document if the `color_key` has a color in the options. ### Inspect.Algebra.concat/1 (function) Concatenates a list of documents returning a new document. ### Examples - Inspect.Algebra.concat/1 (function) iex> doc = Inspect.Algebra.concat(["a", "b", "c"]) iex> Inspect.Algebra.format(doc, 80) ["a", "b", "c"] ### Inspect.Algebra.concat/2 (function) Concatenates two document entities returning a new document. ### Examples - Inspect.Algebra.concat/2 (function) iex> doc = Inspect.Algebra.concat("hello", "world") iex> Inspect.Algebra.format(doc, 80) ["hello", "world"] ### Inspect.Algebra.container_doc/6 (function) Wraps `collection` in `left` and `right` according to limit and contents. It uses the given `left` and `right` documents as surrounding and the separator document `separator` to separate items in `docs`. If all entries in the collection are simple documents (texts or strings), then this function attempts to put as much as possible on the same line. If they are not simple, only one entry is shown per line if they do not fit. The limit in the given `inspect_opts` is respected and when reached this function stops processing and outputs `"..."` instead. ### Options - Inspect.Algebra.container_doc/6 (function) * `:separator` - the separator used between each doc * `:break` - If `:strict`, always break between each element. If `:flex`, breaks only when necessary. If `:maybe`, chooses `:flex` only if all elements are text-based, otherwise is `:strict` ### Examples - Inspect.Algebra.container_doc/6 (function) iex> inspect_opts = %Inspect.Opts{limit: :infinity} iex> fun = fn i, _opts -> to_string(i) end iex> doc = Inspect.Algebra.container_doc("[", Enum.to_list(1..5), "]", inspect_opts, fun) iex> Inspect.Algebra.format(doc, 5) |> IO.iodata_to_binary() "[1,\n 2,\n 3,\n 4,\n 5]" iex> inspect_opts = %Inspect.Opts{limit: 3} iex> fun = fn i, _opts -> to_string(i) end iex> doc = Inspect.Algebra.container_doc("[", Enum.to_list(1..5), "]", inspect_opts, fun) iex> Inspect.Algebra.format(doc, 20) |> IO.iodata_to_binary() "[1, 2, 3, ...]" iex> inspect_opts = %Inspect.Opts{limit: 3} iex> fun = fn i, _opts -> to_string(i) end iex> opts = [separator: "!"] iex> doc = Inspect.Algebra.container_doc("[", Enum.to_list(1..5), "]", inspect_opts, fun, opts) iex> Inspect.Algebra.format(doc, 20) |> IO.iodata_to_binary() "[1! 2! 3! ...]" ### Inspect.Algebra.empty/0 (function) Returns a document entity used to represent nothingness. ### Examples - Inspect.Algebra.empty/0 (function) iex> Inspect.Algebra.empty() :doc_nil ### Inspect.Algebra.flex_break/1 (function) Returns a flex break document based on the given `string`. A flex break still causes a group to break, like `break/1`, but it is re-evaluated when the documented is rendered. For example, take a group document represented as `[1, 2, 3]` where the space after every comma is a break. When the document above does not fit a single line, all breaks are enabled, causing the document to be rendered as: [1, 2, 3] However, if flex breaks are used, then each break is re-evaluated when rendered, so the document could be possible rendered as: [1, 2, 3] Hence the name "flex". they are more flexible when it comes to the document fitting. On the other hand, they are more expensive since each break needs to be re-evaluated. This function is used by `container_doc/6` and friends to the maximum number of entries on the same line. ### Inspect.Algebra.flex_glue/3 (function) Glues two documents (`doc1` and `doc2`) inserting a `flex_break/1` given by `break_string` between them. This function is used by `container_doc/6` and friends to the maximum number of entries on the same line. ### Inspect.Algebra.fold/2 (function) Folds a list of documents into a document using the given folder function. The list of documents is folded "from the right"; in that, this function is similar to `List.foldr/3`, except that it doesn't expect an initial accumulator and uses the last element of `docs` as the initial accumulator. ### Examples - Inspect.Algebra.fold/2 (function) iex> docs = ["A", "B", "C"] iex> docs = ...> Inspect.Algebra.fold(docs, fn doc, acc -> ...> Inspect.Algebra.concat([doc, "!", acc]) ...> end) iex> Inspect.Algebra.format(docs, 80) ["A", "!", "B", "!", "C"] ### Inspect.Algebra.fold_doc/2 (function) ### Inspect.Algebra.force_unfit/1 (function) Forces the current group to be unfit. ### Inspect.Algebra.format/2 (function) Formats a given document for a given width. Takes the maximum width and a document to print as its arguments and returns an IO data representation of the best layout for the document to fit in the given width. The document starts flat (without breaks) until a group is found. ### Examples - Inspect.Algebra.format/2 (function) iex> doc = Inspect.Algebra.glue("hello", " ", "world") iex> doc = Inspect.Algebra.group(doc) iex> doc |> Inspect.Algebra.format(30) |> IO.iodata_to_binary() "hello world" iex> doc |> Inspect.Algebra.format(10) |> IO.iodata_to_binary() "hello\nworld" ### Inspect.Algebra.glue/3 (function) Glues two documents (`doc1` and `doc2`) inserting the given break `break_string` between them. For more information on how the break is inserted, see `break/1`. ### Examples - Inspect.Algebra.glue/3 (function) iex> doc = Inspect.Algebra.glue("hello", "world") iex> Inspect.Algebra.format(doc, 80) ["hello", " ", "world"] iex> doc = Inspect.Algebra.glue("hello", "\t", "world") iex> Inspect.Algebra.format(doc, 80) ["hello", "\t", "world"] ### Inspect.Algebra.group/2 (function) Returns a group containing the specified document `doc`. Documents in a group are attempted to be rendered together to the best of the renderer ability. The group mode can also be set to `:inherit`, which means it automatically breaks if the parent group has broken too. ### Examples - Inspect.Algebra.group/2 (function) iex> doc = ...> Inspect.Algebra.group( ...> Inspect.Algebra.concat( ...> Inspect.Algebra.group( ...> Inspect.Algebra.concat( ...> "Hello,", ...> Inspect.Algebra.concat( ...> Inspect.Algebra.break(), ...> "A" ...> ) ...> ) ...> ), ...> Inspect.Algebra.concat( ...> Inspect.Algebra.break(), ...> "B" ...> ) ...> ) ...> ) iex> Inspect.Algebra.format(doc, 80) ["Hello,", " ", "A", " ", "B"] iex> Inspect.Algebra.format(doc, 6) ["Hello,", "\n", "A", "\n", "B"] ### Inspect.Algebra.is_doc/1 (macro) ### Inspect.Algebra.line/0 (function) A mandatory linebreak. A group with linebreaks will fit if all lines in the group fit. ### Examples - Inspect.Algebra.line/0 (function) iex> doc = ...> Inspect.Algebra.concat( ...> Inspect.Algebra.concat( ...> "Hughes", ...> Inspect.Algebra.line() ...> ), ...> "Wadler" ...> ) iex> Inspect.Algebra.format(doc, 80) ["Hughes", "\n", "Wadler"] ### Inspect.Algebra.line/2 (function) Inserts a mandatory linebreak between two documents. See `line/0`. ### Examples - Inspect.Algebra.line/2 (function) iex> doc = Inspect.Algebra.line("Hughes", "Wadler") iex> Inspect.Algebra.format(doc, 80) ["Hughes", "\n", "Wadler"] ### Inspect.Algebra.nest/3 (function) Nests the given document at the given `level`. If `level` is an integer, that's the indentation appended to line breaks whenever they occur. If the level is `:cursor`, the current position of the "cursor" in the document becomes the nesting. If the level is `:reset`, it is set back to 0. `mode` can be `:always`, which means nesting always happen, or `:break`, which means nesting only happens inside a group that has been broken. ### Examples - Inspect.Algebra.nest/3 (function) iex> doc = Inspect.Algebra.nest(Inspect.Algebra.glue("hello", "world"), 5) iex> doc = Inspect.Algebra.group(doc) iex> Inspect.Algebra.format(doc, 5) ["hello", "\n ", "world"] ### Inspect.Algebra.next_break_fits/2 (function) Considers the next break as fit. `mode` can be `:enabled` or `:disabled`. When `:enabled`, it will consider the document as fit as soon as it finds the next break, effectively cancelling the break. It will also ignore any `force_unfit/1` in search of the next break. When disabled, it behaves as usual and it will ignore any further `next_break_fits/2` instruction. ### Examples - Inspect.Algebra.next_break_fits/2 (function) This is used by Elixir's code formatter to avoid breaking code at some specific locations. For example, consider this code: some_function_call(%{..., key: value, ...}) Now imagine that this code does not fit its line. The code formatter introduces breaks inside `(` and `)` and inside `%{` and `}`. Therefore the document would break as: some_function_call( %{ ..., key: value, ... } ) The formatter wraps the algebra document representing the map in `next_break_fits/1` so the code is formatted as: some_function_call(%{ ..., key: value, ... }) ### Inspect.Algebra.no_limit/1 (function) Disable any rendering limit while rendering the given document. ### Examples - Inspect.Algebra.no_limit/1 (function) iex> doc = Inspect.Algebra.glue("hello", "world") |> Inspect.Algebra.group() iex> Inspect.Algebra.format(doc, 10) ["hello", "\n", "world"] iex> doc = Inspect.Algebra.no_limit(doc) iex> Inspect.Algebra.format(doc, 10) ["hello", " ", "world"] ### Inspect.Algebra.space/2 (function) Inserts a mandatory single space between two documents. ### Examples - Inspect.Algebra.space/2 (function) iex> doc = Inspect.Algebra.space("Hughes", "Wadler") iex> Inspect.Algebra.format(doc, 5) ["Hughes", " ", "Wadler"] ### Inspect.Algebra.string/1 (function) Creates a document represented by string. While `Inspect.Algebra` accepts binaries as documents, those are counted by binary size. On the other hand, `string` documents are measured in terms of graphemes towards the document size. ### Examples - Inspect.Algebra.string/1 (function) The following document has 10 bytes and therefore it does not format to width 9 without breaks: iex> doc = Inspect.Algebra.glue("olá", " ", "mundo") iex> doc = Inspect.Algebra.group(doc) iex> Inspect.Algebra.format(doc, 9) ["olá", "\n", "mundo"] However, if we use `string`, then the string length is used, instead of byte size, correctly fitting: iex> string = Inspect.Algebra.string("olá") iex> doc = Inspect.Algebra.glue(string, " ", "mundo") iex> doc = Inspect.Algebra.group(doc) iex> Inspect.Algebra.format(doc, 9) ["olá", " ", "mundo"] ### Inspect.Algebra.to_doc/2 (function) Converts an Elixir term to an algebra document according to the `Inspect` protocol. ### Inspect.Algebra.t/0 (type) ### Inspect.Opts (module) Defines the options used by the `Inspect` protocol. The following fields are available: * `:base` - prints integers and binaries as `:binary`, `:octal`, `:decimal`, or `:hex`. Defaults to `:decimal`. * `:binaries` - when `:as_binaries` all binaries will be printed in bit syntax. When `:as_strings` all binaries will be printed as strings, non-printable bytes will be escaped. When the default `:infer`, the binary will be printed as a string if `:base` is `:decimal` and if it is printable, otherwise in bit syntax. See `String.printable?/1` to learn when a string is printable. * `:charlists` - when `:as_charlists` all lists will be printed as charlists, non-printable elements will be escaped. When `:as_lists` all lists will be printed as lists. When the default `:infer`, the list will be printed as a charlist if it is printable, otherwise as list. See `List.ascii_printable?/1` to learn when a charlist is printable. * `:custom_options` (since v1.9.0) - a keyword list storing custom user-defined options. Useful when implementing the `Inspect` protocol for nested structs to pass the custom options through. It supports some pre-defined keys: - `:sort_maps` (since v1.14.4) - if set to `true`, sorts key-value pairs in maps. This can be helpful to make map inspection deterministic for testing, given maps key order is random. * `:inspect_fun` (since v1.9.0) - a function to build algebra documents. Defaults to `Inspect.Opts.default_inspect_fun/0`. * `:limit` - limits the number of items that are inspected for tuples, bitstrings, maps, lists and any other collection of items, with the exception of printable strings and printable charlists which use the `:printable_limit` option. If you don't want to limit the number of items to a particular number, use `:infinity`. It accepts a positive integer or `:infinity`. Defaults to `50`. * `:pretty` - if set to `true` enables pretty printing. Defaults to `false`. * `:printable_limit` - limits the number of characters that are inspected on printable strings and printable charlists. You can use `String.printable?/1` and `List.ascii_printable?/1` to check if a given string or charlist is printable. If you don't want to limit the number of characters to a particular number, use `:infinity`. It accepts a positive integer or `:infinity`. Defaults to `4096`. * `:safe` - when `false`, failures while inspecting structs will be raised as errors instead of being wrapped in the `Inspect.Error` exception. This is useful when debugging failures and crashes for custom inspect implementations. Defaults to `true`. * `:structs` - when `false`, structs are not formatted by the inspect protocol, they are instead printed as maps. Defaults to `true`. * `:syntax_colors` - when set to a keyword list of colors the output is colorized. The keys are types and the values are the colors to use for each type (for example, `[number: :red, atom: :blue]`). Types can include `:atom`, `:binary`, `:boolean`, `:list`, `:map`, `:number`, `:regex`, `:string`, `:tuple`, or some types to represent AST like `:variable`, `:call`, and `:operator`. Custom data types may provide their own options. Colors can be any `t:IO.ANSI.ansidata/0` as accepted by `IO.ANSI.format/1`. A default list of colors can be retrieved from `IO.ANSI.syntax_colors/0`. * `:width` - number of characters per line used when pretty is `true` or when printing to IO devices. Set to `0` to force each item to be printed on its own line. If you don't want to limit the number of items to a particular number, use `:infinity`. Defaults to `80`. ### Inspect.Opts.default_inspect_fun/0 (function) Returns the default inspect function. ### Inspect.Opts.default_inspect_fun/1 (function) Sets the default inspect function. Set this option with care as it will change how all values in the system are inspected. The main use of this functionality is to provide an entry point to filter inspected values, in order for entities to comply with rules and legislations on data security and data privacy. It is **extremely discouraged** for libraries to set their own function as this must be controlled by applications. Libraries should instead define their own structs with custom inspect implementations. If a library must change the default inspect function, then it is best to ask users of your library to explicitly call `default_inspect_fun/1` with your function of choice. The default is `Inspect.inspect/2`. ### Examples - Inspect.Opts.default_inspect_fun/1 (function) previous_fun = Inspect.Opts.default_inspect_fun() Inspect.Opts.default_inspect_fun(fn %{address: _} = map, opts -> previous_fun.(%{map | address: "[REDACTED]"}, opts) value, opts -> previous_fun.(value, opts) end) ### Inspect.Opts.new/1 (function) Builds an `Inspect.Opts` struct. ### Inspect.Opts.color_key/0 (type) ### Inspect.Opts.t/0 (type) ### JSON.Encoder (protocol) A protocol for custom JSON encoding of data structures. If you have a struct, you can derive the implementation of this protocol by specifying which fields should be encoded to JSON: @derive {JSON.Encoder, only: [....]} defstruct ... It is also possible to encode all fields or skip some fields via the `:except` option: @derive JSON.Encoder defstruct ... > #### Leaking Private Information {: .error} > > The `:except` approach should be used carefully to avoid > accidentally leaking private information when new fields are added. Finally, if you don't own the struct you want to encode to JSON, you may use `Protocol.derive/3` placed outside of any module: Protocol.derive(JSON.Encoder, NameOfTheStruct, only: [...]) Protocol.derive(JSON.Encoder, NameOfTheStruct) ### JSON.Encoder.encode/2 (function) A function invoked to encode the given term to `t:iodata/0`. ### JSON.Encoder.t/0 (type) All the types that implement this protocol. ### List.Chars (protocol) The `List.Chars` protocol is responsible for converting a structure to a charlist (only if applicable). The only function that must be implemented is `to_charlist/1` which does the conversion. The `to_charlist/1` function automatically imported by `Kernel` invokes this protocol. ### List.Chars.to_charlist/1 (function) Converts `term` to a charlist. ### List.Chars.t/0 (type) All the types that implement this protocol. ### Protocol (behaviour) Reference and functions for working with protocols. A protocol specifies an API that should be defined by its implementations. A protocol is defined with `Kernel.defprotocol/2` and its implementations with `Kernel.defimpl/3`. ### Example - Protocol (behaviour) In Elixir, we have two nouns for checking how many items there are in a data structure: `length` and `size`. `length` means the information must be computed. For example, `length(list)` needs to traverse the whole list to calculate its length. On the other hand, `tuple_size(tuple)` and `byte_size(binary)` do not depend on the tuple and binary size as the size information is precomputed in the data structure. Although Elixir includes specific functions such as `tuple_size`, `binary_size` and `map_size`, sometimes we want to be able to retrieve the size of a data structure regardless of its type. In Elixir we can write polymorphic code, i.e. code that works with different shapes/types, by using protocols. A size protocol could be implemented as follows: defprotocol Size do @doc "Calculates the size (and not the length!) of a data structure" def size(data) end Now that the protocol can be implemented for every data structure the protocol may have a compliant implementation for: defimpl Size, for: BitString do def size(binary), do: byte_size(binary) end defimpl Size, for: Map do def size(map), do: map_size(map) end defimpl Size, for: Tuple do def size(tuple), do: tuple_size(tuple) end Finally, we can use the `Size` protocol to call the correct implementation: Size.size({1, 2}) # => 2 Size.size(%{key: :value}) # => 1 Note that we didn't implement it for lists as we don't have the `size` information on lists, rather its value needs to be computed with `length`. The data structure you are implementing the protocol for must be the first argument to all functions defined in the protocol. It is possible to implement protocols for all Elixir types: * Structs (see the "Protocols and Structs" section below) * `Tuple` * `Atom` * `List` * `BitString` * `Integer` * `Float` * `Function` * `PID` * `Map` * `Port` * `Reference` * `Any` (see the "Fallback to `Any`" section below) ### Protocols and Structs - Protocol (behaviour) The real benefit of protocols comes when mixed with structs. For instance, Elixir ships with many data types implemented as structs, like `MapSet`. We can implement the `Size` protocol for those types as well: defimpl Size, for: MapSet do def size(map_set), do: MapSet.size(map_set) end When implementing a protocol for a struct, the `:for` option can be omitted if the `defimpl/3` call is inside the module that defines the struct: defmodule User do defstruct [:email, :name] defimpl Size do # two fields def size(%User{}), do: 2 end end If a protocol implementation is not found for a given type, invoking the protocol will raise unless it is configured to fall back to `Any`. Conveniences for building implementations on top of existing ones are also available, look at `defstruct/1` for more information about deriving protocols. ### Fallback to `Any` - Protocol (behaviour) In some cases, it may be convenient to provide a default implementation for all types. This can be achieved by setting the `@fallback_to_any` attribute to `true` in the protocol definition: defprotocol Size do @fallback_to_any true def size(data) end The `Size` protocol can now be implemented for `Any`: defimpl Size, for: Any do def size(_), do: 0 end Although the implementation above is arguably not a reasonable one. For example, it makes no sense to say a PID or an integer have a size of `0`. That's one of the reasons why `@fallback_to_any` is an opt-in behavior. For the majority of protocols, raising an error when a protocol is not implemented is the proper behavior. ### Multiple implementations - Protocol (behaviour) Protocols can also be implemented for multiple types at once: defprotocol Reversible do def reverse(term) end defimpl Reversible, for: [Map, List] do def reverse(term), do: Enum.reverse(term) end Inside `defimpl/3`, you can use `@protocol` to access the protocol being implemented and `@for` to access the module it is being defined for. ### Types - Protocol (behaviour) Defining a protocol automatically defines a zero-arity type named `t`, which can be used as follows: @spec print_size(Size.t()) :: :ok def print_size(data) do result = case Size.size(data) do 0 -> "data has no items" 1 -> "data has one item" n -> "data has #{n} items" end IO.puts(result) end The `@spec` above expresses that all types allowed to implement the given protocol are valid argument types for the given function. ### Configuration - Protocol (behaviour) The following module attributes are available to configure a protocol: * `@fallback_to_any` - when true, enables protocol dispatch to fallback to any * `@undefined_impl_description` - a string with additional description to be used on `Protocol.UndefinedError` when looking up the implementation fails. This option is only applied if `@fallback_to_any` is not set to true ### Consolidation - Protocol (behaviour) In order to speed up protocol dispatching, whenever all protocol implementations are known up-front, typically after all Elixir code in a project is compiled, Elixir provides a feature called *protocol consolidation*. Consolidation directly links protocols to their implementations in a way that invoking a function from a consolidated protocol is equivalent to invoking two remote functions - one to identify the correct implementation, and another to call the implementation. Protocol consolidation is applied by default to all Mix projects during compilation. This may be an issue during test. For instance, if you want to implement a protocol during test, the implementation will have no effect, as the protocol has already been consolidated. One possible solution is to include compilation directories that are specific to your test environment in your mix.exs: def project do ... elixirc_paths: elixirc_paths(Mix.env()) ... end defp elixirc_paths(:test), do: ["lib", "test/support"] defp elixirc_paths(_), do: ["lib"] And then you can define the implementations specific to the test environment inside `test/support/some_file.ex`. Another approach is to disable protocol consolidation during tests in your mix.exs: def project do ... consolidate_protocols: Mix.env() != :test ... end If you are using `Mix.install/2`, you can do by passing the `consolidate_protocols` option: Mix.install( deps, consolidate_protocols: false ) Although doing so is not recommended as it may affect the performance of your code. Finally, note all protocols are compiled with `debug_info` set to `true`, regardless of the option set by the `elixirc` compiler. The debug info is used for consolidation and it is removed after consolidation unless globally set. ### Protocol.__protocol__/1 (callback) A function available in all protocol definitions that returns protocol metadata. ### Protocol.assert_impl!/2 (function) Checks if the given module is loaded and is an implementation of the given protocol. Returns `:ok` if so, otherwise raises `ArgumentError`. ### Protocol.assert_protocol!/1 (function) Checks if the given module is loaded and is protocol. Returns `:ok` if so, otherwise raises `ArgumentError`. ### Protocol.consolidate/2 (function) Receives a protocol and a list of implementations and consolidates the given protocol. Consolidation happens by changing the protocol `impl_for` in the abstract format to have fast lookup rules. Usually the list of implementations to use during consolidation are retrieved with the help of `extract_impls/2`. It returns the updated version of the protocol bytecode. If the first element of the tuple is `:ok`, it means the protocol was consolidated. A given bytecode or protocol implementation can be checked to be consolidated or not by analyzing the protocol attribute: Protocol.consolidated?(Enumerable) This function does not load the protocol at any point nor loads the new bytecode for the compiled module. However, each implementation must be available and it will be loaded. ### Protocol.consolidated?/1 (function) Returns `true` if the protocol was consolidated. ### Protocol.derive/3 (macro) Derives the `protocol` for `module` with the given options. Every time you derive a protocol, Elixir will verify if the protocol has implemented the `c:Protocol.__deriving__/2` callback. If so, the callback will be invoked and it should define the implementation module. Otherwise an implementation that simply points to the `Any` implementation is automatically derived. ### Examples - Protocol.derive/3 (macro) defprotocol Derivable do @impl true defmacro __deriving__(module, options) do # If you need to load struct metadata, you may call: # struct_info = Macro.struct_info!(module, __CALLER__) quote do defimpl Derivable, for: unquote(module) do def ok(arg) do {:ok, arg, unquote(options)} end end end end def ok(arg) end Once the protocol is defined, there are two ways it can be derived. The first is by using the `@derive` module attribute by the time you define the struct: defmodule ImplStruct do @derive [Derivable] defstruct a: 0, b: 0 end Derivable.ok(%ImplStruct{}) #=> {:ok, %ImplStruct{a: 0, b: 0}, []} If the struct has already been defined, you can call this macro: require Protocol Protocol.derive(Derivable, ImplStruct, :oops) Derivable.ok(%ImplStruct{a: 1, b: 1}) #=> {:ok, %ImplStruct{a: 1, b: 1}, :oops} ### Protocol.extract_impls/2 (function) Extracts all types implemented for the given protocol from the given paths. The paths can be either a charlist or a string. Internally they are worked on as charlists, so passing them as lists avoid extra conversion. Does not load any of the implementations. ### Examples - Protocol.extract_impls/2 (function) # Get Elixir's ebin directory path and retrieve all protocols iex> path = Application.app_dir(:elixir, "ebin") iex> mods = Protocol.extract_impls(Enumerable, [path]) iex> List in mods true ### Protocol.extract_protocols/1 (function) Extracts all protocols from the given paths. The paths can be either a charlist or a string. Internally they are worked on as charlists, so passing them as lists avoid extra conversion. Does not load any of the protocols. ### Examples - Protocol.extract_protocols/1 (function) # Get Elixir's ebin directory path and retrieve all protocols iex> path = Application.app_dir(:elixir, "ebin") iex> mods = Protocol.extract_protocols([path]) iex> Enumerable in mods true ### Protocol.impl_for/1 (callback) A function available in all protocol definitions that returns the implementation for the given `term` or nil. If `@fallback_to_any` is true, `nil` is never returned. ### Protocol.impl_for!/1 (callback) A function available in all protocol definitions that returns the implementation for the given `term` or raises. If `@fallback_to_any` is true, it never raises. ### String.Chars (protocol) The `String.Chars` protocol is responsible for converting a structure to a binary (only if applicable). The only function required to be implemented is `to_string/1`, which does the conversion. The `to_string/1` function automatically imported by `Kernel` invokes this protocol. String interpolation also invokes `to_string/1` in its arguments. For example, `"foo#{bar}"` is the same as `"foo" <> to_string(bar)`. ### String.Chars.to_string/1 (function) Converts `term` to a string. ### String.Chars.t/0 (type) All the types that implement this protocol. ### Code (module) Utilities for managing code compilation, code evaluation, and code loading. This module complements Erlang's [`:code` module](`:code`) to add behavior which is specific to Elixir. For functions to manipulate Elixir's AST (rather than evaluating it), see the `Macro` module. ### Working with files - Code (module) This module contains three functions for compiling and evaluating files. Here is a summary of them and their behavior: * `require_file/2` - compiles a file and tracks its name. It does not compile the file again if it has been previously required. * `compile_file/2` - compiles a file without tracking its name. Compiles the file multiple times when invoked multiple times. * `eval_file/2` - evaluates the file contents without tracking its name. It returns the result of the last expression in the file, instead of the modules defined in it. Evaluated files do not trigger the compilation tracers described in the next section. In a nutshell, the first must be used when you want to keep track of the files handled by the system, to avoid the same file from being compiled multiple times. This is common in scripts. `compile_file/2` must be used when you are interested in the modules defined in a file, without tracking. `eval_file/2` should be used when you are interested in the result of evaluating the file rather than the modules it defines. The functions above work with Elixir source. If you want to work with modules compiled to bytecode, which have the `.beam` extension and are typically found below the _build directory of a Mix project, see the functions in Erlang's [`:code`](`:code`) module. ### Code loading on the Erlang VM - Code (module) Erlang has two modes to load code: interactive and embedded. By default, the Erlang VM runs in interactive mode, where modules are loaded as needed. In embedded mode the opposite happens, as all modules need to be loaded upfront or explicitly. You can use `ensure_loaded/1` (as well as `ensure_loaded?/1` and `ensure_loaded!/1`) to check if a module is loaded before using it and act. ## `ensure_compiled/1` and `ensure_compiled!/1` Elixir also includes `ensure_compiled/1` and `ensure_compiled!/1` functions that are a superset of `ensure_loaded/1`. Since Elixir's compilation happens in parallel, in some situations you may need to use a module that was not yet compiled, therefore it can't even be loaded. When invoked, `ensure_compiled/1` and `ensure_compiled!/1` halt the compilation of the caller until the module becomes available. Note that the distinction between `ensure_compiled/1` and `ensure_compiled!/1` is important: if you are using `ensure_compiled!/1`, you are indicating to the compiler that you can only continue if said module is available. If you are using `Code.ensure_compiled/1`, you are implying you may continue without the module and therefore Elixir may return `{:error, :unavailable}` for cases where the module is not yet available (but may be available later on). For those reasons, developers must typically use `Code.ensure_compiled!/1`. In particular, do not do this: case Code.ensure_compiled(module) do {:module, _} -> module {:error, _} -> raise ... end Finally, note you only need `ensure_compiled!/1` to check for modules being defined within the same project. It does not apply to modules from dependencies as dependencies are always compiled upfront. In most cases, `ensure_loaded/1` is enough. `ensure_compiled!/1` must be used in rare cases, usually involving macros that need to invoke a module for callback information. The use of `ensure_compiled/1` is even less likely. ### Compilation tracers - Code (module) Elixir supports compilation tracers, which allow modules to observe constructs handled by the Elixir compiler when compiling files. A tracer is a module that implements the `trace/2` function. The function receives the event name as first argument and `Macro.Env` as second and it must return `:ok`. It is very important for a tracer to do as little work as possible synchronously and dispatch the bulk of the work to a separate process. **Slow tracers will slow down compilation**. You can configure your list of tracers via `put_compiler_option/2`. The following events are available to tracers: * `:start` - (since v1.11.0) invoked whenever the compiler starts to trace a new lexical context. A lexical context is started when compiling a new file or when defining a module within a function. Note evaluated code does not start a new lexical context (because they don't track unused aliases, imports, etc) but defining a module inside evaluated code will. Note this event may be emitted in parallel, where multiple files/modules invoke `:start` and run at the same time. The value of the `lexical_tracker` of the macro environment, albeit opaque, can be used to uniquely identify the environment. * `:stop` - (since v1.11.0) invoked whenever the compiler stops tracing a new lexical context, such as a new file. * `{:import, meta, module, opts}` - traced whenever `module` is imported. `meta` is the import AST metadata and `opts` are the import options. * `{:imported_function, meta, module, name, arity}` and `{:imported_macro, meta, module, name, arity}` - traced whenever an imported function or macro is invoked. `meta` is the call AST metadata, `module` is the module the import is from, followed by the `name` and `arity` of the imported function/macro. A :remote_function/:remote_macro event may still be emitted for the imported module/name/arity. * `{:imported_quoted, meta, module, name, [arity]}` - traced whenever an imported function or macro is processed inside a `quote/2`. `meta` is the call AST metadata, `module` is the module the import is from, followed by the `name` and a list of `arities` of the imported function/macro. * `{:alias, meta, alias, as, opts}` - traced whenever `alias` is aliased to `as`. `meta` is the alias AST metadata and `opts` are the alias options. * `{:alias_expansion, meta, as, alias}` traced whenever there is an alias expansion for a previously defined `alias`, i.e. when the user writes `as` which is expanded to `alias`. `meta` is the alias expansion AST metadata. * `{:alias_reference, meta, module}` - traced whenever there is an alias in the code, i.e. whenever the user writes `MyModule.Foo.Bar` in the code, regardless if it was expanded or not. * `{:require, meta, module, opts}` - traced whenever `module` is required. `meta` is the require AST metadata and `opts` are the require options. If the `meta` option contains the `:from_macro`, then module was called from within a macro and therefore must be treated as a compile-time dependency. * `{:struct_expansion, meta, module, keys}` - traced whenever `module`'s struct is expanded. `meta` is the struct AST metadata and `keys` are the keys being used by expansion * `{:remote_function, meta, module, name, arity}` and `{:remote_macro, meta, module, name, arity}` - traced whenever a remote function or macro is referenced. `meta` is the call AST metadata, `module` is the invoked module, followed by the `name` and `arity`. * `{:local_function, meta, name, arity}` and `{:local_macro, meta, name, arity}` - traced whenever a local function or macro is referenced. `meta` is the call AST metadata, followed by the `name` and `arity`. * `{:compile_env, app, path, return}` - traced whenever `Application.compile_env/3` or `Application.compile_env!/2` are called. `app` is an atom, `path` is a list of keys to traverse in the application environment and `return` is either `{:ok, value}` or `:error`. * `:defmodule` - (since v1.16.2) traced as soon as the definition of a module starts. This is invoked early on in the module life cycle, `Module.open?/1` still returns `false` for such traces * `{:on_module, bytecode, _ignore}` - (since v1.13.0) traced whenever a module is defined. This is equivalent to the `@after_compile` callback and invoked after any `@after_compile` in the given module. The third element is currently `:none` but it may provide more metadata in the future. It is best to ignore it at the moment. Note that `Module` functions expecting not yet compiled modules (such as `Module.definitions_in/1`) are still available at the time this event is emitted. The `:tracers` compiler option can be combined with the `:parser_options` compiler option to enrich the metadata of the traced events above. New events may be added at any time in the future, therefore it is advised for the `trace/2` function to have a "catch-all" clause. Below is an example tracer that prints all remote function invocations: defmodule MyTracer do def trace({:remote_function, _meta, module, name, arity}, env) do IO.puts("#{env.file}:#{env.line} #{inspect(module)}.#{name}/#{arity}") :ok end def trace(_event, _env) do :ok end end ### Code.append_path/2 (function) Appends a path to the Erlang VM code path list. This is the list of directories the Erlang VM uses for finding module code. The list of files is managed per Erlang VM node. The path is expanded with `Path.expand/1` before being appended. It requires the path to exist. Returns a boolean indicating if the path was successfully added. ### Examples - Code.append_path/2 (function) Code.append_path(".") #=> true Code.append_path("/does_not_exist") #=> false ### Options - Code.append_path/2 (function) * `:cache` - (since v1.15.0) when true, the code path is cached the first time it is traversed in order to reduce file system operations. It requires Erlang/OTP 26, otherwise it is a no-op. ### Code.append_paths/2 (function) Appends a list of `paths` to the Erlang VM code path list. This is the list of directories the Erlang VM uses for finding module code. The list of files is managed per Erlang VM node. All paths are expanded with `Path.expand/1` before being appended. Only existing paths are appended. This function always returns `:ok`, regardless of how many paths were appended. Use `append_path/1` if you need more control. ### Examples - Code.append_paths/2 (function) Code.append_paths([".", "/does_not_exist"]) #=> :ok ### Options - Code.append_paths/2 (function) * `:cache` - when true, the code path is cached the first time it is traversed in order to reduce file system operations. It requires Erlang/OTP 26, otherwise it is a no-op. ### Code.available_compiler_options/0 (function) Returns a list with all available compiler options. For a description of all options, see `put_compiler_option/2`. ### Examples - Code.available_compiler_options/0 (function) Code.available_compiler_options() #=> [:docs, :debug_info, ...] ### Code.can_await_module_compilation?/0 (function) Returns `true` if the current process can await for module compilation. When compiling Elixir code via `Kernel.ParallelCompiler`, which is used by Mix and `elixirc`, calling a module that has not yet been compiled will block the caller until the module becomes available. Executing Elixir scripts, such as passing a filename to `elixir`, does not await. ### Code.compile_file/2 (function) Compiles the given file. Accepts `relative_to` as an argument to tell where the file is located. Returns a list of tuples where the first element is the module name and the second one is its bytecode (as a binary). Opposite to `require_file/2`, it does not track the filename of the compiled file. If you would like to get the result of evaluating file rather than the modules defined in it, see `eval_file/2`. For compiling many files concurrently, see `Kernel.ParallelCompiler.compile/2`. ### Code.compile_quoted/2 (function) Compiles the quoted expression. Returns a list of tuples where the first element is the module name and the second one is its bytecode (as a binary). A `file` can be given as second argument which will be used for reporting warnings and errors. ### Code.compile_string/2 (function) Compiles the given string. Returns a list of tuples where the first element is the module name and the second one is its bytecode (as a binary). A `file` can be given as a second argument which will be used for reporting warnings and errors. **Warning**: `string` can be any Elixir code and code can be executed with the same privileges as the Erlang VM: this means that such code could compromise the machine (for example by executing system commands). Don't use `compile_string/2` with untrusted input (such as strings coming from the network). ### Code.compiler_options/0 (function) Gets all compilation options from the code server. To get individual options, see `get_compiler_option/1`. For a description of all options, see `put_compiler_option/2`. ### Examples - Code.compiler_options/0 (function) Code.compiler_options() #=> %{debug_info: true, docs: true, ...} ### Code.compiler_options/1 (function) Stores all given compilation options. Changing the compilation options affect all processes running in a given Erlang VM node. To store individual options and for a description of all options, see `put_compiler_option/2`. Returns a map with previous values. ### Examples - Code.compiler_options/1 (function) Code.compiler_options(infer_signatures: false) #=> %{infer_signatures: true} ### Code.delete_path/1 (function) Deletes a path from the Erlang VM code path list. This is the list of directories the Erlang VM uses for finding module code. The list of files is managed per Erlang VM node. The path is expanded with `Path.expand/1` before being deleted. If the path does not exist, this function returns `false`. ### Examples - Code.delete_path/1 (function) Code.prepend_path(".") Code.delete_path(".") #=> true Code.delete_path("/does_not_exist") #=> false ### Code.delete_paths/1 (function) Deletes a list of paths from the Erlang VM code path list. This is the list of directories the Erlang VM uses for finding module code. The list of files is managed per Erlang VM node. The path is expanded with `Path.expand/1` before being deleted. If the path does not exist, this function returns `false`. ### Code.ensure_all_loaded/1 (function) Ensures the given modules are loaded. Similar to `ensure_loaded/1`, but accepts a list of modules instead of a single module, and loads all of them. If all modules load successfully, returns `:ok`. Otherwise, returns `{:error, errors}` where `errors` is a list of tuples made of the module and the reason it failed to load. ### Examples - Code.ensure_all_loaded/1 (function) iex> Code.ensure_all_loaded([Atom, String]) :ok iex> Code.ensure_all_loaded([Atom, DoesNotExist]) {:error, [{DoesNotExist, :nofile}]} ### Code.ensure_all_loaded!/1 (function) Same as `ensure_all_loaded/1` but raises if any of the modules cannot be loaded. ### Code.ensure_compiled/1 (function) Similar to `ensure_compiled!/1` but indicates you can continue without said module. While `ensure_compiled!/1` indicates to the Elixir compiler you can only continue when said module is available, this function indicates you may continue compilation without said module. If it succeeds in loading the module, it returns `{:module, module}`. If not, returns `{:error, reason}` with the error reason. If the module being checked is currently in a compiler deadlock, this function returns `{:error, :unavailable}`. Unavailable doesn't necessarily mean the module doesn't exist, just that it is not currently available, but it (or may not) become available in the future. Therefore, if you can only continue if the module is available, use `ensure_compiled!/1` instead. In particular, do not do this: case Code.ensure_compiled(module) do {:module, _} -> module {:error, _} -> raise ... end See the module documentation for more information on code loading. ### Code.ensure_compiled!/1 (function) Ensures the given module is compiled and loaded. If the module is already loaded, it works as no-op. If the module was not compiled yet, `ensure_compiled!/1` halts the compilation of the caller until the module given to `ensure_compiled!/1` becomes available or all files for the current project have been compiled. If compilation finishes and the module is not available or is in a deadlock, an error is raised. Given this function halts compilation, use it carefully. In particular, avoid using it to guess which modules are in the system. Overuse of this function can also lead to deadlocks, where two modules check at the same time if the other is compiled. This returns a specific unavailable error code, where we cannot successfully verify a module is available or not. See the module documentation for more information on code loading. ### Code.ensure_loaded/1 (function) Ensures the given module is loaded. If the module is already loaded, this works as no-op. If the module was not yet loaded, it tries to load it. If it succeeds in loading the module, it returns `{:module, module}`. If not, returns `{:error, reason}` with the error reason. See the module documentation for more information on code loading. ### Examples - Code.ensure_loaded/1 (function) iex> Code.ensure_loaded(Atom) {:module, Atom} iex> Code.ensure_loaded(DoesNotExist) {:error, :nofile} ### Code.ensure_loaded!/1 (function) Same as `ensure_loaded/1` but raises if the module cannot be loaded. ### Code.ensure_loaded?/1 (function) Ensures the given module is loaded. Similar to `ensure_loaded/1`, but returns `true` if the module is already loaded or was successfully loaded. Returns `false` otherwise. ### Examples - Code.ensure_loaded?/1 (function) iex> Code.ensure_loaded?(String) true ### Code.env_for_eval/1 (function) Returns an environment for evaluation. It accepts either a `Macro.Env`, that is then pruned and prepared, or a list of options. It returns an environment that is ready for evaluation. Most functions in this module will automatically prepare the given environment for evaluation, so you don't need to explicitly call this function, with the exception of `eval_quoted_with_env/3`, which was designed precisely to be called in a loop, to implement features such as interactive shells or anything else with multiple evaluations. ### Options - Code.env_for_eval/1 (function) If an env is not given, the options can be: * `:file` - the file to be considered in the evaluation * `:line` - the line on which the script starts * `:module` - the module to run the environment on ### Code.eval_file/2 (function) Evaluates the given file. Accepts `relative_to` as an argument to tell where the file is located. While `require_file/2` and `compile_file/2` return the loaded modules and their bytecode, `eval_file/2` simply evaluates the file contents and returns the evaluation result and its binding (exactly the same return value as `eval_string/3`). ### Code.eval_quoted/3 (function) Evaluates the quoted contents. **Warning**: Calling this function inside a macro is considered bad practice as it will attempt to evaluate runtime values at compile time. Macro arguments are typically transformed by unquoting them into the returned quoted expressions (instead of evaluated). See `eval_string/3` for a description of `binding` and `opts`. ### Examples - Code.eval_quoted/3 (function) iex> contents = quote(do: var!(a) + var!(b)) iex> {result, binding} = Code.eval_quoted(contents, [a: 1, b: 2], file: __ENV__.file, line: __ENV__.line) iex> result 3 iex> Enum.sort(binding) [a: 1, b: 2] For convenience, you can pass `__ENV__/0` as the `opts` argument and all options will be automatically extracted from the current environment: iex> contents = quote(do: var!(a) + var!(b)) iex> {result, binding} = Code.eval_quoted(contents, [a: 1, b: 2], __ENV__) iex> result 3 iex> Enum.sort(binding) [a: 1, b: 2] ### Code.eval_quoted_with_env/4 (function) Evaluates the given `quoted` contents with `binding` and `env`. This function is meant to be called in a loop, to implement features such as interactive shells or anything else with multiple evaluations. Therefore, the first time you call this function, you must compute the initial environment with `env_for_eval/1`. The remaining calls must pass the environment that was returned by this function. ### Options - Code.eval_quoted_with_env/4 (function) * `:prune_binding` - (since v1.14.2) prune binding to keep only variables read or written by the evaluated code. Note that variables used by modules are always pruned, even if later used by the modules. You can submit to the `:on_module` tracer event and access the variables used by the module from its environment. ### Code.eval_string/3 (function) Evaluates the contents given by `string`. The `binding` argument is a list of all variables and their values. The `opts` argument is a keyword list of environment options. **Warning**: `string` can be any Elixir code and will be executed with the same privileges as the Erlang VM: this means that such code could compromise the machine (for example by executing system commands). Don't use `eval_string/3` with untrusted input (such as strings coming from the network). ### Options - Code.eval_string/3 (function) It accepts the same options as `env_for_eval/1`. Additionally, you may also pass an environment as second argument, so the evaluation happens within that environment. Returns a tuple of the form `{value, binding}`, where `value` is the value returned from evaluating `string`. If an error occurs while evaluating `string`, an exception will be raised. `binding` is a list with all variable names and their values after evaluating `string`. The binding keys are usually atoms, but they may be a tuple for variables defined in a different context. The names are in no particular order. ### Examples - Code.eval_string/3 (function) iex> {result, binding} = Code.eval_string("a + b", [a: 1, b: 2], file: __ENV__.file, line: __ENV__.line) iex> result 3 iex> Enum.sort(binding) [a: 1, b: 2] iex> {result, binding} = Code.eval_string("c = a + b", [a: 1, b: 2], __ENV__) iex> result 3 iex> Enum.sort(binding) [a: 1, b: 2, c: 3] iex> {result, binding} = Code.eval_string("a = a + b", [a: 1, b: 2]) iex> result 3 iex> Enum.sort(binding) [a: 3, b: 2] For convenience, you can pass `__ENV__/0` as the `opts` argument and all imports, requires and aliases defined in the current environment will be automatically carried over: iex> {result, binding} = Code.eval_string("a + b", [a: 1, b: 2], __ENV__) iex> result 3 iex> Enum.sort(binding) [a: 1, b: 2] ### Code.fetch_docs/1 (function) Returns the docs for the given module or path to `.beam` file. When given a module name, it finds its BEAM code and reads the docs from it. When given a path to a `.beam` file, it will load the docs directly from that file. It returns the term stored in the documentation chunk in the format defined by [EEP 48](https://www.erlang.org/eeps/eep-0048.html) or `{:error, reason}` if the chunk is not available. ### Examples - Code.fetch_docs/1 (function) # Module documentation of an existing module iex> {:docs_v1, _, :elixir, _, %{"en" => module_doc}, _, _} = Code.fetch_docs(Atom) iex> module_doc |> String.split("\n") |> Enum.at(0) "Atoms are constants whose values are their own name." # A module that doesn't exist iex> Code.fetch_docs(ModuleNotGood) {:error, :module_not_found} ### Code.format_file!/2 (function) Formats a file. See `format_string!/2` for more information on code formatting and available options. ### Code.format_string!/2 (function) Formats the given code `string`. The formatter receives a string representing Elixir code and returns iodata representing the formatted code according to pre-defined rules. ### Options - Code.format_string!/2 (function) Regular options (do not change the AST): * `:file` - the file which contains the string, used for error reporting * `:line` - the line the string starts, used for error reporting * `:line_length` - the line length to aim for when formatting the document. Defaults to 98. This value indicates when an expression should be broken over multiple lines but it is not guaranteed to do so. See the "Line length" section below for more information * `:locals_without_parens` - a keyword list of name and arity pairs that should be kept without parens whenever possible. The arity may be the atom `:*`, which implies all arities of that name. The formatter already includes a list of functions and this option augments this list. * `:force_do_end_blocks` (since v1.9.0) - when `true`, converts all inline usages of `do: ...`, `else: ...` and friends into `do`-`end` blocks. Defaults to `false`. Note that this option is convergent: once you set it to `true`, **all keywords** will be converted. If you set it to `false` later on, `do`-`end` blocks won't be converted back to keywords. Migration options (change the AST), see the "Migration formatting" section below: * `:migrate` (since v1.18.0) - when `true`, sets all other migration options to `true` by default. Defaults to `false`. * `:migrate_bitstring_modifiers` (since v1.18.0) - when `true`, removes unnecessary parentheses in known bitstring [modifiers](`<<>>/1`), for example `< >` becomes `< >`, or adds parentheses for custom modifiers, where `< >` becomes `< >`. Defaults to the value of the `:migrate` option. This option changes the AST. * `:migrate_charlists_as_sigils` (since v1.18.0) - when `true`, formats charlists as [`~c`](`Kernel.sigil_c/2`) sigils, for example `'foo'` becomes `~c"foo"`. Defaults to the value of the `:migrate` option. This option changes the AST. * `:migrate_unless` (since v1.18.0) - when `true`, rewrites `unless` expressions using `if` with a negated condition, for example `unless foo, do:` becomes `if !foo, do:`. Defaults to the value of the `:migrate` option. This option changes the AST. ### Design principles - Code.format_string!/2 (function) The formatter was designed under three principles. First, the formatter never changes the semantics of the code by default. This means the input AST and the output AST are almost always equivalent. The second principle is to provide as little configuration as possible. This eases the formatter adoption by removing contention points while making sure a single style is followed consistently by the community as a whole. The formatter does not hard code names. The formatter will not behave specially because a function is named `defmodule`, `def`, or the like. This principle mirrors Elixir's goal of being an extensible language where developers can extend the language with new constructs as if they were part of the language. When it is absolutely necessary to change behavior based on the name, this behavior should be configurable, such as the `:locals_without_parens` option. ### Running the formatter - Code.format_string!/2 (function) The formatter attempts to fit the most it can on a single line and introduces line breaks wherever possible when it cannot. In some cases, this may lead to undesired formatting. Therefore, **some code generated by the formatter may not be aesthetically pleasing and may require explicit intervention from the developer**. That's why we do not recommend to run the formatter blindly in an existing codebase. Instead you should format and sanity check each formatted file. For example, the formatter may break a long function definition over multiple clauses: def my_function( %User{name: name, age: age, ...}, arg1, arg2 ) do ... end While the code above is completely valid, you may prefer to match on the struct variables inside the function body in order to keep the definition on a single line: def my_function(%User{} = user, arg1, arg2) do %{name: name, age: age, ...} = user ... end In some situations, you can use the fact the formatter does not generate elegant code as a hint for refactoring. Take this code: def board?(board_id, %User{} = user, available_permissions, required_permissions) do Tracker.OrganizationMembers.user_in_organization?(user.id, board.organization_id) and required_permissions == Enum.to_list(MapSet.intersection(MapSet.new(required_permissions), MapSet.new(available_permissions))) end The code above has very long lines and running the formatter is not going to address this issue. In fact, the formatter may make it more obvious that you have complex expressions: def board?(board_id, %User{} = user, available_permissions, required_permissions) do Tracker.OrganizationMembers.user_in_organization?(user.id, board.organization_id) and required_permissions == Enum.to_list( MapSet.intersection( MapSet.new(required_permissions), MapSet.new(available_permissions) ) ) end Take such cases as a suggestion that your code should be refactored: def board?(board_id, %User{} = user, available_permissions, required_permissions) do Tracker.OrganizationMembers.user_in_organization?(user.id, board.organization_id) and matching_permissions?(required_permissions, available_permissions) end defp matching_permissions?(required_permissions, available_permissions) do intersection = required_permissions |> MapSet.new() |> MapSet.intersection(MapSet.new(available_permissions)) |> Enum.to_list() required_permissions == intersection end To sum it up: since the formatter cannot change the semantics of your code, sometimes it is necessary to tweak or refactor the code to get optimal formatting. To help better understand how to control the formatter, we describe in the next sections the cases where the formatter keeps the user encoding and how to control multiline expressions. ### Line length - Code.format_string!/2 (function) Another point about the formatter is that the `:line_length` configuration indicates when an expression should be broken over multiple lines but it is not guaranteed to do so. In many cases, it is not possible for the formatter to break your code apart, which means it will go over the line length. For example, if you have a long string: "this is a very long string that will go over the line length" The formatter doesn't know how to break it apart without changing the code underlying syntax representation, so it is up to you to step in: "this is a very long string " <> "that will go over the line length" The string concatenation makes the code fit on a single line and also gives more options to the formatter. This may also appear in keywords such as do/end blocks and operators, where the `do` keyword may go over the line length because there is no opportunity for the formatter to introduce a line break in a readable way. For example, if you do: case very_long_expression() do end And only the `do` keyword is beyond the line length, Elixir **will not** emit this: case very_long_expression() do end So it prefers to not touch the line at all and leave `do` above the line limit. ### Keeping user's formatting - Code.format_string!/2 (function) The formatter respects the input format in some cases. Those are listed below: * Insignificant digits in numbers are kept as is. The formatter, however, always inserts underscores for decimal numbers with more than 5 digits and converts hexadecimal digits to uppercase * Strings, charlists, atoms and sigils are kept as is. No character is automatically escaped or unescaped. The choice of delimiter is also respected from the input * Newlines inside blocks are kept as in the input except for: 1) expressions that take multiple lines will always have an empty line before and after and 2) empty lines are always squeezed together into a single empty line * The choice between `:do` keyword and `do`-`end` blocks is left to the user * Lists, tuples, bitstrings, maps, structs and function calls will be broken into multiple lines if they are followed by a newline in the opening bracket and preceded by a new line in the closing bracket * Newlines before certain operators (such as the pipeline operators) and before other operators (such as comparison operators) The behaviors above are not guaranteed. We may remove or add new rules in the future. The goal of documenting them is to provide better understanding on what to expect from the formatter. ### Multi-line lists, maps, tuples, and the like - Code.format_string!/2 (function) You can force lists, tuples, bitstrings, maps, structs and function calls to have one entry per line by adding a newline after the opening bracket and a new line before the closing bracket lines. For example: [ foo, bar ] If there are no newlines around the brackets, then the formatter will try to fit everything on a single line, such that the snippet below [foo, bar] will be formatted as [foo, bar] You can also force function calls and keywords to be rendered on multiple lines by having each entry on its own line: defstruct name: nil, age: 0 The code above will be kept with one keyword entry per line by the formatter. To avoid that, just squash everything into a single line. ### Parens and no parens in function calls - Code.format_string!/2 (function) Elixir has two syntaxes for function calls. With parens and no parens. By default, Elixir will add parens to all calls except for: 1. calls that have `do`-`end` blocks 2. local calls without parens where the name and arity of the local call is also listed under `:locals_without_parens` (except for calls with arity 0, where the compiler always require parens) The choice of parens and no parens also affects indentation. When a function call with parens doesn't fit on the same line, the formatter introduces a newline around parens and indents the arguments with two spaces: some_call( arg1, arg2, arg3 ) On the other hand, function calls without parens are always indented by the function call length itself, like this: some_call arg1, arg2, arg3 If the last argument is a data structure, such as maps and lists, and the beginning of the data structure fits on the same line as the function call, then no indentation happens, this allows code like this: Enum.reduce(some_collection, initial_value, fn element, acc -> # code end) some_function_without_parens %{ foo: :bar, baz: :bat } ### Code comments - Code.format_string!/2 (function) The formatter handles code comments and guarantees a space is always added between the beginning of the comment (#) and the next character. The formatter also extracts all trailing comments to their previous line. For example, the code below hello #world will be rewritten to # world hello While the formatter attempts to preserve comments in most situations, that's not always possible, because code comments are handled apart from the code representation (AST). While the formatter can preserve code comments between expressions and function arguments, the formatter cannot currently preserve them around operators. For example, the following code will move the code comments to before the operator usage: foo() || # also check for bar bar() In some situations, code comments can be seen as ambiguous by the formatter. For example, the comment in the anonymous function below fn arg1 -> body1 # comment arg2 -> body2 end and in this one fn arg1 -> body1 # comment arg2 -> body2 end are considered equivalent (the nesting is discarded alongside most of user formatting). In such cases, the code formatter will always format to the latter. ### Newlines - Code.format_string!/2 (function) The formatter converts all newlines in code from `\r\n` to `\n`. ### Migration formatting - Code.format_string!/2 (function) As part of the Elixir release cycle, deprecations are being introduced, emitting warnings which might require existing code to be changed. In order to reduce the burden on developers when upgrading Elixir to the next version, the formatter exposes some options, disabled by default, in order to automate this process. These options should address most of the typical use cases, but given they introduce changes to the AST, there is a non-zero risk for meta-programming heavy projects that relied on a specific AST, or projects that are re-defining functions from the `Kernel`. In such cases, migrations cannot be applied blindly and some extra changes might be needed in order to address the deprecation warnings. ### Code.get_compiler_option/1 (function) Returns the value of a given compiler option. For a description of all options, see `put_compiler_option/2`. ### Examples - Code.get_compiler_option/1 (function) Code.get_compiler_option(:debug_info) #=> true ### Code.loaded?/1 (function) Returns `true` if the module is loaded. This function doesn't attempt to load the module. For such behavior, `ensure_loaded?/1` can be used. ### Examples - Code.loaded?/1 (function) iex> Code.loaded?(Atom) true iex> Code.loaded?(NotYetLoaded) false ### Code.prepend_path/2 (function) Prepends a path to the Erlang VM code path list. This is the list of directories the Erlang VM uses for finding module code. The list of files is managed per Erlang VM node. The path is expanded with `Path.expand/1` before being prepended. It requires the path to exist. Returns a boolean indicating if the path was successfully added. ### Examples - Code.prepend_path/2 (function) Code.prepend_path(".") #=> true Code.prepend_path("/does_not_exist") #=> false ### Options - Code.prepend_path/2 (function) * `:cache` - (since v1.15.0) when true, the code path is cached the first time it is traversed in order to reduce file system operations. It requires Erlang/OTP 26, otherwise it is a no-op. ### Code.prepend_paths/2 (function) Prepends a list of `paths` to the Erlang VM code path list. This is the list of directories the Erlang VM uses for finding module code. The list of files is managed per Erlang VM node. All paths are expanded with `Path.expand/1` before being prepended. Only existing paths are prepended. This function always returns `:ok`, regardless of how many paths were prepended. Use `prepend_path/1` if you need more control. ### Examples - Code.prepend_paths/2 (function) Code.prepend_paths([".", "/does_not_exist"]) #=> :ok ### Options - Code.prepend_paths/2 (function) * `:cache` - when true, the code path is cached the first time it is traversed in order to reduce file system operations. It requires Erlang/OTP 26, otherwise it is a no-op. ### Code.print_diagnostic/2 (function) Prints a diagnostic into the standard error. A diagnostic is either returned by `Kernel.ParallelCompiler` or by `Code.with_diagnostics/2`. ### Options - Code.print_diagnostic/2 (function) * `:snippet` - whether to read the code snippet in the diagnostic location. As it may impact performance, it is not recommended to be used in runtime. Defaults to `true`. ### Code.purge_compiler_modules/0 (function) Purge compiler modules. The compiler utilizes temporary modules to compile code. For example, `elixir_compiler_1`, `elixir_compiler_2`, and so on. In case the compiled code stores references to anonymous functions or similar, the Elixir compiler may be unable to reclaim those modules, keeping an unnecessary amount of code in memory and eventually leading to modules such as `elixir_compiler_12345`. This function purges all modules currently kept by the compiler, allowing old compiler module names to be reused. If there are any processes running any code from such modules, they will be terminated too. This function is only meant to be called if you have a long running node that is constantly evaluating code. It returns `{:ok, number_of_modules_purged}`. ### Code.put_compiler_option/2 (function) Stores a compilation option. Changing the compilation options affect all processes running in a given Erlang VM node. Available options are: * `:docs` - when `true`, retains documentation in the compiled module. Defaults to `true`. * `:debug_info` - when `true`, retains debug information in the compiled module. This option can also be overridden per module using the `@compile` directive. Defaults to `true`. This enables tooling to partially reconstruct the original source code, for instance, to perform static analysis of code. Therefore, disabling `:debug_info` is not recommended as it removes the ability of the Elixir compiler and other tools to provide feedback. If you want to remove the `:debug_info` while deploying, tools like `mix release` already do such by default. Other environments, such as `mix test`, automatically disables this via the `:test_elixirc_options` project configuration, as there is typically no need to store debug chunks for test files. * `:ignore_already_consolidated` (since v1.10.0) - when `true`, does not warn when a protocol has already been consolidated and a new implementation is added. Defaults to `false`. * `:ignore_module_conflict` - when `true`, does not warn when a module has already been defined. Defaults to `false`. * `:infer_signatures` (since v1.18.0) - when `false`, it disables module-local signature inference used when type checking remote calls to the compiled module. Type checking will be executed regardless of the value of this option. Defaults to `true`. `mix test` automatically disables this option via the `:test_elixirc_options` project configuration, as there is typically no need to store infer signatures for test files. * `:relative_paths` - when `true`, uses relative paths in quoted nodes, warnings, and errors generated by the compiler. Note disabling this option won't affect runtime warnings and errors. Defaults to `true`. * `:no_warn_undefined` (since v1.10.0) - list of modules and `{Mod, fun, arity}` tuples that will not emit warnings that the module or function does not exist at compilation time. Pass atom `:all` to skip warning for all undefined functions. This can be useful when doing dynamic compilation. Defaults to `[]`. * `:tracers` (since v1.10.0) - a list of tracers (modules) to be used during compilation. See the module docs for more information. Defaults to `[]`. * `:parser_options` (since v1.10.0) - a keyword list of options to be given to the parser when compiling files. It accepts the same options as `string_to_quoted/2` (except by the options that change the AST itself). This can be used in combination with the tracer to retrieve localized information about events happening during compilation. Defaults to `[columns: true]`. This option only affects code compilation functions, such as `compile_string/2` and `compile_file/2` but not `string_to_quoted/2` and friends, as the latter is used for other purposes beyond compilation. * `:on_undefined_variable` (since v1.15.0) - either `:raise` or `:warn`. When `:raise` (the default), undefined variables will trigger a compilation error. You may be set it to `:warn` if you want undefined variables to emit a warning and expand as to a local call to the zero-arity function of the same name (for example, `node` would be expanded as `node()`). This `:warn` behavior only exists for compatibility reasons when working with old dependencies, its usage is discouraged and it will be removed in future releases. It always returns `:ok`. Raises an error for invalid options. ### Examples - Code.put_compiler_option/2 (function) Code.put_compiler_option(:debug_info, true) #=> :ok ### Code.quoted_to_algebra/2 (function) Converts a quoted expression to an algebra document using Elixir's formatter rules. The algebra document can be converted into a string by calling: doc |> Inspect.Algebra.format(:infinity) |> IO.iodata_to_binary() For a high-level function that does the same, see `Macro.to_string/1`. ### Formatting considerations - Code.quoted_to_algebra/2 (function) The Elixir AST does not contain metadata for literals like strings, lists, or tuples with two elements, which means that the produced algebra document will not respect all of the user preferences and comments may be misplaced. To get better results, you can use the `:token_metadata`, `:unescape` and `:literal_encoder` options to `string_to_quoted/2` to provide additional information to the formatter: [ literal_encoder: &{:ok, {:__block__, &2, [&1]}}, token_metadata: true, unescape: false ] This will produce an AST that contains information such as `do` blocks start and end lines or sigil delimiters, and by wrapping literals in blocks they can now hold metadata like line number, string delimiter and escaped sequences, or integer formatting (such as `0x2a` instead of `47`). However, **note this AST is not valid**. If you evaluate it, it won't have the same semantics as the regular Elixir AST due to the `:unescape` and `:literal_encoder` options. However, those options are useful if you're doing source code manipulation, where it's important to preserve user choices and comments placing. ### Options - Code.quoted_to_algebra/2 (function) * `:comments` - the list of comments associated with the quoted expression. Defaults to `[]`. It is recommended that both `:token_metadata` and `:literal_encoder` options are given to `string_to_quoted_with_comments/2` in order to get proper placement for comments * `:escape` - when `true`, escaped sequences like `\n` will be escaped into `\\n`. If the `:unescape` option was set to `false` when using `string_to_quoted/2`, setting this option to `false` will prevent it from escaping the sequences twice. Defaults to `true`. * `:locals_without_parens` - a keyword list of name and arity pairs that should be kept without parens whenever possible. The arity may be the atom `:*`, which implies all arities of that name. The formatter already includes a list of functions and this option augments this list. * `:syntax_colors` - a keyword list of colors the output is colorized. See `Inspect.Opts` for more information. ### Code.require_file/2 (function) Requires the given `file`. Accepts `relative_to` as an argument to tell where the file is located. If the file was already required, `require_file/2` doesn't do anything and returns `nil`. Note that if `require_file/2` is invoked by different processes concurrently, the first process to invoke `require_file/2` acquires a lock and the remaining ones will block until the file is available. This means that if `require_file/2` is called more than once with a given file, that file will be compiled only once. The first process to call `require_file/2` will get the list of loaded modules, others will get `nil`. The list of required files is managed per Erlang VM node. See `compile_file/2` if you would like to compile a file without tracking its filenames. Finally, if you would like to get the result of evaluating a file rather than the modules defined in it, see `eval_file/2`. ### Examples - Code.require_file/2 (function) If the file has not been required, it returns the list of modules: modules = Code.require_file("eex_test.exs", "../eex/test") List.first(modules) #=> {EExTest.Compiled, <<70, 79, 82, 49, ...>>} If the file has been required, it returns `nil`: Code.require_file("eex_test.exs", "../eex/test") #=> nil ### Code.required_files/0 (function) Lists all required files. ### Examples - Code.required_files/0 (function) Code.require_file("../eex/test/eex_test.exs") List.first(Code.required_files()) =~ "eex_test.exs" #=> true ### Code.string_to_quoted/2 (function) Converts the given string to its quoted form. Returns `{:ok, quoted_form}` if it succeeds, `{:error, {meta, message_info, token}}` otherwise. ### Options - Code.string_to_quoted/2 (function) * `:file` - the filename to be reported in case of parsing errors. Defaults to `"nofile"`. * `:line` - the starting line of the string being parsed. Defaults to 1. * `:column` - (since v1.11.0) the starting column of the string being parsed. Defaults to 1. * `:columns` - when `true`, attach a `:column` key to the quoted metadata. Defaults to `false`. * `:unescape` (since v1.10.0) - when `false`, preserves escaped sequences. For example, `"null byte\\t\\x00"` will be kept as is instead of being converted to a bitstring literal. Note if you set this option to false, the resulting AST is no longer valid, but it can be useful to analyze/transform source code, typically in combination with `quoted_to_algebra/2`. Defaults to `true`. * `:existing_atoms_only` - when `true`, raises an error when non-existing atoms are found by the tokenizer. Defaults to `false`. * `:token_metadata` (since v1.10.0) - when `true`, includes token-related metadata in the expression AST, such as metadata for `do` and `end` tokens, for closing tokens, end of expressions, as well as delimiters for sigils. See `t:Macro.metadata/0`. Defaults to `false`. * `:literal_encoder` (since v1.10.0) - how to encode literals in the AST. It must be a function that receives two arguments, the literal and its metadata, and it must return `{:ok, ast :: Macro.t}` or `{:error, reason :: binary}`. If you return anything than the literal itself as the `term`, then the AST is no longer valid. This option may still useful for textual analysis of the source code. * `:static_atoms_encoder` - the static atom encoder function, see "The `:static_atoms_encoder` function" section below. Note this option overrides the `:existing_atoms_only` behavior for static atoms but `:existing_atoms_only` is still used for dynamic atoms, such as atoms with interpolations. * `:emit_warnings` (since v1.16.0) - when `false`, does not emit tokenizing/parsing related warnings. Defaults to `true`. ## `Macro.to_string/2` The opposite of converting a string to its quoted form is `Macro.to_string/2`, which converts a quoted form to a string/binary representation. ### The `:static_atoms_encoder` function - Code.string_to_quoted/2 (function) When `static_atoms_encoder: &my_encoder/2` is passed as an argument, `my_encoder/2` is called every time the tokenizer needs to create a "static" atom. Static atoms are atoms in the AST that function as aliases, remote calls, local calls, variable names, regular atoms and keyword lists. The encoder function will receive the atom name (as a binary) and a keyword list with the current file, line and column. It must return `{:ok, token :: term} | {:error, reason :: binary}`. The encoder function is supposed to create an atom from the given string. To produce a valid AST, it is required to return `{:ok, term}`, where `term` is an atom. It is possible to return something other than an atom, however, in that case the AST is no longer "valid" in that it cannot be used to compile or evaluate Elixir code. A use case for this is if you want to use the Elixir parser in a user-facing situation, but you don't want to exhaust the atom table. The atom encoder is not called for *all* atoms that are present in the AST. It won't be invoked for the following atoms: * operators (`:+`, `:-`, and so on) * syntax keywords (`fn`, `do`, `else`, and so on) * atoms containing interpolation (`:"#{1 + 1} is two"`), as these atoms are constructed at runtime * atoms used to represent single-letter sigils like `:sigil_X` (but multi-letter sigils like `:sigil_XYZ` are encoded). ### Code.string_to_quoted!/2 (function) Converts the given string to its quoted form. It returns the AST if it succeeds, raises an exception otherwise. The exception is a `TokenMissingError` in case a token is missing (usually because the expression is incomplete), `MismatchedDelimiterError` (in case of mismatched opening and closing delimiters) and `SyntaxError` otherwise. Check `string_to_quoted/2` for options information. ### Code.string_to_quoted_with_comments/2 (function) Converts the given string to its quoted form and a list of comments. This function is useful when performing textual changes to the source code, while preserving information like comments and literals position. Returns `{:ok, quoted_form, comments}` if it succeeds, `{:error, {line, error, token}}` otherwise. Comments are maps with the following fields: * `:line` - The line number of the source code * `:text` - The full text of the comment, including the leading `#` * `:previous_eol_count` - How many end of lines there are between the comment and the previous AST node or comment * `:next_eol_count` - How many end of lines there are between the comment and the next AST node or comment Check `string_to_quoted/2` for options information. ### Examples - Code.string_to_quoted_with_comments/2 (function) iex> Code.string_to_quoted_with_comments(""" ...> :foo ...> ...> # Hello, world! ...> ...> ...> # Some more comments! ...> """) {:ok, :foo, [ %{line: 3, column: 1, previous_eol_count: 2, next_eol_count: 3, text: "# Hello, world!"}, %{line: 6, column: 1, previous_eol_count: 3, next_eol_count: 1, text: "# Some more comments!"}, ]} iex> Code.string_to_quoted_with_comments(":foo # :bar") {:ok, :foo, [ %{line: 1, column: 6, previous_eol_count: 0, next_eol_count: 0, text: "# :bar"} ]} ### Code.string_to_quoted_with_comments!/2 (function) Converts the given string to its quoted form and a list of comments. Returns the AST and a list of comments if it succeeds, raises an exception otherwise. The exception is a `TokenMissingError` in case a token is missing (usually because the expression is incomplete), `SyntaxError` otherwise. Check `string_to_quoted/2` for options information. ### Code.unrequire_files/1 (function) Removes files from the required files list. The modules defined in the file are not removed; calling this function only removes them from the list, allowing them to be required again. The list of files is managed per Erlang VM node. ### Examples - Code.unrequire_files/1 (function) # Require EEx test code Code.require_file("../eex/test/eex_test.exs") # Now unrequire all files Code.unrequire_files(Code.required_files()) # Note that modules are still available function_exported?(EExTest.Compiled, :before_compile, 0) #=> true ### Code.with_diagnostics/2 (function) Executes the given `fun` and capture all diagnostics. Diagnostics are warnings and errors emitted during code evaluation or single-file compilation and by functions such as `IO.warn/2`. If using `mix compile` or `Kernel.ParallelCompiler`, note they already capture and return diagnostics. ### Options - Code.with_diagnostics/2 (function) * `:log` - if the diagnostics should be logged as they happen. Defaults to `false`. > #### Rescuing errors {: .info} > > `with_diagnostics/2` does not automatically handle exceptions. > You may capture them by adding a `try/1` in `fun`: > > {result, all_errors_and_warnings} = > Code.with_diagnostics(fn -> > try do > {:ok, Code.compile_quoted(quoted)} > rescue > err -> {:error, err} > end > end) ### Code.binding/0 (type) A list with all variables and their values. The binding keys are usually atoms, but they may be a tuple for variables defined in a different context. ### Code.diagnostic/1 (type) Diagnostics returned by the compiler and code evaluation. The file and position relate to where the diagnostic should be shown. If there is a file and position, then the diagnostic is precise and you can use the given file and position for generating snippets, IDEs annotations, and so on. An optional span is available with the line and column the diagnostic ends. Otherwise, a stacktrace may be given, which you can place your own heuristics to provide better reporting. The source field points to the source file the compiler tracked the error to. For example, a file `lib/foo.ex` may embed `.eex` templates from `lib/foo/bar.eex`. A syntax error on the EEx template will point to file `lib/foo/bar.eex` but the source is `lib/foo.ex`. ### Code.line/0 (type) The line. 0 indicates no line. ### Code.position/0 (type) The position of the diagnostic. Can be either a line number or a `{line, column}`. Line and columns numbers are one-based. A position of `0` represents unknown. ### Code.Fragment (module) This module provides conveniences for analyzing fragments of textual code and extract available information whenever possible. This module should be considered experimental. ### Code.Fragment.container_cursor_to_quoted/2 (function) Receives a string and returns a quoted expression with the cursor AST position within its parent expression. This function receives a string with an Elixir code fragment, representing a cursor position, and converts such string to AST with the inclusion of special `__cursor__()` node representing the cursor position within its container (i.e. its parent). For example, take this code, which would be given as input: max(some_value, This function will return the AST equivalent to: max(some_value, __cursor__()) In other words, this function is capable of closing any open brackets and insert the cursor position. Other content at the cursor position which is not a parent is discarded. For example, if this is given as input: max(some_value, another_val It will return the same AST: max(some_value, __cursor__()) Similarly, if only this is given: max(some_va Then it returns: max(__cursor__()) Calls without parenthesis are also supported, as we assume the brackets are implicit. Tuples, lists, maps, and binaries all retain the cursor position: max(some_value, [1, 2, Returns the following AST: max(some_value, [1, 2, __cursor__()]) Keyword lists (and do-end blocks) are also retained. The following: if(some_value, do: if(some_value, do: :token if(some_value, do: 1 + val all return: if(some_value, do: __cursor__()) For multi-line blocks, all previous lines are preserved. The AST returned by this function is not safe to evaluate but it can be analyzed and expanded. ### Examples - Code.Fragment.container_cursor_to_quoted/2 (function) Function call: iex> Code.Fragment.container_cursor_to_quoted("max(some_value, ") {:ok, {:max, [line: 1], [{:some_value, [line: 1], nil}, {:__cursor__, [line: 1], []}]}} Containers (for example, a list): iex> Code.Fragment.container_cursor_to_quoted("[some, value") {:ok, [{:some, [line: 1], nil}, {:__cursor__, [line: 1], []}]} If an expression is complete, then the whole expression is discarded and only the parent is returned: iex> Code.Fragment.container_cursor_to_quoted("if(is_atom(var)") {:ok, {:if, [line: 1], [{:__cursor__, [line: 1], []}]}} this means complete expressions themselves return only the cursor: iex> Code.Fragment.container_cursor_to_quoted("if(is_atom(var))") {:ok, {:__cursor__, [line: 1], []}} Operators are also included from Elixir v1.15: iex> Code.Fragment.container_cursor_to_quoted("foo +") {:ok, {:+, [line: 1], [{:foo, [line: 1], nil}, {:__cursor__, [line: 1], []}]}} In order to parse the left-side of `->` properly, which appears both in anonymous functions and do-end blocks, the trailing fragment option must be given with the rest of the contents: iex> Code.Fragment.container_cursor_to_quoted("fn x", trailing_fragment: " -> :ok end") {:ok, {:fn, [line: 1], [{:->, [line: 1], [[{:__cursor__, [line: 1], []}], :ok]}]}} ### Options - Code.Fragment.container_cursor_to_quoted/2 (function) * `:file` - the filename to be reported in case of parsing errors. Defaults to `"nofile"`. * `:line` - the starting line of the string being parsed. Defaults to 1. * `:column` - the starting column of the string being parsed. Defaults to 1. * `:columns` - when `true`, attach a `:column` key to the quoted metadata. Defaults to `false`. * `:token_metadata` - when `true`, includes token-related metadata in the expression AST, such as metadata for `do` and `end` tokens, for closing tokens, end of expressions, as well as delimiters for sigils. See `t:Macro.metadata/0`. Defaults to `false`. * `:literal_encoder` - a function to encode literals in the AST. See the documentation for `Code.string_to_quoted/2` for more information. * `:trailing_fragment` (since v1.18.0) - the rest of the contents after the cursor. This is necessary to correctly complete anonymous functions and the left-hand side of `->` ### Code.Fragment.cursor_context/2 (function) Receives a string and returns the cursor context. This function receives a string with an Elixir code fragment, representing a cursor position, and based on the string, it provides contextual information about the latest token. The return of this function can then be used to provide tips, suggestions, and autocompletion functionality. This function performs its analyses on tokens. This means it does not understand how constructs are nested within each other. See the "Limitations" section below. Consider adding a catch-all clause when handling the return type of this function as new cursor information may be added in future releases. ### Examples - Code.Fragment.cursor_context/2 (function) iex> Code.Fragment.cursor_context("") :expr iex> Code.Fragment.cursor_context("hello_wor") {:local_or_var, ~c"hello_wor"} ### Return values - Code.Fragment.cursor_context/2 (function) * `{:alias, charlist}` - the context is an alias, potentially a nested one, such as `Hello.Wor` or `HelloWor` * `{:alias, inside_alias, charlist}` - the context is an alias, potentially a nested one, where `inside_alias` is an expression `{:module_attribute, charlist}` or `{:local_or_var, charlist}` and `charlist` is a static part Examples are `__MODULE__.Submodule` or `@hello.Submodule` * `{:dot, inside_dot, charlist}` - the context is a dot where `inside_dot` is either a `{:var, charlist}`, `{:alias, charlist}`, `{:module_attribute, charlist}`, `{:unquoted_atom, charlist}` or a `dot` itself. If a var is given, this may either be a remote call or a map field access. Examples are `Hello.wor`, `:hello.wor`, `hello.wor`, `Hello.nested.wor`, `hello.nested.wor`, and `@hello.world`. If `charlist` is empty and `inside_dot` is an alias, then the autocompletion may either be an alias or a remote call. * `{:dot_arity, inside_dot, charlist}` - the context is a dot arity where `inside_dot` is either a `{:var, charlist}`, `{:alias, charlist}`, `{:module_attribute, charlist}`, `{:unquoted_atom, charlist}` or a `dot` itself. If a var is given, it must be a remote arity. Examples are `Hello.world/`, `:hello.world/`, `hello.world/2`, and `@hello.world/2` * `{:dot_call, inside_dot, charlist}` - the context is a dot call. This means parentheses or space have been added after the expression. where `inside_dot` is either a `{:var, charlist}`, `{:alias, charlist}`, `{:module_attribute, charlist}`, `{:unquoted_atom, charlist}` or a `dot` itself. If a var is given, it must be a remote call. Examples are `Hello.world(`, `:hello.world(`, `Hello.world `, `hello.world(`, `hello.world `, and `@hello.world(` * `:expr` - may be any expression. Autocompletion may suggest an alias, local or var * `{:local_or_var, charlist}` - the context is a variable or a local (import or local) call, such as `hello_wor` * `{:local_arity, charlist}` - the context is a local (import or local) arity, such as `hello_world/` * `{:local_call, charlist}` - the context is a local (import or local) call, such as `hello_world(` and `hello_world ` * `{:anonymous_call, inside_caller}` - the context is an anonymous call, such as `fun.(` and `@fun.(`. * `{:module_attribute, charlist}` - the context is a module attribute, such as `@hello_wor` * `{:operator, charlist}` - the context is an operator, such as `+` or `==`. Note textual operators, such as `when` do not appear as operators but rather as `:local_or_var`. `@` is never an `:operator` and always a `:module_attribute` * `{:operator_arity, charlist}` - the context is an operator arity, which is an operator followed by /, such as `+/`, `not/` or `when/` * `{:operator_call, charlist}` - the context is an operator call, which is an operator followed by space, such as `left + `, `not ` or `x when ` * `:none` - no context possible * `{:sigil, charlist}` - the context is a sigil. It may be either the beginning of a sigil, such as `~` or `~s`, or an operator starting with `~`, such as `~>` and `~>>` * `{:struct, inside_struct}` - the context is a struct, such as `%`, `%UR` or `%URI`. `inside_struct` can either be a `charlist` in case of a static alias or an expression `{:alias, inside_alias, charlist}`, `{:module_attribute, charlist}`, `{:local_or_var, charlist}`, `{:dot, inside_dot, charlist}` * `{:unquoted_atom, charlist}` - the context is an unquoted atom. This can be any atom or an atom representing a module We recommend looking at the test suite of this function for a complete list of examples and their return values. ### Limitations - Code.Fragment.cursor_context/2 (function) The analysis is based on the current token, by analysing the last line of the input. For example, this code: iex> Code.Fragment.cursor_context("%URI{") :expr returns `:expr`, which suggests any variable, local function or alias could be used. However, given we are inside a struct, the best suggestion would be a struct field. In such cases, you can use `container_cursor_to_quoted`, which will return the container of the AST the cursor is currently within. You can then analyse this AST to provide completion of field names. As a consequence of its token-based implementation, this function considers only the last line of the input. This means it will show suggestions inside strings, heredocs, etc, which is intentional as it helps with doctests, references, and more. ### Code.Fragment.surround_context/3 (function) Receives a string and returns the surround context. This function receives a string with an Elixir code fragment and a `position`. It returns a map containing the beginning and ending of the identifier alongside its context, or `:none` if there is nothing with a known context. This is useful to provide mouse-over and highlight functionality in editors. The difference between `cursor_context/2` and `surround_context/3` is that the former assumes the expression in the code fragment is incomplete. For example, `do` in `cursor_context/2` may be a keyword or a variable or a local call, while `surround_context/3` assumes the expression in the code fragment is complete, therefore `do` would always be a keyword. The `position` contains both the `line` and `column`, both starting with the index of 1. The column must precede the surrounding expression. For example, the expression `foo`, will return something for the columns 1, 2, and 3, but not 4: foo ^ column 1 foo ^ column 2 foo ^ column 3 foo ^ column 4 The returned map contains the column the expression starts and the first column after the expression ends. Similar to `cursor_context/2`, this function is also token-based and may not be accurate under all circumstances. See the "Return values" and "Limitations" section under `cursor_context/2` for more information. ### Examples - Code.Fragment.surround_context/3 (function) iex> Code.Fragment.surround_context("foo", {1, 1}) %{begin: {1, 1}, context: {:local_or_var, ~c"foo"}, end: {1, 4}} ### Differences to `cursor_context/2` - Code.Fragment.surround_context/3 (function) Because `surround_context/3` attempts to capture complex expressions, it has some differences to `cursor_context/2`: * `dot_call`/`dot_arity` and `operator_call`/`operator_arity` are collapsed into `dot` and `operator` contexts respectively as there aren't any meaningful distinctions between them * On the other hand, this function still makes a distinction between `local_call`/`local_arity` and `local_or_var`, since the latter can be a local or variable * `@` when not followed by any identifier is returned as `{:operator, ~c"@"}` (in contrast to `{:module_attribute, ~c""}` in `cursor_context/2` * This function never returns empty sigils `{:sigil, ~c""}` or empty structs `{:struct, ~c""}` as context * This function returns keywords as `{:keyword, ~c"do"}` * This function never returns `:expr` We recommend looking at the test suite of this function for a complete list of examples and their return values. ### Code.Fragment.position/0 (type) ### Kernel.ParallelCompiler (module) A module responsible for compiling and requiring files in parallel. ### Kernel.ParallelCompiler.async/1 (function) Starts a task for parallel compilation. ### Kernel.ParallelCompiler.compile/2 (function) Compiles the given files. Those files are compiled in parallel and can automatically detect dependencies between them. Once a dependency is found, the current file stops being compiled until the dependency is resolved. It returns `{:ok, modules, warnings}` or `{:error, errors, warnings}` by default but we recommend using `return_diagnostics: true` so it returns diagnostics as maps as well as a map of compilation information. The map has the shape of: %{ runtime_warnings: [warning], compile_warnings: [warning] } ### Options - Kernel.ParallelCompiler.compile/2 (function) * `:each_file` - for each file compiled, invokes the callback passing the file * `:each_long_compilation` - for each file that takes more than a given timeout (see the `:long_compilation_threshold` option) to compile, invoke this callback passing the file as its argument * `:each_module` - for each module compiled, invokes the callback passing the file, module and the module bytecode * `:each_cycle` - after the given files are compiled, invokes this function that should return the following values: * `{:compile, modules, warnings}` - to continue compilation with a list of further modules to compile * `{:runtime, modules, warnings}` - to stop compilation and verify the list of modules because dependent modules have changed * `:long_compilation_threshold` - the timeout (in seconds) to check for modules taking too long to compile. For each file that exceeds the threshold, the `:each_long_compilation` callback is invoked. From Elixir v1.11, only the time spent compiling the actual module is taken into account by the threshold, the time spent waiting is not considered. Defaults to `10` seconds. * `:profile` - if set to `:time` measure the compilation time of each compilation cycle and group pass checker * `:dest` - the destination directory for the BEAM files. When using `compile/2`, this information is only used to properly annotate the BEAM files before they are loaded into memory. If you want a file to actually be written to `dest`, use `compile_to_path/3` instead. * `:beam_timestamp` - the modification timestamp to give all BEAM files * `:return_diagnostics` (since v1.15.0) - returns maps with information instead of a list of warnings and returns diagnostics as maps instead of tuples * `:max_concurrency` - the maximum number of files to compile in parallel. Setting this option to 1 will compile files sequentially. Defaults to the number of schedulers online, or at least 2. ### Kernel.ParallelCompiler.compile_to_path/3 (function) Compiles the given files and writes resulting BEAM files into path. See `compile/2` for more information. ### Kernel.ParallelCompiler.pmap/2 (function) Perform parallel compilation of `collection` with `fun`. If you have a file that needs to compile other modules in parallel, the spawned processes need to be aware of the compiler environment. This function allows a developer to perform such tasks. ### Kernel.ParallelCompiler.require/2 (function) Requires the given files in parallel. Opposite to compile, dependencies are not attempted to be automatically solved between files. It returns `{:ok, modules, warnings}` or `{:error, errors, warnings}` by default but we recommend using `return_diagnostics: true` so it returns diagnostics as maps as well as a map of compilation information. The map has the shape of: %{ runtime_warnings: [warning], compile_warnings: [warning] } ### Options - Kernel.ParallelCompiler.require/2 (function) * `:each_file` - for each file compiled, invokes the callback passing the file * `:each_module` - for each module compiled, invokes the callback passing the file, module and the module bytecode * `:max_concurrency` - the maximum number of files to compile in parallel. Setting this option to 1 will compile files sequentially. Defaults to the number of schedulers online, or at least 2. ### Kernel.ParallelCompiler.error/0 (type) ### Kernel.ParallelCompiler.info/0 (type) ### Kernel.ParallelCompiler.warning/0 (type) ### Macro (module) Functions for manipulating AST and implementing macros. Macros are compile-time constructs that receive Elixir's AST as input and return Elixir's AST as output. Many of the functions in this module exist precisely to work with Elixir AST, to traverse, query, and transform it. Let's see a simple example that shows the difference between functions and macros: defmodule Example do defmacro macro_inspect(value) do IO.inspect(value) value end def fun_inspect(value) do IO.inspect(value) value end end Now let's give it a try: import Example macro_inspect(1) #=> 1 #=> 1 fun_inspect(1) #=> 1 #=> 1 So far they behave the same, as we are passing an integer as argument. But let's see what happens when we pass an expression: macro_inspect(1 + 2) #=> {:+, [line: 3], [1, 2]} #=> 3 fun_inspect(1 + 2) #=> 3 #=> 3 The macro receives the representation of the code given as argument, while a function receives the result of the code given as argument. A macro must return a superset of the code representation. See `t:input/0` and `t:output/0` for more information. To learn more about Elixir's AST and how to build them programmatically, see `quote/2`. > #### Evaluating code {: .tip} > > The functions in this module do not evaluate code. In fact, > evaluating code from macros is often an anti-pattern. For code > evaluation, see the `Code` module. ### Macro.camelize/1 (function) Converts the given string to CamelCase format. This function was designed to camelize language identifiers/tokens, that's why it belongs to the `Macro` module. Do not use it as a general mechanism for camelizing strings as it does not support Unicode or characters that are not valid in Elixir identifiers. ### Examples - Macro.camelize/1 (function) iex> Macro.camelize("foo_bar") "FooBar" iex> Macro.camelize("foo/bar") "Foo.Bar" If uppercase characters are present, they are not modified in any way as a mechanism to preserve acronyms: iex> Macro.camelize("API.V1") "API.V1" iex> Macro.camelize("API_SPEC") "API_SPEC" ### Macro.classify_atom/1 (function) Classifies an `atom` based on its possible AST placement. It returns one of the following atoms: * `:alias` - the atom represents an alias * `:identifier` - the atom can be used as a variable or local function call (as well as be an unquoted atom) * `:unquoted` - the atom can be used in its unquoted form, includes operators and atoms with `@` in them * `:quoted` - all other atoms which can only be used in their quoted form Most operators are going to be `:unquoted`, such as `:+`, with some exceptions returning `:quoted` due to ambiguity, such as `:"::"`. Use `operator?/2` to check if a given atom is an operator. ### Examples - Macro.classify_atom/1 (function) iex> Macro.classify_atom(:foo) :identifier iex> Macro.classify_atom(Foo) :alias iex> Macro.classify_atom(:foo@bar) :unquoted iex> Macro.classify_atom(:+) :unquoted iex> Macro.classify_atom(:Foo) :unquoted iex> Macro.classify_atom(:"with spaces") :quoted ### Macro.compile_apply/4 (function) Applies a `mod`, `function`, and `args` at compile-time in `caller`. This is used when you want to programmatically invoke a macro at compile-time. ### Macro.dbg/3 (function) Default backend for `Kernel.dbg/2`. This function provides a default backend for `Kernel.dbg/2`. See the `Kernel.dbg/2` documentation for more information. This function: * prints information about the given `env` * prints information about `code` and its returned value (using `opts` to inspect terms) * returns the value returned by evaluating `code` You can call this function directly to build `Kernel.dbg/2` backends that fall back to this function. This function raises if the context of the given `env` is `:match` or `:guard`. ### Macro.decompose_call/1 (function) Decomposes a local or remote call into its remote part (when provided), function name and argument list. Returns `:error` when an invalid call syntax is provided. ### Examples - Macro.decompose_call/1 (function) iex> Macro.decompose_call(quote(do: foo)) {:foo, []} iex> Macro.decompose_call(quote(do: foo())) {:foo, []} iex> Macro.decompose_call(quote(do: foo(1, 2, 3))) {:foo, [1, 2, 3]} iex> Macro.decompose_call(quote(do: Elixir.M.foo(1, 2, 3))) {{:__aliases__, [], [:Elixir, :M]}, :foo, [1, 2, 3]} iex> Macro.decompose_call(quote(do: 42)) :error iex> Macro.decompose_call(quote(do: {:foo, [], []})) :error ### Macro.escape/2 (function) Recursively escapes a value so it can be inserted into a syntax tree. ### Examples - Macro.escape/2 (function) iex> Macro.escape(:foo) :foo iex> Macro.escape({:a, :b, :c}) {:{}, [], [:a, :b, :c]} iex> Macro.escape({:unquote, [], [1]}, unquote: true) 1 ### Options - Macro.escape/2 (function) * `:unquote` - when `true`, this function leaves `unquote/1` and `unquote_splicing/1` expressions unescaped, effectively unquoting the contents on escape. This option is useful only when escaping ASTs which may have quoted fragments in them. Defaults to `false`. * `:prune_metadata` - when `true`, removes most metadata from escaped AST nodes. Note this option changes the semantics of escaped code and it should only be used when escaping ASTs. Defaults to `false`. As an example for `:prune_metadata`, `ExUnit` stores the AST of every assertion, so when an assertion fails we can show code snippets to users. Without this option, each time the test module is compiled, we would get a different MD5 of the module bytecode, because the AST contains metadata, such as counters, specific to the compilation environment. By pruning the metadata, we ensure that the module is deterministic and reduce the amount of data `ExUnit` needs to keep around. Only the minimal amount of metadata is kept, such as `:line`, `:no_parens` and `:delimiter`. ### Comparison to `quote/2` - Macro.escape/2 (function) The `escape/2` function is sometimes confused with `quote/2`, because the above examples behave the same with both. The key difference is best illustrated when the value to escape is stored in a variable. iex> Macro.escape({:a, :b, :c}) {:{}, [], [:a, :b, :c]} iex> quote do: {:a, :b, :c} {:{}, [], [:a, :b, :c]} iex> value = {:a, :b, :c} iex> Macro.escape(value) {:{}, [], [:a, :b, :c]} iex> quote do: value {:value, [], __MODULE__} iex> value = {:a, :b, :c} iex> quote do: unquote(value) ** (ArgumentError) tried to unquote invalid AST: {:a, :b, :c} Did you forget to escape term using Macro.escape/1? `escape/2` is used to escape *values* (either directly passed or variable bound), while `quote/2` produces syntax trees for expressions. ### Macro.expand/2 (function) Receives an AST node and expands it until it can no longer be expanded. Note this function does not traverse the AST, only the root node is expanded. This function uses `expand_once/2` under the hood. Check it out for more information and examples. ### Macro.expand_literals/2 (function) Expands all literals in `ast` with the given `env`. This function is mostly used to remove compile-time dependencies from AST nodes. In such cases, the given environment is usually manipulated to represent a function: Macro.expand_literals(ast, %{env | function: {:my_code, 1}}) At the moment, the only expandable literal nodes in an AST are aliases, so this function only expands aliases (and it does so anywhere in a literal). However, be careful when removing compile-time dependencies between modules. If you remove them but you still invoke the module at compile-time, Elixir will be unable to properly recompile modules when they change. ### Macro.expand_literals/3 (function) Expands all literals in `ast` with the given `acc` and `fun`. `fun` will be invoked with an expandable AST node and `acc` and must return a new node with `acc`. This is a general version of `expand_literals/2` which supports a custom expansion function. Please check `expand_literals/2` for use cases and pitfalls. ### Macro.expand_once/2 (function) Receives an AST node and expands it once. The following contents are expanded: * Macros (local or remote) * Aliases are expanded (if possible) and return atoms * Compilation environment macros (`__CALLER__/0`, `__DIR__/0`, `__ENV__/0` and `__MODULE__/0`) * Module attributes reader (`@foo`) If the expression cannot be expanded, it returns the expression itself. This function does not traverse the AST, only the root node is expanded. The expansion happens as if it was expanded by the Elixir compiler and therefore compilation tracers will be invoked and deprecation warnings will be emitted during the expansion. `expand_once/2` performs the expansion just once. Check `expand/2` to perform expansion until the node can no longer be expanded. ### Examples - Macro.expand_once/2 (function) In the example below, we have a macro that generates a module with a function named `name_length` that returns the length of the module name. The value of this function will be calculated at compilation time and not at runtime. Consider the implementation below: defmacro defmodule_with_length(name, do: block) do length = length(Atom.to_charlist(name)) quote do defmodule unquote(name) do def name_length, do: unquote(length) unquote(block) end end end When invoked like this: defmodule_with_length My.Module do def other_function, do: ... end The compilation will fail because `My.Module` when quoted is not an atom, but a syntax tree as follows: {:__aliases__, [], [:My, :Module]} That said, we need to expand the aliases node above to an atom, so we can retrieve its length. Expanding the node is not straightforward because we also need to expand the caller aliases. For example: alias MyHelpers, as: My defmodule_with_length My.Module do def other_function, do: ... end The final module name will be `MyHelpers.Module` and not `My.Module`. With `Macro.expand/2`, such aliases are taken into consideration. Local and remote macros are also expanded. We could rewrite our macro above to use this function as: defmacro defmodule_with_length(name, do: block) do expanded = Macro.expand(name, __CALLER__) length = length(Atom.to_charlist(expanded)) quote do defmodule unquote(name) do def name_length, do: unquote(length) unquote(block) end end end ### Macro.generate_arguments/2 (function) Generates AST nodes for a given number of required argument variables using `Macro.var/2`. Note the arguments are not unique. If you later on want to access the same variables, you can invoke this function with the same inputs. Use `generate_unique_arguments/2` to generate unique arguments that can't be overridden. ### Examples - Macro.generate_arguments/2 (function) iex> Macro.generate_arguments(2, __MODULE__) [{:arg1, [], __MODULE__}, {:arg2, [], __MODULE__}] ### Macro.generate_unique_arguments/2 (function) Generates AST nodes for a given number of required argument variables using `Macro.unique_var/2`. ### Examples - Macro.generate_unique_arguments/2 (function) iex> [var1, var2] = Macro.generate_unique_arguments(2, __MODULE__) iex> {:arg1, [counter: c1], __MODULE__} = var1 iex> {:arg2, [counter: c2], __MODULE__} = var2 iex> is_integer(c1) and is_integer(c2) true ### Macro.inspect_atom/3 (function) Inspects `atom` according to different source formats. The atom can be inspected according to the three different formats it appears in the AST: as a literal (`:literal`), as a key (`:key`), or as the function name of a remote call (`:remote_call`). ### Options - Macro.inspect_atom/3 (function) * `:escape` - a two-arity function used to escape a quoted atom content, if necessary. The function receives the atom content as string and a quote delimiter character, which should always be escaped. By default the content is escaped such that the inspected sequence would be parsed as the given atom. ### Examples - Macro.inspect_atom/3 (function) ### As a literal - Macro.inspect_atom/3 (function) Literals include regular atoms, quoted atoms, operators, aliases, and the special `nil`, `true`, and `false` atoms. iex> Macro.inspect_atom(:literal, nil) "nil" iex> Macro.inspect_atom(:literal, :foo) ":foo" iex> Macro.inspect_atom(:literal, :<>) ":<>" iex> Macro.inspect_atom(:literal, :Foo) ":Foo" iex> Macro.inspect_atom(:literal, Foo.Bar) "Foo.Bar" iex> Macro.inspect_atom(:literal, :"with spaces") ":\"with spaces\"" ### As a key - Macro.inspect_atom/3 (function) Inspect an atom as a key of a keyword list or a map. iex> Macro.inspect_atom(:key, :foo) "foo:" iex> Macro.inspect_atom(:key, :<>) "<>:" iex> Macro.inspect_atom(:key, :Foo) "Foo:" iex> Macro.inspect_atom(:key, :"with spaces") "\"with spaces\":" ### As a remote call - Macro.inspect_atom/3 (function) Inspect an atom the function name of a remote call. iex> Macro.inspect_atom(:remote_call, :foo) "foo" iex> Macro.inspect_atom(:remote_call, :<>) "<>" iex> Macro.inspect_atom(:remote_call, :Foo) "\"Foo\"" iex> Macro.inspect_atom(:remote_call, :"with spaces") "\"with spaces\"" ### Macro.operator?/2 (function) Returns `true` if the given name and arity is an operator. ### Examples - Macro.operator?/2 (function) iex> Macro.operator?(:not_an_operator, 3) false iex> Macro.operator?(:.., 0) true iex> Macro.operator?(:+, 1) true iex> Macro.operator?(:++, 2) true iex> Macro.operator?(:..//, 3) true ### Macro.path/2 (function) Returns the path to the node in `ast` for which `fun` returns a truthy value. The path is a list, starting with the node in which `fun` returns a truthy value, followed by all of its parents. Returns `nil` if `fun` returns only falsy values. Computing the path can be an efficient operation when you want to find a particular node in the AST within its context and then assert something about it. ### Examples - Macro.path/2 (function) iex> Macro.path(quote(do: [1, 2, 3]), & &1 == 3) [3, [1, 2, 3]] iex> Macro.path(quote(do: [1, 2]), & &1 == 5) nil iex> Macro.path(quote(do: Foo.bar(3)), & &1 == 3) [3, quote(do: Foo.bar(3))] iex> Macro.path(quote(do: %{foo: [bar: :baz]}), & &1 == :baz) [ :baz, {:bar, :baz}, [bar: :baz], {:foo, [bar: :baz]}, {:%{}, [], [foo: [bar: :baz]]} ] ### Macro.pipe/3 (function) Pipes `expr` into the `call_args` at the given `position`. This function can be used to implement `|>` like functionality. For example, `|>` itself is implemented as: defmacro left |> right do Macro.pipe(left, right, 0) end `expr` is the AST of an expression. `call_args` must be the AST *of a call*, otherwise this function will raise an error. As an example, consider the pipe operator `|>/2`, which uses this function to build pipelines. Even if the expression is piped into the AST, it doesn't necessarily mean that the AST is valid. For example, you could pipe an argument to `div/2`, effectively turning it into a call to `div/3`, which is a function that doesn't exist by default. The code will raise unless a `div/3` function is locally defined. ### Macro.postwalk/2 (function) This function behaves like `prewalk/2`, but performs a depth-first, post-order traversal of quoted expressions. ### Macro.postwalk/3 (function) This functions behaves like `prewalk/3`, but performs a depth-first, post-order traversal of quoted expressions using an accumulator. ### Macro.postwalker/1 (function) Returns an enumerable that traverses the `ast` in depth-first, post-order traversal. ### Examples - Macro.postwalker/1 (function) iex> ast = quote do: foo(1, "abc") iex> Enum.map(Macro.postwalker(ast), & &1) [1, "abc", {:foo, [], [1, "abc"]}] ### Macro.prewalk/2 (function) Performs a depth-first, pre-order traversal of quoted expressions. Returns a new AST where each node is the result of invoking `fun` on each corresponding node of `ast`. ### Examples - Macro.prewalk/2 (function) iex> ast = quote do: 5 + 3 * 7 iex> {:+, _, [5, {:*, _, [3, 7]}]} = ast iex> new_ast = Macro.prewalk(ast, fn ...> {:+, meta, children} -> {:*, meta, children} ...> {:*, meta, children} -> {:+, meta, children} ...> other -> other ...> end) iex> {:*, _, [5, {:+, _, [3, 7]}]} = new_ast iex> Code.eval_quoted(ast) {26, []} iex> Code.eval_quoted(new_ast) {50, []} ### Macro.prewalk/3 (function) Performs a depth-first, pre-order traversal of quoted expressions using an accumulator. Returns a tuple where the first element is a new AST where each node is the result of invoking `fun` on each corresponding node and the second one is the final accumulator. ### Examples - Macro.prewalk/3 (function) iex> ast = quote do: 5 + 3 * 7 iex> {:+, _, [5, {:*, _, [3, 7]}]} = ast iex> {new_ast, acc} = Macro.prewalk(ast, [], fn ...> {:+, meta, children}, acc -> {{:*, meta, children}, [:+ | acc]} ...> {:*, meta, children}, acc -> {{:+, meta, children}, [:* | acc]} ...> other, acc -> {other, acc} ...> end) iex> {{:*, _, [5, {:+, _, [3, 7]}]}, [:*, :+]} = {new_ast, acc} iex> Code.eval_quoted(ast) {26, []} iex> Code.eval_quoted(new_ast) {50, []} ### Macro.prewalker/1 (function) Returns an enumerable that traverses the `ast` in depth-first, pre-order traversal. ### Examples - Macro.prewalker/1 (function) iex> ast = quote do: foo(1, "abc") iex> Enum.map(Macro.prewalker(ast), & &1) [{:foo, [], [1, "abc"]}, 1, "abc"] ### Macro.quoted_literal?/1 (function) Returns `true` if the given quoted expression represents a quoted literal. Atoms and numbers are always literals. Binaries, lists, tuples, maps, and structs are only literals if all of their terms are also literals. ### Examples - Macro.quoted_literal?/1 (function) iex> Macro.quoted_literal?(quote(do: "foo")) true iex> Macro.quoted_literal?(quote(do: {"foo", 1})) true iex> Macro.quoted_literal?(quote(do: {"foo", 1, :baz})) true iex> Macro.quoted_literal?(quote(do: %{foo: "bar"})) true iex> Macro.quoted_literal?(quote(do: %URI{path: "/"})) true iex> Macro.quoted_literal?(quote(do: URI.parse("/"))) false iex> Macro.quoted_literal?(quote(do: {foo, var})) false ### Macro.special_form?/2 (function) Returns `true` if the given name and arity is a special form. ### Macro.struct!/2 (function) ### Macro.struct_info!/2 (function) Extracts the struct information (equivalent to calling `module.__info__(:struct)`). This is useful when a struct needs to be expanded at compilation time and the struct being expanded may or may not have been compiled. This function is also capable of expanding structs defined under the module being compiled. Calling this function also adds an export dependency on the given struct. It will raise `ArgumentError` if the struct is not available. ### Macro.to_string/1 (function) Converts the given expression AST to a string. This is a convenience function for converting AST into a string, which discards all formatting of the original code and wraps newlines around 98 characters. See `Code.quoted_to_algebra/2` as a lower level function with more control around formatting. If the AST contains invalid nodes, this function will attempt to inspect them, to aid debugging, although the elements won't be formatted accordingly. ### Examples - Macro.to_string/1 (function) iex> Macro.to_string(quote(do: foo.bar(1, 2, 3))) "foo.bar(1, 2, 3)" ### Macro.to_string/2 (function) Converts the given expression AST to a string. The given `fun` is called for every node in the AST with two arguments: the AST of the node being printed and the string representation of that same node. The return value of this function is used as the final string representation for that AST node. This function discards all formatting of the original code. ### Examples - Macro.to_string/2 (function) Macro.to_string(quote(do: 1 + 2), fn 1, _string -> "one" 2, _string -> "two" _ast, string -> string end) #=> "one + two" ### Macro.traverse/4 (function) Performs a depth-first traversal of quoted expressions using an accumulator. Returns a tuple where the first element is a new AST and the second one is the final accumulator. The new AST is the result of invoking `pre` on each node of `ast` during the pre-order phase and `post` during the post-order phase. ### Examples - Macro.traverse/4 (function) iex> ast = quote do: 5 + 3 * 7 iex> {:+, _, [5, {:*, _, [3, 7]}]} = ast iex> {new_ast, acc} = ...> Macro.traverse( ...> ast, ...> [], ...> fn ...> {:+, meta, children}, acc -> {{:-, meta, children}, [:- | acc]} ...> {:*, meta, children}, acc -> {{:/, meta, children}, [:/ | acc]} ...> other, acc -> {other, acc} ...> end, ...> fn ...> {:-, meta, children}, acc -> {{:min, meta, children}, [:min | acc]} ...> {:/, meta, children}, acc -> {{:max, meta, children}, [:max | acc]} ...> other, acc -> {other, acc} ...> end ...> ) iex> {:min, _, [5, {:max, _, [3, 7]}]} = new_ast iex> [:min, :max, :/, :-] = acc iex> Code.eval_quoted(new_ast) {5, []} ### Macro.underscore/1 (function) Converts the given argument to a string with the underscore-slash format. The argument must either be an atom, representing an Elixir module, or a string representing a module without the `Elixir.` prefix. This function was designed to format language identifiers/tokens with the underscore-slash format, that's why it belongs to the `Macro` module. Do not use it as a general mechanism for underscoring strings as it does not support Unicode or characters that are not valid in Elixir identifiers. ### Examples - Macro.underscore/1 (function) iex> Macro.underscore("FooBar") "foo_bar" iex> Macro.underscore("Foo.Bar") "foo/bar" iex> Macro.underscore(Foo.Bar) "foo/bar" In general, `underscore` can be thought of as the reverse of `camelize`, however, in some cases formatting may be lost: iex> Macro.underscore("SAPExample") "sap_example" iex> Macro.camelize("sap_example") "SapExample" iex> Macro.camelize("hello_10") "Hello10" iex> Macro.camelize("foo/bar") "Foo.Bar" ### Macro.unescape_string/1 (function) Unescapes characters in a string. This is the unescaping behaviour used by default in Elixir single- and double-quoted strings. Check `unescape_string/2` for information on how to customize the escaping map. In this setup, Elixir will escape the following: `\0`, `\a`, `\b`, `\d`, `\e`, `\f`, `\n`, `\r`, `\s`, `\t` and `\v`. Bytes can be given as hexadecimals via `\xNN` and Unicode code points as `\uNNNN` escapes. This function is commonly used on sigil implementations (like `~r`, `~s` and others), which receive a raw, unescaped string, and it can be used anywhere that needs to mimic how Elixir parses strings. ### Examples - Macro.unescape_string/1 (function) iex> Macro.unescape_string("example\\n") "example\n" In the example above, we pass a string with `\n` escaped and return a version with it unescaped. ### Macro.unescape_string/2 (function) Unescapes characters in a string according to the given mapping. Check `unescape_string/1` if you want to use the same mapping as Elixir single- and double-quoted strings. ### Mapping function - Macro.unescape_string/2 (function) The mapping function receives an integer representing the code point of the character it wants to unescape. There are also the special atoms `:newline`, `:unicode`, and `:hex`, which control newline, unicode, and escaping respectively. Here is the default mapping function implemented by Elixir: def unescape_map(:newline), do: true def unescape_map(:unicode), do: true def unescape_map(:hex), do: true def unescape_map(?0), do: ?0 def unescape_map(?a), do: ?\a def unescape_map(?b), do: ?\b def unescape_map(?d), do: ?\d def unescape_map(?e), do: ?\e def unescape_map(?f), do: ?\f def unescape_map(?n), do: ?\n def unescape_map(?r), do: ?\r def unescape_map(?s), do: ?\s def unescape_map(?t), do: ?\t def unescape_map(?v), do: ?\v def unescape_map(e), do: e If the `unescape_map/1` function returns `false`, the char is not escaped and the backslash is kept in the string. ### Examples - Macro.unescape_string/2 (function) Using the `unescape_map/1` function defined above is easy: Macro.unescape_string("example\\n", &unescape_map(&1)) ### Macro.unique_var/2 (function) Generates an AST node representing a unique variable given by the atoms `var` and `context`. Calling this function with the same arguments will generate another variable, with its own unique counter. See `var/2` for an alternative. ### Examples - Macro.unique_var/2 (function) iex> {:foo, [counter: c], __MODULE__} = Macro.unique_var(:foo, __MODULE__) iex> is_integer(c) true ### Macro.unpipe/1 (function) Breaks a pipeline expression into a list. The AST for a pipeline (a sequence of applications of `|>/2`) is similar to the AST of a sequence of binary operators or function applications: the top-level expression is the right-most `:|>` (which is the last one to be executed), and its left-hand and right-hand sides are its arguments: quote do: 100 |> div(5) |> div(2) #=> {:|>, _, [arg1, arg2]} In the example above, the `|>/2` pipe is the right-most pipe; `arg1` is the AST for `100 |> div(5)`, and `arg2` is the AST for `div(2)`. It's often useful to have the AST for such a pipeline as a list of function applications. This function does exactly that: Macro.unpipe(quote do: 100 |> div(5) |> div(2)) #=> [{100, 0}, {{:div, [], [5]}, 0}, {{:div, [], [2]}, 0}] We get a list that follows the pipeline directly: first the `100`, then the `div(5)` (more precisely, its AST), then `div(2)`. The `0` as the second element of the tuples is the position of the previous element in the pipeline inside the current function application: `{{:div, [], [5]}, 0}` means that the previous element (`100`) will be inserted as the 0th (first) argument to the `div/2` function, so that the AST for that function will become `{:div, [], [100, 5]}` (`div(100, 5)`). ### Macro.update_meta/2 (function) Applies the given function to the node metadata if it contains one. This is often useful when used with `Macro.prewalk/2` to remove information like lines and hygienic counters from the expression for either storage or comparison. ### Examples - Macro.update_meta/2 (function) iex> quoted = quote line: 10, do: sample() {:sample, [line: 10], []} iex> Macro.update_meta(quoted, &Keyword.delete(&1, :line)) {:sample, [], []} ### Macro.validate/1 (function) Validates the given expressions are valid quoted expressions. Check the type `t:Macro.t/0` for a complete specification of a valid quoted expression. It returns `:ok` if the expression is valid. Otherwise it returns a tuple in the form of `{:error, remainder}` where `remainder` is the invalid part of the quoted expression. ### Examples - Macro.validate/1 (function) iex> Macro.validate({:two_element, :tuple}) :ok iex> Macro.validate({:three, :element, :tuple}) {:error, {:three, :element, :tuple}} iex> Macro.validate([1, 2, 3]) :ok iex> Macro.validate([1, 2, 3, {4}]) {:error, {4}} ### Macro.var/2 (function) Generates an AST node representing the variable given by the atoms `var` and `context`. Note this variable is not unique. If you later on want to access this same variable, you can invoke `var/2` again with the same arguments. Use `unique_var/2` to generate a unique variable that can't be overridden. ### Examples - Macro.var/2 (function) In order to build a variable, a context is expected. Most of the times, in order to preserve hygiene, the context must be `__MODULE__/0`: iex> Macro.var(:foo, __MODULE__) {:foo, [], __MODULE__} However, if there is a need to access the user variable, nil can be given: iex> Macro.var(:foo, nil) {:foo, [], nil} ### Macro.captured_remote_function/0 (type) A captured remote function in the format of &Mod.fun/arity ### Macro.input/0 (type) The inputs of a macro ### Macro.metadata/0 (type) A keyword list of AST metadata. The metadata in Elixir AST is a keyword list of values. Any key can be used and different parts of the compiler may use different keys. For example, the AST received by a macro will always include the `:line` annotation, while the AST emitted by `quote/2` will only have the `:line` annotation if the `:line` option is provided. The following metadata keys are public: * `:context` - Defines the context in which the AST was generated. For example, `quote/2` will include the module calling `quote/2` as the context. This is often used to distinguish regular code from code generated by a macro or by `quote/2`. * `:counter` - The variable counter used for variable hygiene. In terms of the compiler, each variable is identified by the combination of either `name` and `metadata[:counter]`, or `name` and `context`. * `:from_brackets` - Used to determine whether a call to `Access.get/3` is from bracket syntax. * `:from_interpolation` - Used to determine whether a call to `Kernel.to_string/1` is from interpolation. * `:generated` - Whether the code should be considered as generated by the compiler or not. This means the compiler and tools like Dialyzer may not emit certain warnings. * `:if_undefined` - How to expand a variable that is undefined. Set it to `:apply` if you want a variable to become a nullary call without warning or `:raise` * `:keep` - Used by `quote/2` with the option `location: :keep` to annotate the file and the line number of the quoted source. * `:line` - The line number of the AST node. Note line information is discarded from quoted code but can be enabled back via the `:line` option. The following metadata keys are enabled by `Code.string_to_quoted/2`: * `:closing` - contains metadata about the closing pair, such as a `}` in a tuple or in a map, or such as the closing `)` in a function call with parens (when `:token_metadata` is true). If the function call has a do-end block attached to it, its metadata is found under the `:do` and `:end` metadata * `:column` - the column number of the AST node (when `:columns` is true). Note column information is always discarded from quoted code. * `:delimiter` - contains the opening delimiter for sigils, strings, and charlists as a string (such as `"{"`, `"/"`, `"'"`, and the like) * `:format` - set to `:keyword` when an atom is defined as a keyword * `:do` - contains metadata about the `do` location in a function call with `do`-`end` blocks (when `:token_metadata` is true) * `:end` - contains metadata about the `end` location in a function call with `do`-`end` blocks (when `:token_metadata` is true) * `:end_of_expression` - denotes when the end of expression effectively happens (when `:token_metadata` is true). This is only available for expressions inside "blocks of code", which are either direct children of a `__block__` or the right side of `->`. The last expression of the block does not have metadata if it is not followed by an end of line character (either a newline or `;`) * `:indentation` - indentation of a sigil heredoc The following metadata keys are private: * `:alias` - Used for alias hygiene. * `:ambiguous_op` - Used for improved error messages in the compiler. * `:imports` - Used for import hygiene. * `:var` - Used for improved error messages on undefined variables. Do not rely on them as they may change or be fully removed in future versions of the language. They are often used by `quote/2` and the compiler to provide features like hygiene, better error messages, and so forth. If you introduce custom keys into the AST metadata, please make sure to prefix them with the name of your library or application, so that they will not conflict with keys that could potentially be introduced by the compiler in the future. ### Macro.output/0 (type) The output of a macro ### Macro.t/0 (type) Abstract Syntax Tree (AST) ### Macro.Env (module) A struct that holds compile time environment information. The current environment can be accessed at any time as `__ENV__/0`. Inside macros, the caller environment can be accessed as `__CALLER__/0`. The majority of the functions in this module are provided for low-level tools, which need to integrate with the Elixir compiler, such as language servers and embedded languages. For regular usage in Elixir code and macros, you must use the `Macro` module instead. In particular, avoid modifying the `Macro.Env` struct directly and prefer to use high-level constructs, such as a `import`, `aliases`, and so forth to build your own environment. For example, to build a custom environment, you can define a function such as: def make_custom_env do import SomeModule, only: [some_function: 2], warn: false alias A.B.C, warn: false __ENV__ end ### Struct fields - Macro.Env (module) The `Macro.Env` struct contains the following fields: * `context` - the context of the environment; it can be `nil` (default context), `:guard` (inside a guard) or `:match` (inside a match) * `context_modules` - a list of modules defined in the current context * `file` - the current absolute file name as a binary * `function` - a tuple as `{atom, integer}`, where the first element is the function name and the second its arity; returns `nil` if not inside a function * `line` - the current line as an integer * `module` - the current module name The following fields are private to Elixir's macro expansion mechanism and must not be accessed directly: * `aliases` * `functions` * `macro_aliases` * `macros` * `lexical_tracker` * `requires` * `tracers` * `versioned_vars` ### Macro.Env.define_alias/4 (function) Defines the given `as` an alias to `module` in the environment. This is used by tools which need to mimic the Elixir compiler. The appropriate `:alias` compiler tracing event will be emitted. ### Additional options - Macro.Env.define_alias/4 (function) It accepts the same options as `Kernel.SpecialForm.alias/2` plus: * `:trace` - when set to `false`, it disables compilation tracers and lexical tracker. This option must only be used by language servers and other tools that need to introspect code without affecting how it is compiled. Disabling tracer inside macros or regular code expansion is extremely discouraged as it blocks the compiler from accurately tracking dependencies ### Examples - Macro.Env.define_alias/4 (function) iex> env = __ENV__ iex> Macro.Env.expand_alias(env, [], [:Baz]) :error iex> {:ok, env} = Macro.Env.define_alias(env, [line: 10], Foo.Bar, as: Baz) iex> Macro.Env.expand_alias(env, [], [:Baz]) {:alias, Foo.Bar} iex> Macro.Env.expand_alias(env, [], [:Baz, :Bat]) {:alias, Foo.Bar.Bat} If no `:as` option is given, the alias will be inferred from the module: iex> env = __ENV__ iex> {:ok, env} = Macro.Env.define_alias(env, [line: 10], Foo.Bar) iex> Macro.Env.expand_alias(env, [], [:Bar]) {:alias, Foo.Bar} If it is not possible to infer one, an error is returned: iex> Macro.Env.define_alias(__ENV__, [line: 10], :an_atom) {:error, "alias cannot be inferred automatically for module: :an_atom, " <> "please use the :as option. Implicit aliasing is only supported with Elixir modules"} ### Macro.Env.define_import/4 (function) Defines the given `module` as imported in the environment. It assumes `module` is available. This is used by tools which need to mimic the Elixir compiler. The appropriate `:import` compiler tracing event will be emitted. ### Additional options - Macro.Env.define_import/4 (function) It accepts the same options as `Kernel.SpecialForm.import/2` plus: * `:emit_warnings` - emit warnings found when defining imports * `:trace` - when set to `false`, it disables compilation tracers and lexical tracker. This option must only be used by language servers and other tools that need to introspect code without affecting how it is compiled. Disabling tracer inside macros or regular code expansion is extremely discouraged as it blocks the compiler from accurately tracking dependencies * `:info_callback` - a function to use instead of `c:Module.__info__/1`. The function will be invoked with `:functions` or `:macros` argument. It has to return a list of `{function, arity}` key value pairs. If it fails, it defaults to using module metadata based on `module_info/1`. ### Examples - Macro.Env.define_import/4 (function) iex> env = __ENV__ iex> Macro.Env.lookup_import(env, {:flatten, 1}) [] iex> {:ok, env} = Macro.Env.define_import(env, [line: 10], List) iex> Macro.Env.lookup_import(env, {:flatten, 1}) [{:function, List}] It accepts the same options as `Kernel.SpecialForm.import/2`: iex> env = __ENV__ iex> Macro.Env.lookup_import(env, {:is_odd, 1}) [] iex> {:ok, env} = Macro.Env.define_import(env, [line: 10], Integer, only: :macros) iex> Macro.Env.lookup_import(env, {:is_odd, 1}) [{:macro, Integer}] ### Info callback override - Macro.Env.define_import/4 (function) iex> env = __ENV__ iex> Macro.Env.lookup_import(env, {:flatten, 1}) [] iex> {:ok, env} = Macro.Env.define_import(env, [line: 10], SomeModule, [info_callback: fn :functions -> [{:flatten, 1}]; :macros -> [{:some, 2}]; end]) iex> Macro.Env.lookup_import(env, {:flatten, 1}) [{:function, SomeModule}] iex> Macro.Env.lookup_import(env, {:some, 2}) [{:macro, SomeModule}] ### Macro.Env.define_require/4 (function) Defines the given `module` as required in the environment. It does not check or assert the module is available. This is used by tools which need to mimic the Elixir compiler. The appropriate `:require` compiler tracing event will be emitted. ### Additional options - Macro.Env.define_require/4 (function) It accepts the same options as `Kernel.SpecialForm.require/2` plus: * `:trace` - when set to `false`, it disables compilation tracers and lexical tracker. This option must only be used by language servers and other tools that need to introspect code without affecting how it is compiled. Disabling tracer inside macros or regular code expansion is extremely discouraged as it blocks the compiler from accurately tracking dependencies ### Examples - Macro.Env.define_require/4 (function) iex> env = __ENV__ iex> Macro.Env.required?(env, Integer) false iex> {:ok, env} = Macro.Env.define_require(env, [line: 10], Integer) iex> Macro.Env.required?(env, Integer) true If the `:as` option is given, it will also define an alias: iex> env = __ENV__ iex> {:ok, env} = Macro.Env.define_require(env, [line: 10], Foo.Bar, as: Baz) iex> Macro.Env.expand_alias(env, [], [:Baz]) {:alias, Foo.Bar} ### Macro.Env.expand_alias/4 (function) Expands an alias given by the alias segments. It returns `{:alias, alias}` if the segments is a list of atoms and an alias was found. Returns `:error` otherwise. This expansion may emit the `:alias_expansion` trace event but it does not emit the `:alias_reference` one. ### Options - Macro.Env.expand_alias/4 (function) * `:trace` - when set to `false`, it disables compilation tracers and lexical tracker. This option must only be used by language servers and other tools that need to introspect code without affecting how it is compiled. Disabling tracer inside macros or regular code expansion is extremely discouraged as it blocks the compiler from accurately tracking dependencies ### Examples - Macro.Env.expand_alias/4 (function) iex> alias List, as: MyList iex> Macro.Env.expand_alias(__ENV__, [], [:MyList]) {:alias, List} iex> Macro.Env.expand_alias(__ENV__, [], [:MyList, :Nested]) {:alias, List.Nested} If there is no alias or the alias starts with `Elixir.` (which disables aliasing), then `:error` is returned: iex> alias List, as: MyList iex> Macro.Env.expand_alias(__ENV__, [], [:Elixir, MyList]) :error iex> Macro.Env.expand_alias(__ENV__, [], [:AnotherList]) :error ### Macro.Env.expand_import/5 (function) Expands an import given by `name` and `arity`. If the import points to a macro, it returns a tuple with the module and a function that expands the macro. The function expects the metadata to be attached to the expansion and the arguments of the macro. If the import points to a function, it returns a tuple with the module and the function name. If any import is found, the appropriate compiler tracing event will be emitted. Otherwise returns `{:error, reason}`. ### Options - Macro.Env.expand_import/5 (function) * `:allow_locals` - when set to `false`, it does not attempt to capture local macros defined in the current module in `env` * `:check_deprecations` - when set to `false`, does not check for deprecations when expanding macros * `:trace` - when set to `false`, it disables compilation tracers and lexical tracker. This option must only be used by language servers and other tools that need to introspect code without affecting how it is compiled. Disabling tracer inside macros or regular code expansion is extremely discouraged as it blocks the compiler from accurately tracking dependencies ### Macro.Env.expand_require/6 (function) Expands a require given by `module`, `name`, and `arity`. If the require points to a macro and the module has been required, it returns a tuple with the module and a function that expands the macro. The function expects the metadata to be attached to the expansion and the arguments of the macro. The appropriate `:remote_macro` compiler tracing event will be emitted if a macro is found (note a `:remote_function` event is not emitted in `:error` cases). Otherwise returns `:error`. ### Options - Macro.Env.expand_require/6 (function) * `:check_deprecations` - when set to `false`, does not check for deprecations when expanding macros * `:trace` - when set to `false`, it disables compilation tracers and lexical tracker. This option must only be used by language servers and other tools that need to introspect code without affecting how it is compiled. Disabling tracer inside macros or regular code expansion is extremely discouraged as it blocks the compiler from accurately tracking dependencies ### Macro.Env.has_var?/2 (function) Checks if a variable belongs to the environment. ### Examples - Macro.Env.has_var?/2 (function) iex> x = 13 iex> x 13 iex> Macro.Env.has_var?(__ENV__, {:x, nil}) true iex> Macro.Env.has_var?(__ENV__, {:unknown, nil}) false ### Macro.Env.in_guard?/1 (function) Returns whether the compilation environment is currently inside a guard. ### Macro.Env.in_match?/1 (function) Returns whether the compilation environment is currently inside a match clause. ### Macro.Env.location/1 (function) Returns a keyword list containing the file and line information as keys. ### Macro.Env.lookup_alias_as/2 (function) Returns the names of any aliases for the given module or atom. ### Examples - Macro.Env.lookup_alias_as/2 (function) iex> alias Foo.Bar iex> Bar Foo.Bar iex> Macro.Env.lookup_alias_as(__ENV__, Foo.Bar) [Elixir.Bar] iex> alias Foo.Bar, as: Baz iex> Baz Foo.Bar iex> Macro.Env.lookup_alias_as(__ENV__, Foo.Bar) [Elixir.Bar, Elixir.Baz] iex> Macro.Env.lookup_alias_as(__ENV__, Unknown) [] ### Macro.Env.lookup_import/2 (function) Returns the modules from which the given `{name, arity}` was imported. It returns a list of two element tuples in the shape of `{:function | :macro, module}`. The elements in the list are in no particular order and the order is not guaranteed. > #### Use only for introspection {: .warning} > > This function does not emit compiler tracing events, > which may block the compiler from correctly tracking > dependencies. Use this function for reflection purposes > but to do not use it to expand imports into qualified > calls. Instead, use `expand_import/5`. ### Examples - Macro.Env.lookup_import/2 (function) iex> Macro.Env.lookup_import(__ENV__, {:duplicate, 2}) [] iex> import Tuple, only: [duplicate: 2], warn: false iex> Macro.Env.lookup_import(__ENV__, {:duplicate, 2}) [{:function, Tuple}] iex> import List, only: [duplicate: 2], warn: false iex> Macro.Env.lookup_import(__ENV__, {:duplicate, 2}) [{:function, List}, {:function, Tuple}] iex> Macro.Env.lookup_import(__ENV__, {:def, 1}) [{:macro, Kernel}] ### Macro.Env.prepend_tracer/2 (function) Prepend a tracer to the list of tracers in the environment. ### Examples - Macro.Env.prepend_tracer/2 (function) Macro.Env.prepend_tracer(__ENV__, MyCustomTracer) ### Macro.Env.prune_compile_info/1 (function) Prunes compile information from the environment. This happens when the environment is captured at compilation time, for example, in the module body, and then used to evaluate code after the module has been defined. ### Macro.Env.required?/2 (function) Returns `true` if the given module has been required. ### Examples - Macro.Env.required?/2 (function) iex> Macro.Env.required?(__ENV__, Integer) false iex> require Integer iex> Macro.Env.required?(__ENV__, Integer) true iex> Macro.Env.required?(__ENV__, Kernel) true ### Macro.Env.stacktrace/1 (function) Returns the environment stacktrace. ### Macro.Env.to_guard/1 (function) Returns an environment in the guard context. ### Macro.Env.to_match/1 (function) Returns an environment in the match context. ### Macro.Env.vars/1 (function) Returns a list of variables in the current environment. Each variable is identified by a tuple of two elements, where the first element is the variable name as an atom and the second element is its context, which may be an atom or an integer. ### Macro.Env.context/0 (type) ### Macro.Env.context_modules/0 (type) ### Macro.Env.file/0 (type) ### Macro.Env.line/0 (type) ### Macro.Env.name_arity/0 (type) ### Macro.Env.t/0 (type) ### Macro.Env.variable/0 (type) ### Behaviour (module) Mechanism for handling behaviours. This module is deprecated. Instead of `defcallback/1` and `defmacrocallback/1`, the `@callback` and `@macrocallback` module attributes can be used respectively. See the documentation for `Module` for more information on these attributes. Instead of `MyModule.__behaviour__(:callbacks)`, `MyModule.behaviour_info(:callbacks)` can be used. `behaviour_info/1` is documented in `Module`. ### Behaviour.defcallback/1 (macro) Defines a function callback according to the given type specification. ### Behaviour.defmacrocallback/1 (macro) Defines a macro callback according to the given type specification. ### Dict (module) Generic API for dictionaries. If you need a general dictionary, use the `Map` module. If you need to manipulate keyword lists, use `Keyword`. To convert maps into keywords and vice-versa, use the `new` function in the respective modules. ### Dict.delete/2 (function) ### Dict.drop/2 (function) ### Dict.empty/1 (function) ### Dict.equal?/2 (function) ### Dict.fetch/2 (function) ### Dict.fetch!/2 (function) ### Dict.get/3 (function) ### Dict.get_and_update/3 (function) ### Dict.get_lazy/3 (function) ### Dict.has_key?/2 (function) ### Dict.keys/1 (function) ### Dict.merge/2 (function) ### Dict.merge/3 (function) ### Dict.pop/3 (function) ### Dict.pop_lazy/3 (function) ### Dict.put/3 (function) ### Dict.put_new/3 (function) ### Dict.put_new_lazy/3 (function) ### Dict.size/1 (function) ### Dict.split/2 (function) ### Dict.take/2 (function) ### Dict.to_list/1 (function) ### Dict.update/4 (function) ### Dict.update!/3 (function) ### Dict.values/1 (function) ### Dict.key/0 (type) ### Dict.t/0 (type) ### Dict.value/0 (type) ### GenEvent (behaviour) An event manager with event handlers behaviour. If you are interested in implementing an event manager, please read the "Alternatives" section below. If you have to implement an event handler to integrate with an existing system, such as Elixir's Logger, please use [`:gen_event`](`:gen_event`) instead. ### Alternatives - GenEvent (behaviour) There are a few suitable alternatives to replace GenEvent. Each of them can be the most beneficial based on the use case. ### Supervisor and GenServers - GenEvent (behaviour) One alternative to GenEvent is a very minimal solution consisting of using a supervisor and multiple GenServers started under it. The supervisor acts as the "event manager" and the children GenServers act as the "event handlers". This approach has some shortcomings (it provides no back-pressure for example) but can still replace GenEvent for low-profile usages of it. [This blog post by José Valim](https://dashbit.co/blog/replacing-genevent-by-a-supervisor-plus-genserver) has more detailed information on this approach. ### GenStage - GenEvent (behaviour) If the use case where you were using GenEvent requires more complex logic, [GenStage](https://github.com/elixir-lang/gen_stage) provides a great alternative. GenStage is an external Elixir library maintained by the Elixir team; it provides a tool to implement systems that exchange events in a demand-driven way with built-in support for back-pressure. See the [GenStage documentation](https://hexdocs.pm/gen_stage) for more information. ### `:gen_event` If your use case requires exactly what GenEvent provided, or you have to integrate with an existing `:gen_event`-based system, you can still use the [`:gen_event`](`:gen_event`) Erlang module. ### GenEvent.code_change/3 (callback) ### GenEvent.handle_call/2 (callback) ### GenEvent.handle_event/2 (callback) ### GenEvent.handle_info/2 (callback) ### GenEvent.init/1 (callback) ### GenEvent.terminate/2 (callback) ### GenEvent.handler/0 (type) ### GenEvent.manager/0 (type) ### GenEvent.name/0 (type) ### GenEvent.on_start/0 (type) ### GenEvent.options/0 (type) ### HashDict (module) Tuple-based HashDict implementation. This module is deprecated. Use the `Map` module instead. ### HashDict.delete/2 (function) ### HashDict.drop/2 (function) ### HashDict.equal?/2 (function) ### HashDict.fetch/2 (function) ### HashDict.fetch!/2 (function) ### HashDict.get/3 (function) ### HashDict.get_and_update/3 (function) ### HashDict.get_lazy/3 (function) ### HashDict.has_key?/2 (function) ### HashDict.keys/1 (function) ### HashDict.merge/3 (function) ### HashDict.new/0 (function) Creates a new empty dict. ### HashDict.pop/3 (function) ### HashDict.pop_lazy/3 (function) ### HashDict.put/3 (function) ### HashDict.put_new/3 (function) ### HashDict.put_new_lazy/3 (function) ### HashDict.size/1 (function) ### HashDict.split/2 (function) ### HashDict.take/2 (function) ### HashDict.to_list/1 (function) ### HashDict.update/4 (function) ### HashDict.update!/3 (function) ### HashDict.values/1 (function) ### HashSet (module) Tuple-based HashSet implementation. This module is deprecated. Use the `MapSet` module instead. ### HashSet.delete/2 (function) ### HashSet.difference/2 (function) ### HashSet.disjoint?/2 (function) ### HashSet.equal?/2 (function) ### HashSet.intersection/2 (function) ### HashSet.member?/2 (function) ### HashSet.new/0 (function) ### HashSet.put/2 (function) ### HashSet.size/1 (function) ### HashSet.subset?/2 (function) ### HashSet.to_list/1 (function) ### HashSet.union/2 (function) ### Set (module) Generic API for sets. This module is deprecated, use the `MapSet` module instead. ### Set.delete/2 (function) ### Set.difference/2 (function) ### Set.disjoint?/2 (function) ### Set.empty/1 (function) ### Set.equal?/2 (function) ### Set.intersection/2 (function) ### Set.member?/2 (function) ### Set.put/2 (function) ### Set.size/1 (function) ### Set.subset?/2 (function) ### Set.to_list/1 (function) ### Set.union/2 (function) ### Set.t/0 (type) ### Set.value/0 (type) ### Set.values/0 (type) ### Supervisor.Spec (module) Outdated functions for building child specifications. The functions in this module are deprecated and they do not work with the module-based child specs introduced in Elixir v1.5. Please see the `Supervisor` documentation instead. Convenience functions for defining supervisor specifications. ### Example - Supervisor.Spec (module) By using the functions in this module one can specify the children to be used under a supervisor, started with `Supervisor.start_link/2`: import Supervisor.Spec children = [ worker(MyWorker, [arg1, arg2, arg3]), supervisor(MySupervisor, [arg1]) ] Supervisor.start_link(children, strategy: :one_for_one) Sometimes, it may be handy to define supervisors backed by a module: defmodule MySupervisor do use Supervisor def start_link(arg) do Supervisor.start_link(__MODULE__, arg) end def init(arg) do children = [ worker(MyWorker, [arg], restart: :temporary) ] supervise(children, strategy: :simple_one_for_one) end end Note that in this case we don't have to explicitly import `Supervisor.Spec` since `use Supervisor` automatically does so. Defining a module-based supervisor can be useful, for example, to perform initialization tasks in the `c:Supervisor.init/1` callback. ### Supervisor and worker options - Supervisor.Spec (module) In the example above, we defined specs for workers and supervisors. These specs (both for workers as well as supervisors) accept the following options: * `:id` - a name used to identify the child specification internally by the supervisor; defaults to the given module name for the child worker/supervisor * `:function` - the function to invoke on the child to start it * `:restart` - an atom that defines when a terminated child process should be restarted (see the "Restart values" section below) * `:shutdown` - an atom that defines how a child process should be terminated (see the "Shutdown values" section below) * `:modules` - it should be a list with one element `[module]`, where module is the name of the callback module only if the child process is a `Supervisor` or `GenServer`; if the child process is a `GenEvent`, `:modules` should be `:dynamic` ### Restart values (:restart) - Supervisor.Spec (module) The following restart values are supported in the `:restart` option: * `:permanent` - the child process is always restarted * `:temporary` - the child process is never restarted (not even when the supervisor's strategy is `:rest_for_one` or `:one_for_all`) * `:transient` - the child process is restarted only if it terminates abnormally, i.e., with an exit reason other than `:normal`, `:shutdown` or `{:shutdown, term}` Note that supervisor that reached maximum restart intensity will exit with `:shutdown` reason. In this case the supervisor will only restart if its child specification was defined with the `:restart` option set to `:permanent` (the default). ### Shutdown values (`:shutdown`) - Supervisor.Spec (module) The following shutdown values are supported in the `:shutdown` option: * `:brutal_kill` - the child process is unconditionally terminated using `Process.exit(child, :kill)` * `:infinity` - if the child process is a supervisor, this is a mechanism to give the subtree enough time to shut down; it can also be used with workers with care * a non-negative integer - the amount of time in milliseconds that the supervisor tells the child process to terminate by calling `Process.exit(child, :shutdown)` and then waits for an exit signal back. If no exit signal is received within the specified time, the child process is unconditionally terminated using `Process.exit(child, :kill)` ### Supervisor.Spec.supervise/2 (function) Receives a list of `children` (workers or supervisors) to supervise and a set of `options`. Returns a tuple containing the supervisor specification. This tuple can be used as the return value of the `c:Supervisor.init/1` callback when implementing a module-based supervisor. ### Examples - Supervisor.Spec.supervise/2 (function) supervise(children, strategy: :one_for_one) ### Options - Supervisor.Spec.supervise/2 (function) * `:strategy` - the restart strategy option. It can be either `:one_for_one`, `:rest_for_one`, `:one_for_all`, or `:simple_one_for_one`. You can learn more about strategies in the `Supervisor` module docs. * `:max_restarts` - the maximum number of restarts allowed in a time frame. Defaults to `3`. * `:max_seconds` - the time frame in which `:max_restarts` applies. Defaults to `5`. The `:strategy` option is required and by default a maximum of 3 restarts is allowed within 5 seconds. Check the `Supervisor` module for a detailed description of the available strategies. ### Supervisor.Spec.supervisor/3 (function) Defines the given `module` as a supervisor which will be started with the given arguments. supervisor(module, [], restart: :permanent) By default, the function `start_link` is invoked on the given module. Overall, the default values for the options are: [ id: module, function: :start_link, restart: :permanent, shutdown: :infinity, modules: [module] ] See the "Supervisor and worker options" section in the `Supervisor.Spec` module for more information on the available options. ### Supervisor.Spec.worker/3 (function) Defines the given `module` as a worker which will be started with the given arguments. worker(ExUnit.Runner, [], restart: :permanent) By default, the function `start_link` is invoked on the given module. Overall, the default values for the options are: [ id: module, function: :start_link, restart: :permanent, shutdown: 5000, modules: [module] ] See the "Supervisor and worker options" section in the `Supervisor.Spec` module for more information on the available options. ### Supervisor.Spec.child_id/0 (type) Supported ID values ### Supervisor.Spec.modules/0 (type) Supported module values ### Supervisor.Spec.restart/0 (type) Supported restart values ### Supervisor.Spec.shutdown/0 (type) Supported shutdown values ### Supervisor.Spec.spec/0 (type) The supervisor specification ### Supervisor.Spec.strategy/0 (type) Supported strategies ### Supervisor.Spec.worker/0 (type) Supported worker values ### MissingApplicationsError.t/0 (type) ## Links - [Online documentation](https://hexdocs.pm/elixir)