Skip to content

Commit dfd5e79

Browse files
authored
Polish the docs for the Record module (#4908)
1 parent 43c1818 commit dfd5e79

File tree

1 file changed

+78
-25
lines changed

1 file changed

+78
-25
lines changed

lib/elixir/lib/record.ex

Lines changed: 78 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule Record do
22
@moduledoc """
3-
Module to work with, define and import records.
3+
Module to work with, define, and import records.
44
55
Records are simply tuples where the first element is an atom:
66
@@ -17,15 +17,14 @@ defmodule Record do
1717
1. to work with short, internal data
1818
2. to interface with Erlang records
1919
20-
The macros `defrecord/3` and `defrecordp/3` can be used to create
21-
records while `extract/2` can be used to extract records from Erlang
22-
files.
20+
The macros `defrecord/3` and `defrecordp/3` can be used to create records
21+
while `extract/2` and `extract_all/1` can be used to extract records from
22+
Erlang files.
2323
2424
## Types
2525
26-
Types can be defined for tuples with the `record/2` macro (only available
27-
in typespecs). Like with the generated record macros it will expand to
28-
a tuple.
26+
Types can be defined for tuples with the `record/2` macro (only available in
27+
typespecs). This macro will expand to a tuple as seen in the example below:
2928
3029
defmodule MyModule do
3130
require Record
@@ -34,14 +33,34 @@ defmodule Record do
3433
@type user :: record(:user, name: String.t, age: integer)
3534
# expands to: "@type user :: {:user, String.t, integer}"
3635
end
36+
3737
"""
3838

3939
@doc """
4040
Extracts record information from an Erlang file.
4141
4242
Returns a quoted expression containing the fields as a list
43-
of tuples. It expects the record name to be an atom and the
44-
library path to be a string at expansion time.
43+
of tuples.
44+
45+
`name`, which is the name of the extracted record, is expected to be an atom
46+
*at compile time*.
47+
48+
## Options
49+
50+
This function accepts the following options, which are exclusive to each other
51+
(i.e., only one of them can be used in the same call):
52+
53+
* `:from` - (binary representing a path to a file) path to the Erlang file
54+
that contains the record definition to extract; with this option, this
55+
function uses the same path lookup used by the `-include` attribute used in
56+
Erlang modules.
57+
* `:from_lib` - (binary representing a path to a file) path to the Erlang
58+
file that contains the record definition to extract; with this option,
59+
this function uses the same path lookup used by the `-include_lib`
60+
attribute used in Erlang modules.
61+
62+
These options are expected to be literals (including the binary values) at
63+
compile time.
4564
4665
## Examples
4766
@@ -59,18 +78,33 @@ defmodule Record do
5978
@doc """
6079
Extracts all records information from an Erlang file.
6180
62-
Returns a keyword list containing extracted record names as keys, and
63-
lists of tuples describing the fields as values. It expects a named
64-
argument :from or :from_lib, which correspond to *include* or
65-
*include_lib* attribute from Erlang modules, respectively.
81+
Returns a keyword list of `{record_name, fields}` tuples where `record_name`
82+
is the name of an extracted record and `fields` is a list of `{field, value}`
83+
tuples representing the fields for that record.
84+
85+
## Options
86+
87+
This function accepts the following options, which are exclusive to each other
88+
(i.e., only one of them can be used in the same call):
6689
90+
* `:from` - (binary representing a path to a file) path to the Erlang file
91+
that contains the record definitions to extract; with this option, this
92+
function uses the same path lookup used by the `-include` attribute used in
93+
Erlang modules.
94+
* `:from_lib` - (binary representing a path to a file) path to the Erlang
95+
file that contains the record definitions to extract; with this option,
96+
this function uses the same path lookup used by the `-include_lib`
97+
attribute used in Erlang modules.
98+
99+
These options are expected to be literals (including the binary values) at
100+
compile time.
67101
"""
68102
def extract_all(opts) when is_list(opts) do
69103
Record.Extractor.extract_all(opts)
70104
end
71105

72106
@doc """
73-
Checks if the given `data` is a record of `kind`.
107+
Checks if the given `data` is a record of kind `kind`.
74108
75109
This is implemented as a macro so it can be used in guard clauses.
76110
@@ -110,6 +144,9 @@ defmodule Record do
110144
iex> tuple = {}
111145
iex> Record.is_record(tuple)
112146
false
147+
iex> other_term = "not a record"
148+
iex> Record.is_record(other_term)
149+
false
113150
114151
"""
115152
defmacro is_record(data) do
@@ -128,11 +165,26 @@ defmodule Record do
128165
end
129166

130167
@doc """
131-
Defines a set of macros to create and access a record.
168+
Defines a set of macros to create, access, and pattern match
169+
on a record.
170+
171+
The name of the generated macros will be `name` (which has to be an
172+
atom). `tag` is also an atom and is used as the "tag" for the record (i.e.,
173+
the first element of the record tuple); by default (if `nil`), it's the same
174+
as `name`. `kv` is a keyword list of `name: default_value` fields for the
175+
new record.
176+
177+
The following macros are generated:
132178
133-
The macros are going to have `name`, a tag (which defaults)
134-
to the name if none is given, and a set of fields given by
135-
`kv`.
179+
* `name/0` to create a new record with default values for all fields
180+
* `name/1` to create a new record with the given fields and values or to
181+
convert the given record to a keyword list
182+
* `name/2` to update an existing record with the given fields and values
183+
or to access a given field in a given record
184+
185+
All these macros are public macros (as defined by `defmacro`).
186+
187+
See the "Examples" section for examples on how to use these macros.
136188
137189
## Examples
138190
@@ -142,7 +194,7 @@ defmodule Record do
142194
end
143195
144196
In the example above, a set of macros named `user` but with different
145-
arities will be defined to manipulate the underlying record:
197+
arities will be defined to manipulate the underlying record.
146198
147199
# To create records
148200
record = user() #=> {:user, "meg", 25}
@@ -165,8 +217,8 @@ defmodule Record do
165217
user(name: name) = record
166218
name #=> "meg"
167219
168-
By default, Elixir uses the record name as the first element of
169-
the tuple (the tag). But it can be changed to something else:
220+
By default, Elixir uses the record name as the first element of the tuple (the
221+
"tag"). However, a different tag can be specified when defining a record:
170222
171223
defmodule User do
172224
require Record
@@ -176,11 +228,11 @@ defmodule Record do
176228
require User
177229
User.user() #=> {User, nil}
178230
179-
## Defining extracted records with anonymous functions
231+
## Defining extracted records with anonymous functions in the values
180232
181-
If a record defines an anonymous function, an `ArgumentError`
182-
will occur if you attempt to create a record with it.
183-
This can occur unintentionally when defining a record after extracting
233+
If a record defines an anonymous function in the default values,
234+
an `ArgumentError` will occur if you attempt to create a record with it.
235+
This can happen unintentionally when defining a record after extracting
184236
it from an Erlang library that uses anonymous functions for defaults.
185237
186238
Record.defrecord :my_rec, Record.extract(...)
@@ -195,6 +247,7 @@ defmodule Record do
195247
Record.defrecord :my_rec, Record.extract(...) |> Keyword.merge(fun_field: &__MODULE__.foo/2)
196248
def foo(bar, baz), do: IO.inspect({bar, baz})
197249
end
250+
198251
"""
199252
defmacro defrecord(name, tag \\ nil, kv) do
200253
quote bind_quoted: [name: name, tag: tag, kv: kv] do

0 commit comments

Comments
 (0)