Record.defrecord
defrecord
, go back to Record module for more information.
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 fieldsname/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 listname/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
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
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