Skip to content

Commit 15bf0fb

Browse files
committed
Provide reference documentation for module attributes
1 parent 5184edd commit 15bf0fb

File tree

1 file changed

+257
-3
lines changed

1 file changed

+257
-3
lines changed

lib/elixir/lib/module.ex

Lines changed: 257 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,270 @@ defmodule Module do
77
end
88
end
99

10-
@moduledoc """
10+
@moduledoc %B'''
1111
This module provides many functions to deal with modules during
1212
compilation time. It allows a developer to dynamically attach
1313
documentation, add, delete and register attributes and so forth.
1414
15-
After the module is compiled, using many of the functions in
15+
After a module is compiled, using many of the functions in
1616
this module will raise errors, since it is out of their purpose
1717
to inspect runtime data. Most of the runtime data can be inspected
1818
via the `__info__(attr)` function attached to each compiled module.
19-
"""
19+
20+
## Module attributes
21+
22+
Each module can be decorated with one or more attributes. The following ones
23+
are currently defined by Elixir:
24+
25+
* `@after_compile`
26+
27+
A hook that will be invoked right after the current module is compiled.
28+
29+
Accepts a module or a tuple `{ <module>, <function atom> }`. The function
30+
must take two arguments: the module environment and its bytecode.
31+
When just a module is provided, the function is assumed to be
32+
`__after_compile__/2`.
33+
34+
**Example**
35+
36+
defmodule M do
37+
@after_compile __MODULE__
38+
39+
def __after_compile__(env, _bytecode) do
40+
IO.inspect env
41+
end
42+
end
43+
44+
* `@before_compile`
45+
46+
A hook that will be invoked before the module is compiled.
47+
48+
Accepts a module or a tuple `{ <module>, <function/macro atom> }`. The
49+
function/macro must take one argument: the module environment. If it's a
50+
macro, its returned value will be injected at the end of the module definition
51+
before the compilation starts.
52+
53+
When just a module is provided, the function/macro is assumed to be
54+
`__before_compile__/1`.
55+
56+
**Example**
57+
58+
defmodule M do
59+
@before_compile __MODULE__
60+
61+
defmacro __before_compile__(_env) do
62+
quote do
63+
def hello, do: "world"
64+
end
65+
end
66+
end
67+
68+
* `@behaviour` (notice the british spelling)
69+
70+
Specify an OTP or user-defined behaviour.
71+
72+
**Example**
73+
74+
defmodule M do
75+
@behaviour gen_event
76+
77+
# ...
78+
end
79+
80+
* `@compile`
81+
82+
Define options for module compilation that are passed to the Erlang
83+
compiler.
84+
85+
Accepts an atom, a tuple, or a list of atoms and tuples.
86+
87+
See http://www.erlang.org/doc/man/compile.html for the list of supported
88+
options.
89+
90+
**Example**
91+
92+
defmodule M do
93+
@compile { :inline, myfun: 1 }
94+
95+
def myfun(arg) do
96+
to_binary(arg)
97+
end
98+
end
99+
100+
* `@doc`
101+
102+
Provide documentation for the function or macro that follows the
103+
attribute.
104+
105+
Accepts a string (often a heredoc) or `false` where `@doc false` will
106+
make the function/macro invisible to the documentation extraction tools
107+
like ExDoc.
108+
109+
Can be invoked more than once.
110+
111+
**Example**
112+
113+
defmodule M do
114+
@doc "Hello world"
115+
def hello do
116+
"world"
117+
end
118+
119+
@doc """
120+
Sum.
121+
"""
122+
def sum(a, b) do
123+
a + b
124+
end
125+
end
126+
127+
* `@file`
128+
129+
Change the filename used in stacktraces for the function or macro that
130+
follows the attribute.
131+
132+
Accepts a string. Can be used more than once.
133+
134+
**Example**
135+
136+
defmodule M do
137+
@doc "Hello world"
138+
@file "hello.ex"
139+
def hello do
140+
"world"
141+
end
142+
end
143+
144+
* `@moduledoc`
145+
146+
Provide documentation for the current module.
147+
148+
Accepts a string (which is often a heredoc) or `false` where
149+
`@moduledoc false` will make the module invisible to the
150+
documentation extraction tools like ExDoc.
151+
152+
**Example**
153+
154+
defmodule M do
155+
@moduledoc """
156+
A very useful module
157+
"""
158+
end
159+
160+
161+
* `@on_definition`
162+
163+
A hook that will be invoked after each function or macro in the current
164+
module is defined. This makes it easy to annotate and customize
165+
functions.
166+
167+
Accepts a module or a tuple `{ <module>, <function atom> }`. The function
168+
must take 6 arguments:
169+
170+
- the module environment
171+
- kind: `:def`, `:defp`, `:defmacro`, or `:defmacrop`
172+
- function/macro name
173+
- list of quoted arguments
174+
- list of quoted guards
175+
- quoted function body
176+
177+
If the function/macro being defined has multiple clauses, the hook will
178+
be called for each clause.
179+
180+
When just a module is provided, the function is assumed to be
181+
`__on_definition__/6`.
182+
183+
Note that you can't provide the current module to `@on_definition`
184+
because the hook function will not be defined in time.
185+
186+
**Example**
187+
188+
defmodule H do
189+
def on_def(_env, kind, name, args, guards, body) do
190+
IO.puts "Defining #{kind} named #{name} with args:"
191+
IO.inspect args
192+
IO.puts "and guards"
193+
IO.inspect guards
194+
IO.puts "and body"
195+
IO.puts Macro.to_binary(body)
196+
end
197+
end
198+
199+
defmodule M do
200+
@on_definition { H, :on_def }
201+
202+
def hello(arg) when is_binary(arg) or is_list(arg) do
203+
"Hello" <> to_binary(arg)
204+
end
205+
206+
def hello(_) do
207+
:ok
208+
end
209+
end
210+
211+
* `@on_load`
212+
213+
A hook that will be invoked whenever the module is loaded.
214+
215+
Accepts a function atom of a function in the current module. The function
216+
must have arity 0 (no arguments) and has to return `:ok`, otherwise the
217+
loading of the module will be aborted.
218+
219+
**Example**
220+
221+
defmodule M do
222+
@on_load :load_check
223+
224+
def load_check do
225+
if some_condition() do
226+
:ok
227+
else
228+
nil
229+
end
230+
end
231+
232+
def some_condition do
233+
false
234+
end
235+
end
236+
237+
* `@vsn`
238+
239+
Specify the module version. Accepts any valid Elixir value.
240+
241+
**Example**
242+
243+
defmodule M do
244+
@vsn "1.0"
245+
end
246+
247+
The following attributes are part of typespecs and are also reserved by
248+
Elixir:
249+
250+
* `@type` - defines a type to be used in `@spec`
251+
* `@spec` - provides a specification for a function
252+
* `@callback` - provides a specification for the behavior callback
253+
* `@export_type` - informs which types can be exported
254+
* `@opaque` - defines an opaque type to be used in `@spec`
255+
256+
In addition to the built-in attributes outlined above, custom attributes may
257+
also be added. A custom attribute is any valid identifier prefixed with an
258+
`@` and followed by a valid Elixir value:
259+
260+
defmodule M do
261+
@custom_attr [some: "stuff"]
262+
end
263+
264+
For more advanced options available when defining custom attributes, see
265+
`register_attribute/3`.
266+
267+
## Runtime information about a module
268+
269+
__info__
270+
271+
... (as yet unwritten content) ...
272+
273+
'''
20274

21275
@doc """
22276
Check if a module is open, i.e. it is currently being defined

0 commit comments

Comments
 (0)