官术网_书友最值得收藏!

  • Mastering Elixir
  • André Albuquerque Daniel Caixinha
  • 514字
  • 2021-08-05 10:42:48

Module attributes, directives, and uses

Modules in Elixir may contain attributes. They're normally used where you'd use constants in other languages. You define a module attribute with the following syntax:

$ cat examples/string_helper_with_module_attribute.ex
defmodule StringHelper do
@default_mark "!"

# rest of the StringHelper code
end

Then, we can use the @default_mark module attribute inside the functions of this module. This attribute only exists at compile time, as it's replaced by its value during this process.

There are some other use cases for module attributes: you can register them, which makes them accessible at runtime. For instance, Elixir registers the @moduledoc and @doc attributes, which can be used to provide documentation for modules and functions, respectively. This documentation can then be accessed at runtime by other Elixir tools, as we'll explore in the Tooling and ecosystems section.

We're now mentioning macros for the first time. Macros are Elixir's mechanism to do meta-programming generating code that writes code. We will not touch macros in this introductory chapter, as they will be properly examined in Chapter 6Metaprogramming – Code that Writes Itself.

Elixir provides three lexically scoped directives to manage modules, plus a macro called use. We'll describe them now:

  • alias is used to create aliases for other modules. You use it as alias Helpers.StringHelper, as: StrHlp, and you can then refer to that module as StrHlp. The as: portion is optional, and if you don't provide it, the alias will be set to the last part of the module name.
  • We use require when we want to invoke what's defined as macros in a given module. As stated in the official documentation, is_odd/1 from the Integer module is defined as a macro. To use it in another module, you have to require it: require Integer.
  • When we want to access functions from other modules without having to use the fully-qualified name, we use import. When we import a given module, we're also automatically requiring it. If we're constantly using String.reverse/1 for instance, we can import it: import String, only: [reverse: 1]. Now we can just use reverse directly in our module. Apart from only:, you can also use except: to import all but a given number of functions from a module. Besides function names, only: and except: also accept :modules and :functions (which are self explanatory). You can also just use import without any option, but this isn't recommended, as it pollutes the scope of your modulealways try to pass the only: option when using import.
  • Last, but not least, we have use, which is a macro. This is commonly used to bring extra functionality to our modules. Beneath the surface, use calls the require directive and then calls the __using__/1 callback, which allows the module being used to inject code into our context.

For now, you don't need to know how all of this works. It is enough to know that you have these constructs to deal with modules. When we dive into macros later in this book, all of this will become much clearer.

主站蜘蛛池模板: 都兰县| 绿春县| 清水县| 温宿县| 潢川县| 宁都县| 汉沽区| 水富县| 马鞍山市| 阿图什市| 松滋市| 葵青区| 元阳县| 文安县| 上栗县| 长葛市| 怀安县| 金川县| 丰原市| 高尔夫| 专栏| 比如县| 木兰县| 永新县| 开封市| 安阳县| 罗源县| 黎城县| 杭锦后旗| 和林格尔县| 花垣县| 黄石市| 宁化县| 商洛市| 南充市| 靖安县| 息烽县| 新巴尔虎右旗| 建德市| 保亭| 霍城县|