From 08d844a20643cdda3ab6e32e072ddab84a1ee15e Mon Sep 17 00:00:00 2001 From: Jean Klingler Date: Sun, 12 Jan 2025 18:58:38 +0900 Subject: [PATCH] Add and simplify links to erlang documentation (#14179) * Link more erlang modules in docs * Fix epmd link * Use `:atom` syntax to link erlang modules --- lib/elixir/lib/json.ex | 2 +- lib/elixir/lib/kernel.ex | 4 ++-- lib/elixir/lib/map_set.ex | 3 +-- lib/elixir/lib/string.ex | 2 +- lib/elixir/pages/anti-patterns/process-anti-patterns.md | 2 +- lib/elixir/pages/getting-started/debugging.md | 4 ++-- lib/elixir/pages/mix-and-otp/agents.md | 2 +- lib/elixir/pages/mix-and-otp/distributed-tasks.md | 8 ++++---- lib/elixir/pages/mix-and-otp/erlang-term-storage.md | 2 +- lib/elixir/pages/mix-and-otp/task-and-gen-tcp.md | 2 +- lib/ex_unit/lib/ex_unit.ex | 8 ++++---- lib/mix/lib/mix/tasks/profile.eprof.ex | 2 +- lib/mix/lib/mix/tasks/profile.fprof.ex | 2 +- lib/mix/lib/mix/tasks/profile.tprof.ex | 2 +- lib/mix/lib/mix/tasks/release.ex | 4 ++-- lib/mix/lib/mix/tasks/test.coverage.ex | 6 +++--- 16 files changed, 27 insertions(+), 28 deletions(-) diff --git a/lib/elixir/lib/json.ex b/lib/elixir/lib/json.ex index a34c4590462..7707393a470 100644 --- a/lib/elixir/lib/json.ex +++ b/lib/elixir/lib/json.ex @@ -356,7 +356,7 @@ defmodule JSON do * for `string`: `&Function.identity/1` * for `null`: the atom `nil` - For streaming decoding, see Erlang's `:json` module. + For streaming decoding, see Erlang's [`:json`](`:json`) module. """ @spec decode(binary(), term(), keyword()) :: {term(), term(), binary()} | {:error, decode_error_reason()} diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex index 708fcc3c825..da6ee591cab 100644 --- a/lib/elixir/lib/kernel.ex +++ b/lib/elixir/lib/kernel.ex @@ -60,7 +60,7 @@ defmodule Kernel do * 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 + be manipulated with Erlang's [`:binary`](`:binary`) module * Reference - a unique value in the runtime system, created with `make_ref/0` ### Data types @@ -5722,7 +5722,7 @@ defmodule Kernel do > > * If using `defoverridable`, avoid relying on `super` to trigger the default > behaviour, suggesting users to invoke well-defined APIs instead. - > + > """ defmacro defoverridable(keywords_or_behaviour) do quote do diff --git a/lib/elixir/lib/map_set.ex b/lib/elixir/lib/map_set.ex index a94083df06e..9ed724f2401 100644 --- a/lib/elixir/lib/map_set.ex +++ b/lib/elixir/lib/map_set.ex @@ -43,8 +43,7 @@ defmodule MapSet do `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 + `MapSet` is built on top of Erlang's [`:sets`](`:sets`) (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. diff --git a/lib/elixir/lib/string.ex b/lib/elixir/lib/string.ex index 0b95ba4a139..c93aedf5cda 100644 --- a/lib/elixir/lib/string.ex +++ b/lib/elixir/lib/string.ex @@ -172,7 +172,7 @@ defmodule String do 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. + normalization mechanisms, see Erlang's [`:unicode`](`:unicode`) module. ## String and binary operations diff --git a/lib/elixir/pages/anti-patterns/process-anti-patterns.md b/lib/elixir/pages/anti-patterns/process-anti-patterns.md index 1457a272f28..7070dd14eda 100644 --- a/lib/elixir/pages/anti-patterns/process-anti-patterns.md +++ b/lib/elixir/pages/anti-patterns/process-anti-patterns.md @@ -227,7 +227,7 @@ This anti-pattern has many potential remedies: * If the only process that needs data is the one you are sending to, consider making the process fetch that data instead of passing it. - * Some abstractions, such as [`:persistent_term`](https://www.erlang.org/doc/man/persistent_term.html), allows you to share data between processes, as long as such data changes infrequently. + * Some abstractions, such as [`:persistent_term`](`:persistent_term`), allows you to share data between processes, as long as such data changes infrequently. In our case, limiting the input data is a reasonable strategy. If all we need *right now* is the IP address, then let's only work with that and make sure we're only passing the IP address into the closure, like so: diff --git a/lib/elixir/pages/getting-started/debugging.md b/lib/elixir/pages/getting-started/debugging.md index 8b503106381..310a99bfb4b 100644 --- a/lib/elixir/pages/getting-started/debugging.md +++ b/lib/elixir/pages/getting-started/debugging.md @@ -175,11 +175,11 @@ Finally, remember you can also get a mini-overview of the runtime info by callin We have just scratched the surface of what the Erlang VM has to offer, for example: - * Alongside the observer application, Erlang also includes a [`:crashdump_viewer`](https://www.erlang.org/doc/man/crashdump_viewer.html) to view crash dumps + * Alongside the observer application, Erlang also includes a [`:crashdump_viewer`](`:crashdump_viewer`) to view crash dumps * Integration with OS level tracers, such as [Linux Trace Toolkit,](https://www.erlang.org/doc/apps/runtime_tools/lttng) [DTRACE,](https://www.erlang.org/doc/apps/runtime_tools/dtrace) and [SystemTap](https://www.erlang.org/doc/apps/runtime_tools/systemtap) - * [Microstate accounting](http://www.erlang.org/doc/man/msacc.html) measures how much time the runtime spends in several low-level tasks in a short time interval + * [Microstate accounting](`:msacc`) measures how much time the runtime spends in several low-level tasks in a short time interval * Mix ships with many tasks under the `profile` namespace, such as `mix profile.cprof` and `mix profile.fprof` diff --git a/lib/elixir/pages/mix-and-otp/agents.md b/lib/elixir/pages/mix-and-otp/agents.md index 30ab605c23c..d839e1022e6 100644 --- a/lib/elixir/pages/mix-and-otp/agents.md +++ b/lib/elixir/pages/mix-and-otp/agents.md @@ -9,7 +9,7 @@ If you have skipped the *Getting Started* guide or read it long ago, be sure to Elixir is an immutable language where nothing is shared by default. If we want to share information, which can be read and modified from multiple places, we have two main options in Elixir: * Using processes and message passing - * [ETS (Erlang Term Storage)](http://www.erlang.org/doc/man/ets.html) + * [ETS (Erlang Term Storage)](`:ets`) We covered processes in the *Getting Started* guide. ETS (Erlang Term Storage) is a new topic that we will explore in later chapters. When it comes to processes though, we rarely hand-roll our own, instead we use the abstractions available in Elixir and OTP: diff --git a/lib/elixir/pages/mix-and-otp/distributed-tasks.md b/lib/elixir/pages/mix-and-otp/distributed-tasks.md index 88ea24f83c8..76356f7741f 100644 --- a/lib/elixir/pages/mix-and-otp/distributed-tasks.md +++ b/lib/elixir/pages/mix-and-otp/distributed-tasks.md @@ -15,7 +15,7 @@ The router will check the first byte of the bucket name against the table and di If the matching entry points to the node evaluating the request, then we've finished routing, and this node will perform the requested operation. If the matching entry points to a different node, we'll pass the request to said node, which will look at its own routing table (which may be different from the one in the first node) and act accordingly. If no entry matches, an error will be raised. -> Note: we will be using two nodes in the same machine throughout this chapter. You are free to use two (or more) different machines on the same network but you need to do some prep work. First of all, you need to ensure all machines have a `~/.erlang.cookie` file with exactly the same value. Then you need to guarantee [epmd](http://www.erlang.org/doc/man/epmd.html) is running on a port that is not blocked (you can run `epmd -d` for debug info). +> Note: we will be using two nodes in the same machine throughout this chapter. You are free to use two (or more) different machines on the same network but you need to do some prep work. First of all, you need to ensure all machines have a `~/.erlang.cookie` file with exactly the same value. Then you need to guarantee [epmd](https://www.erlang.org/doc/apps/erts/epmd_cmd) is running on a port that is not blocked (you can run `epmd -d` for debug info). ## Our first distributed code @@ -86,7 +86,7 @@ From our quick exploration, we could conclude that we should use `Node.spawn_lin There are three better alternatives to `Node.spawn_link/2` that we could use in our implementation: -1. We could use Erlang's [:erpc](http://www.erlang.org/doc/man/erpc.html) module to execute functions on a remote node. Inside the `bar@computer-name` shell above, you can call `:erpc.call(:"foo@computer-name", Hello, :world, [])` and it will print "hello world" +1. We could use Erlang's [`:erpc`](`:erpc`) module to execute functions on a remote node. Inside the `bar@computer-name` shell above, you can call `:erpc.call(:"foo@computer-name", Hello, :world, [])` and it will print "hello world" 2. We could have a server running on the other node and send requests to that node via the `GenServer` API. For example, you can call a server on a remote node by using `GenServer.call({name, node}, arg)` or passing the remote process PID as the first argument @@ -347,8 +347,8 @@ Distributed key-value stores, used in real-life, need to consider the fact nodes These topics can be daunting at first but remember that most Elixir frameworks abstract those concerns for you. For example, when using [the Phoenix web framework](https://phoenixframework.org), its plug-and-play abstractions take care of sending messages and tracking how users join and leave a cluster. However, if you are interested in distributed systems after all, there is much to explore. Here are some additional references: * [The excellent Distribunomicon chapter from Learn You Some Erlang](http://learnyousomeerlang.com/distribunomicon) - * [Erlang's global module](https://www.erlang.org/doc/man/global.html), which can provide global names and global locks, allowing unique names and unique locks in a whole cluster of machines - * [Erlang's pg module](https://www.erlang.org/doc/man/pg.html), which allows process to join different groups shared across the whole cluster + * Erlang's [`:global` module](`:global`), which can provide global names and global locks, allowing unique names and unique locks in a whole cluster of machines + * Erlang's [`:pg` module](`:pg`), which allows process to join different groups shared across the whole cluster * [Phoenix PubSub project](https://github.com/phoenixframework/phoenix_pubsub), which provides a distributed messaging system and a distributed presence system for tracking users and processes in a cluster You will also find many libraries for building distributed systems within the overall Erlang ecosystem. For now, it is time to go back to our simple distributed key-value store and learn how to configure and package it for production. diff --git a/lib/elixir/pages/mix-and-otp/erlang-term-storage.md b/lib/elixir/pages/mix-and-otp/erlang-term-storage.md index d5f4efb74b7..b56593b5367 100644 --- a/lib/elixir/pages/mix-and-otp/erlang-term-storage.md +++ b/lib/elixir/pages/mix-and-otp/erlang-term-storage.md @@ -8,7 +8,7 @@ In this chapter, we will learn about ETS (Erlang Term Storage) and how to use it ## ETS as a cache -ETS allows us to store any Elixir term in an in-memory table. Working with ETS tables is done via [Erlang's `:ets` module](http://www.erlang.org/doc/man/ets.html): +ETS allows us to store any Elixir term in an in-memory table. Working with ETS tables is done via [Erlang's `:ets` module](`:ets`): ```elixir iex> table = :ets.new(:buckets_registry, [:set, :protected]) diff --git a/lib/elixir/pages/mix-and-otp/task-and-gen-tcp.md b/lib/elixir/pages/mix-and-otp/task-and-gen-tcp.md index 79d3a2972ec..51d9db61e44 100644 --- a/lib/elixir/pages/mix-and-otp/task-and-gen-tcp.md +++ b/lib/elixir/pages/mix-and-otp/task-and-gen-tcp.md @@ -1,6 +1,6 @@ # Task and gen_tcp -In this chapter, we are going to learn how to use [Erlang's `:gen_tcp` module](http://www.erlang.org/doc/man/gen_tcp.html) to serve requests. This provides a great opportunity to explore Elixir's `Task` module. In future chapters, we will expand our server so that it can actually serve the commands. +In this chapter, we are going to learn how to use Erlang's [`:gen_tcp` module](`:gen_tcp`) to serve requests. This provides a great opportunity to explore Elixir's `Task` module. In future chapters, we will expand our server so that it can actually serve the commands. ## Echo server diff --git a/lib/ex_unit/lib/ex_unit.ex b/lib/ex_unit/lib/ex_unit.ex index a4504d1e4b6..78b90f51d5b 100644 --- a/lib/ex_unit/lib/ex_unit.ex +++ b/lib/ex_unit/lib/ex_unit.ex @@ -14,7 +14,7 @@ defmodule ExUnit do # 2) Create a new test module and use "ExUnit.Case". defmodule AssertionTest do # 3) Note that we pass "async: true", this runs the tests in the - # test module concurrently with other test modules. The + # test module concurrently with other test modules. The # individual tests within each test module are still run serially. use ExUnit.Case, async: true @@ -311,7 +311,7 @@ defmodule ExUnit do * `:rand_algorithm` - algorithm to be used when generating the test seed. Available algorithms can be found in Erlang's - [`:rand`](https://www.erlang.org/doc/man/rand.html) documentation (see + [`:rand`](`:rand`) documentation (see [`:rand.builting_arg/0`](https://www.erlang.org/doc/apps/stdlib/rand.html#t:builtin_alg/0)). Available since v1.16.0. Before v1.16.0, the algorithm was hard-coded to `:exs1024`. On Elixir v1.16.0 and after, the default changed to `:exsss`; @@ -321,8 +321,8 @@ defmodule ExUnit do * `:seed` - an integer seed value to randomize the test suite. This seed is also mixed with the test module and name to create a new unique seed - on every test, which is automatically fed into the `:rand` module. This - provides randomness between tests, but predictable and reproducible + on every test, which is automatically fed into the [`:rand`](`:rand`) module. + This provides randomness between tests, but predictable and reproducible results. A `:seed` of `0` will disable randomization and the tests in each file will always run in the order that they were defined in; diff --git a/lib/mix/lib/mix/tasks/profile.eprof.ex b/lib/mix/lib/mix/tasks/profile.eprof.ex index fb25222fe17..b4fdbb7e8be 100644 --- a/lib/mix/lib/mix/tasks/profile.eprof.ex +++ b/lib/mix/lib/mix/tasks/profile.eprof.ex @@ -82,7 +82,7 @@ defmodule Mix.Tasks.Profile.Eprof do ## Caveats You should be aware that the code being profiled is running in an anonymous - function which is invoked by [`:eprof` module](https://www.erlang.org/doc/man/eprof.html). + function which is invoked by [`:eprof` module](`:eprof`). Thus, you'll see some additional entries in your profile output. It is also important to note that the profiler is stopped as soon as the code has finished running, and this may need special attention, when: running asynchronous code as function calls which were diff --git a/lib/mix/lib/mix/tasks/profile.fprof.ex b/lib/mix/lib/mix/tasks/profile.fprof.ex index a016d9de806..a53f7c5e809 100644 --- a/lib/mix/lib/mix/tasks/profile.fprof.ex +++ b/lib/mix/lib/mix/tasks/profile.fprof.ex @@ -93,7 +93,7 @@ defmodule Mix.Tasks.Profile.Fprof do ## Caveats You should be aware that the code being profiled is running in an anonymous - function which is invoked by [`:fprof` module](https://www.erlang.org/doc/man/fprof.html). + function which is invoked by [`:fprof` module](`:fprof`). Thus, you'll see some additional entries in your profile output, such as `:fprof` calls, an anonymous function with high ACC time, or an `:undefined` function which represents diff --git a/lib/mix/lib/mix/tasks/profile.tprof.ex b/lib/mix/lib/mix/tasks/profile.tprof.ex index fde9c5a3859..6a2b693e249 100644 --- a/lib/mix/lib/mix/tasks/profile.tprof.ex +++ b/lib/mix/lib/mix/tasks/profile.tprof.ex @@ -125,7 +125,7 @@ defmodule Mix.Tasks.Profile.Tprof do ## Caveats You should be aware that the code being profiled is running in an anonymous - function which is invoked by [`:tprof` module](https://www.erlang.org/doc/man/tprof.html). + function which is invoked by [`:tprof` module](`:tprof`). Thus, you'll see some additional entries in your profile output. It is also important to note that the profiler is stopped as soon as the code has finished running, and this may need special attention, when: running asynchronous code as function calls which were diff --git a/lib/mix/lib/mix/tasks/release.ex b/lib/mix/lib/mix/tasks/release.ex index bc317b6ff60..ba406ecec87 100644 --- a/lib/mix/lib/mix/tasks/release.ex +++ b/lib/mix/lib/mix/tasks/release.ex @@ -167,8 +167,8 @@ defmodule Mix.Tasks.Release do $ bin/RELEASE_NAME daemon In daemon mode, the system is started on the background via - [`run_erl`](https://www.erlang.org/doc/apps/erts/run_erl_cmd.html). You may also - want to enable [`heart`](https://www.erlang.org/doc/man/heart.html) + [`run_erl`](https://www.erlang.org/doc/apps/erts/run_erl_cmd.html). + You may also want to enable [`:heart`](`:heart`) in daemon mode so it automatically restarts the system in case of crashes. See the generated `releases/RELEASE_VSN/env.sh` file. diff --git a/lib/mix/lib/mix/tasks/test.coverage.ex b/lib/mix/lib/mix/tasks/test.coverage.ex index 4d86d6ddddb..c182a12f2ef 100644 --- a/lib/mix/lib/mix/tasks/test.coverage.ex +++ b/lib/mix/lib/mix/tasks/test.coverage.ex @@ -11,9 +11,9 @@ defmodule Mix.Tasks.Test.Coverage do ## Line coverage - Elixir uses Erlang's [`:cover`](https://www.erlang.org/doc/man/cover.html) - for its default test coverage. Erlang coverage is done by tracking - *executable lines of code*. This implies blank lines, code comments, + Elixir uses Erlang's [`:cover`](`:cover`) for its default test coverage. + Erlang coverage is done by tracking *executable lines of code*. + This implies blank lines, code comments, function signatures, and patterns are not necessarily executable and therefore won't be tracked in coverage reports. Code in macros are also often executed at compilation time, and therefore may not be covered.