2021 年你需要知道的关于 Erlang 的一切
- admin
- 07 Jan 2024
今天,我们将看一个相当古老且有些古怪的东西。 你们大多数人可能没有注意到的语言。 虽然 Erlang 不像某些现代编程语言那样流行,但它安静地运行着 WhatsApp 和微信等每天为大量用户提供服务的应用程序。 在这篇文章中,我将告诉你关于这门语言的更多事情、它的历史,以及你是否应该考虑自己学习它。 ## 什么是 Erlang,它在哪里使用? Erl
Read More立即跳转到您正在寻找的模块。
专注于重要的事情,放弃其余的。
快速插入参数化、可重用的代码片段。
使用类型信息进行 Erlang 程序的类型注释。
Call Hierarchy 功能可让您探索给定函数的调用者(称为传入调用),以及显示给定函数调用了哪些函数(称为传出调用)。
有关调用层次结构的概述,请观看此视频。
要显示 Call Hierarchy 面板,请右键单击函数名称并选择 Show Call Hierarchy。 您可以使用新打开的面板在调用层次结构中导航。
要在传入调用和传出调用之间切换,只需使用面板右上角的call图标。
该功能由 lsp-treemacs 包提供。
要显示传入调用层次结构:
M-x lsp-treemacs-call-hierarchy
要显示传出调用层次结构:
C-u M-x lsp-treemacs-call-hierarchy
有关更多信息,请参阅官方 lsp-treemacs 文档。
代码操作是一种在错误或警告旁边为用户提供可能的纠正操作的机制。 如果有可用的操作,错误或警告旁边会出现一个灯泡或类似图标。 当用户单击灯泡(或点击快捷方式)时,会显示可用代码操作的列表。
目前 Erlang LS 支持以下代码操作:
可以通过名为 erlang_ls.config 的配置文件自定义 erlang_ls 服务器的行为。 erlang_ls.config 文件应放置在给定项目的根目录中,以存储该项目的配置。
示例 erlang_ls.config 文件如下所示:
otp_path: "/path/to/otp/lib/erlang"
deps_dirs:
- "lib/*"
diagnostics:
enabled:
- crossref
disabled:
- dialyzer
include_dirs:
- "include"
- "_build/default/lib"
lenses:
enabled:
- ct-run-test
disabled:
- show-behaviour-usages
macros:
- name: DEFINED_WITH_VALUE
value: 42
- name: DEFINED_WITHOUT_VALUE
code_reload:
node: node@example
文件格式为 yaml。
可以进行以下自定义:
参数 | 说明 |
---|---|
apps_dirs | 包含项目应用程序的目录列表。它支持通配符。 |
code_reload | 是否应该对远程节点进行 rpc 调用以编译和重新加载模块 |
deps_dirs | 包含依赖项的目录列表。它支持通配符。 |
diagnostics | 自定义活动诊断列表。请参阅下面的可用诊断列表。 |
include_dirs | 作为包含目录提供给编译器的目录列表。它支持通配符。 |
incremental_sync | 是否支持客户端中文本更改的增量同步。默认启用。 |
lenses | 自定义活动code lenses列表 |
macros | 要传递给编译器的自定义宏列表,表示为名称/值对。如果该值被省略或无效,则使用“真”。 |
otp_apps_exclude | 不会被索引的 OTP 应用程序列表(默认:megaco、diameter、snmp、wx) |
otp_path | OTP 安装路径 |
plt_path | Dialyzer PLT 文件的路径。如果没有提供,Dialyzer诊断将不可用。 |
code_path_extra_dirs | erlang_ls 将使用代码add_path/1添加的通配符路径列表 |
elvis_config_path elvis.config | 文件的路径。默认为 ROOT_DIR/elvis.config |
exclude_unused_includes | 从 Unused Includes 警告中排除的包含文件列表 |
compiler_telemetry_enabled | 启用后,发送telmetry/event LSP 消息,其中包含文件中存在的任何诊断的代码字段。默认为假。 |
打开或保存文件时,会在后台运行诊断列表,将代码库的最终问题报告给编辑器。 可以使用以下诊断:
诊断名称 | 用途 | 默认值 |
---|---|---|
bound_var_in_pattern | 报告已在模式中绑定的变量(受 pinning 运算符的启发) | enabled |
compiler | 报告来自 Erlang 编译器的内联警告和错误 | enabled |
crossref | 使用来自 Erlang LS 数据库的信息来找出未定义函数 | disabled |
dialyzer | 使用 dialyzer 静态分析工具查找代码中的差异 | enabled |
elvis | 使用 elvis 查看 Erlang 代码的样式 | enabled |
unused_includes | 警告包含但未使用的头文件 | enabled |
unused_macros | 警告已定义但未使用的宏 | enabled |
可以为特定项目定制诊断。 例如:
diagnostics:
disabled:
- dialyzer
enabled:
- crossref
code_reload 采用以下选项:
参数 | 描述 |
---|---|
node | 为代码重新加载而调用的节点。 例如 erlang_ls@hostname |
Code Lenses 也可以在 Erlang LS 中使用。 Erlang LS 提供以下lenses:
Code Lens 名称 | 用途 |
---|---|
ct-run-test | 在通用测试用例旁边显示一个运行按钮 |
function-references | 显示对函数的引用数 |
server-info | 在每个模块的顶部显示一些 Erlang LS 服务器信息。 仅用于调试。 |
show-behaviour-usages | 显示实现行为的模块数量 |
suggest-spec | 使用来自Dialyzer的信息来建议spec |
默认启用以下code lenses:show-behaviour-usage 可以为特定项目定制code lenses。 例如:
lenses:
enabled:
- ct-run-test
disabled:
- show-behaviour-usages
也可以将系统范围的默认配置存储在位于 User Config 目录中的 erlang_ls.config 文件中。 User Config 目录的确切位置取决于所使用的操作系统,可以通过在 Erlang shell 上执行以下命令来识别它:
> filename:basedir(user_config, "erlang_ls").
通常,User Config 目录的位置是:
操作系统 | User Config 目录 |
---|---|
Linux | /home/USER/.config/erlang_ls |
OS X | /Users/USER/Library/Application\ Support/erlang_ls |
Windows | c:/Users/USER/AppData/Local/erlang_ls |
因此,例如在 Linux 上,默认配置文件的完整路径是 /home/USER/.config/erlang ls/erlang ls.config
许多 Erlang 存储库都遵循相同的结构。 我们在本节中包含了常见的 Erlang LS 配置,以便于重用。
以下配置可用于大多数基于 rebar3 的项目。
apps_dirs:
- "_build/default/lib/*"
include_dirs:
- "_build/default/lib/*/include"
- "include"
如果您的 rebar3 项目包含多个应用程序(例如,在应用程序文件夹中),您可能需要调整您的 Erlang LS 配置,如下所示。
apps_dirs:
- "apps/*"
deps_dirs:
- "_build/default/lib/*"
include_dirs:
- "apps"
- "apps/*/include"
- "_build/default/lib/"
- "_build/default/lib/*/include"
为了能够在 erlang/otp 存储库中使用主要的 Erlang LS 功能,以下最小配置就足够了。
otp_path: "/path/to/otp"
apps_dirs:
- "lib/*"
include_dirs:
- "lib"
- "lib/*/include"
Boost your Productivity with the Erlang Language Server
2020-09-11 Code BEAM Stockholm (Virtual)
为编程语言实现自动完成或转到定义等功能并非易事。 传统上,必须为每个开发工具重复这项工作,并且需要目标编程语言和所选开发工具内部使用的编程语言的专业知识组合。
一个绝妙的直觉,“语言服务器协议”(LSP),改变了游戏规则。 对 Erlang 社区来说是一个真正的祝福。
提及 Erlang LS 的学术论文列表如下:
Erlang LS 通过Debug Adapter Protocol(简称 DAP)提供调试功能。 鉴于协议与编辑器无关的特性,所有支持 DAP 协议的文本编辑器和 IDE 都可以进行调试。 这是 Emacs 中调试会话的样子:
当前的底层实现基于 Erlang/OTP 附带的 Erlang 解释器。 顺便说一句,官方 OTP 调试器也由同一个解释器提供支持。
在本教程中,我们将引导一个示例项目,看看我们如何使用 Erlang LS 调试我们的代码。
Erlang LS 中通过名为 els_dap 的单独可执行文件(Erlang escript)提供了调试功能。
该可执行文件与 Erlang LS 扩展捆绑在一起,因此不需要任何额外的安装步骤。 您可以通过指定不同的 DAP 路径来配置 Erlang LS 扩展以使用自定义版本的调试器:
Extension Settings > DAP Path
如果您使用的是 Emacs,那么您很可能是从源代码构建 Erlang LS。 要生成 els_dap 脚本:
rebar3 as dap escriptize
或者简单地说:
make
然后,您将在以下位置找到 els_dap 脚本:
_build/dap/bin/els_dap
确保生成的 els_dap escript 位于 Emacs 已知的 PATH 中。
官方 dap-mode 包支持 Erlang,因此需要该包和 Erlang 插件:
(require 'dap-mode)
(require 'dap-erlang)
您可以参考官方 dap-mode 文档以获取有关如何安装和配置 dap-mode 软件包及其插件的更多信息。
为了展示 Erlang LS 调试器,我们将使用 Cowboy 网络服务器中的 Hello World 示例。 让我们从clone项目开始:
git clone https://github.com/ninenines/cowboy.git
cd cowboy/examples/hello_world
该项目使用 erlang.mk 构建系统和 relx 发布汇编器。 为了能够在我们的示例项目中使用调试器,我们需要对项目进行两个小的修改:
要将调试器添加为依赖项,请将以下行添加到项目的 Makefile 中的 include ../../erlang.mk 行之前:
LOCAL_DEPS = debugger
要对应用程序进行符号链接,请将以下行添加到 relx.config 文件中:
{overrides, [{hello_world, "../hello_world"}]}.
我们现在可以运行我们的网络服务器:
make run
以上应该会导致终端中运行一个新的 Erlang 节点,名为 hello_world_example@[HOSTNAME]。
我们现在应该可以将浏览器指向 http://localhost:8080 以查看我们辉煌的 Hello world!字符串。
让我们保持服务器运行。 打开一个新终端并继续执行以下步骤。
我们需要告诉调试器如何连接到正在运行的节点。 我们将通过启动配置来做到这一点。
导航到 Run and Debug 面板并单击 Create a launch.json file 链接并选择 Erlang OTP Debugger 选项。
这将在 .vscode/launch.json 中创建一个文件。 将文件内容替换为以下内容:
{
"version": "0.2.0",
"configurations": [
{
"name": "Existing Erlang Node",
"type": "erlang",
"request": "attach",
"projectnode": "hello_world_example",
"cookie": "hello_world_example",
"timeout": 300,
"cwd": "${workspaceRoot}"
}
]
}
我们需要在项目的顶层目录中创建一个名为 launch.json 的文件。 在我们的例子中,该文件将驻留在 cowboy/examples/hello_world/launch.json 中:
{
"version": "0.2.0",
"configurations": [
{
"name": "Existing Erlang Node",
"type": "erlang",
"request": "attach",
"projectnode": "hello_world_example",
"cookie": "hello_world_example",
"timeout": 300
}
]
}
访问 src/toppage_h.erl 文件并通过单击与 init/2 函数体的第一行对应的行号旁边的来添加断点。
导航到 src/toppage_h.erl,移动到 init/2 函数体的第一行并运行:
M-x dap-breakpoint-add
今天,我们将看一个相当古老且有些古怪的东西。 你们大多数人可能没有注意到的语言。 虽然 Erlang 不像某些现代编程语言那样流行,但它安静地运行着 WhatsApp 和微信等每天为大量用户提供服务的应用程序。 在这篇文章中,我将告诉你关于这门语言的更多事情、它的历史,以及你是否应该考虑自己学习它。 ## 什么是 Erlang,它在哪里使用? Erl
Read More这篇文章探讨了 Erlang/OTP 25 中基于类型的新优化,其中编译器将类型信息嵌入到 BEAM 文件中,以帮助JIT(即时编译器)生成更好的代码。 ## 两全其美 OTP 22 中引入的基于SSA的编译器处理步骤进行了复杂的类型分析,允许进行更多优化和更好的生成代码。然而,Erlang 编译器可以做什么样的优化是有限制的,因为 BEAM 文件必须
Read More自从Erlang 存在,就一直有让它更快的需求和野心。这篇博文是一堂历史课,概述了主要的 Erlang 实现以及如何尝试提高 Erlang 的性能。 ## Prolog 解释器 Erlang 的第一个版本是在 1986 年在 Prolog 中实现的。那个版本的 Erlang 对于创建真正的应用程序来说太慢了,但它对于找出Erlang语言的哪些功能有用,哪
Read More