Erlang 的隐藏特性

Posted

技术标签:

【中文标题】Erlang 的隐藏特性【英文标题】:Hidden Features of Erlang [closed] 【发布时间】:2010-11-07 00:04:03 【问题描述】:

本着:

C# 的隐藏特性 Java 的隐藏特性 ASP.NET 的隐藏特性 Python 的隐藏特性 html 的隐藏特性 和其他隐藏功能问题

每个 Erlang 开发者都应该了解的 Erlang 隐藏特性有哪些?

请每个答案一个隐藏功能。

【问题讨论】:

请社区维基这个。 我建议在此添加一个 hidden-features 标签,并将其他语言的隐藏功能的注释链接到这些问题。 @Olafur 怎么样?帮助! @Avihu 完成。感谢您的建议! :) 【参考方案1】:

继承! http://www.erlang.se/euc/07/papers/1700Carlsson.pdf

父母

-module(parent).
-export([foo/0, bar/0]).

foo() ->
    io:format("parent:foo/0 ~n", []).

bar() ->
    io:format("parent:bar/0 ~n", []).

孩子

-module(child).
-extends(parent).
-export([foo/0]).

foo() ->
    io:format("child:foo/0 ~n", []).

控制台

23> parent:foo().
parent:foo/0 
ok
24> parent:bar().
parent:bar/0 
ok
25> child:foo().
child:foo/0 
ok
26> child:bar().
parent:bar/0 
ok

【讨论】:

不知道,很有用,谢谢! 是的。有趣的!虽然我没有在我使用过的任何库中看到它...... 但是不欢迎使用参数化模块:它们将变量添加到函数中,并且在调试它们时并不好。它们打破了函数范式,增加了您应该跟踪的变量(如命令式语言中的全局变量)引入的复杂性,它们是不可变的,但破坏了透明度。有人认为它们(参数化模块)仍然存在于语言中,因为产品使用它们,mochiweb 就是一个例子。试想一下,为什么在 2003 年出现它们仍然没有正式记录? 此评论属于“参数化模块”答案...【参考方案2】:

shell 中的魔法命令。完整列表在the manual,但我用得最多的是:

f() - 忘记所有变量 f(X) - 忘记 X v(42) - 调用第 42 行的结果 v(-1) - 上一行的召回结果 e(-1) - 重新执行上一行的表达式 rr(foo) - 从模块 foo 中读取记录定义 rr("*/*") - 从每个子目录中的每个模块读取记录定义 rp(expression) - 打印带有记录格式的完整表达式

【讨论】:

并使用 rp(expression(...)) 打印出结果,而不是漂亮地打印太深的嵌套结构,而是完全打印它【参考方案3】:

参数化模块!来自http://www.lshift.net/blog/2008/05/18/late-binding-with-erlang 和http://www.erlang.se/euc/07/papers/1700Carlsson.pdf

-module(myclass, [Instvar1, Instvar2]).
-export([getInstvar1/0, getInstvar2/0]).
getInstvar1() -> Instvar1.
getInstvar2() -> Instvar2.

Eshell V5.6  (abort with ^G)
1> Handle = myclass:new(123, 234).
myclass,123,234
2> Handle:getInstvar1().
123
3> Handle:getInstvar2().
234

【讨论】:

我在尝试了解 mochiweb 源代码时发现了这一点。花了一段时间在谷歌上搜索它到底在做什么,因为语法与我以前见过的 Erlang 完全不同。 这很有趣!我也是第一次在 mochiweb 上看到它。将此与继承相结合可能会产生一些有趣的可能性...... 如果您想知道否决票的情况,这是一个意外,请查看this meta topic。我将编辑您的问题,以便将其删除。【参考方案4】:

user_default.erl - 你可以通过在你的路径中有一个编译好的 user_default.beam 来构建你自己的 shell 内置函数,这可能非常漂亮

【讨论】:

【参考方案5】:

beam_lib:chunks 可以从使用 debug 编译的梁中获取源代码,这非常有用

ok,_,[abstract_code,_,AC] = beam_lib:chunks(Beam,[abstract_code]).
  io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).

【讨论】:

【参考方案6】:

端口,外部的或链接的,接受称为 io-lists 的东西来向它们发送数据。 io-list 是 0..255 范围内的二进制或(可能很深)二进制或整数列表。

这意味着,与其在将两个列表发送到端口之前将它们连接起来,不如将它们作为列表中的两个项目发送。所以不是

"foo" ++ "bar"

一个人做

["foo", "bar"]

在这个例子中,它当然是微不足道的。但是 iolist 本身允许在创建输出数据时进行方便的编程。例如 io_lib:format/2,3 本身返回一个 io 列表。

函数 erlang:list_to_binary/1 接受 io 列表,但现在我们有 erlang:iolist_to_binary/1 可以更好地传达意图。还有一个 erlang:iolist_size/1。

最好的,因为文件和套接字是作为端口实现的,所以您可以向它们发送 iolist。无需展平或附加。

【讨论】:

【参考方案7】:

可以使用 ets:fun2ms(...) 构建匹配规范,其中使用 Erlang 有趣的语法并将其转换为具有解析转换的匹配规范。

1> ets:fun2ms(fun(Foo, _, Bar) when Foo > 0 -> Foo, Bar end).
['$1','_','$2',['>','$1',0],['$1','$2']]

因此没有构建任何有趣的值,表达式在编译时被匹配规范替换。有趣的可能只是匹配表达式可以做的事情。

此外,ets:fun2ms 可在 shell 中使用,因此可以轻松测试 fun 表达式。

【讨论】:

【参考方案8】:

.erlang_hosts 提供了一种跨机器共享名称的好方法

【讨论】:

【参考方案9】:

不一定是“隐藏”,但我不经常看到这一点。匿名函数可以有多个子句,就像模块函数一样,即

-module(foo).
-compile(export_all).

foo(0) -> "zero";
foo(1) -> "one";
foo(_) -> "many".

anon() ->
    fun(0) ->
            "zero";
       (1) ->
            "one";
       (_) ->
            "many"
    end.


1> foo:foo(0).
"zero"
2> foo:foo(1).
"one"
3> foo:foo(2).
"many"

4> (foo:anon())(0).
"zero"
5> (foo:anon())(1).
"one"
6> (foo:anon())(2).
"many"

【讨论】:

【参考方案10】:

gen___tcp 和 ssl 套接字有一个 packet, Type 套接字选项来帮助解码许多协议。 erlang:decode_packet/3 函数很好地描述了各种 Type 值可以是什么以及它们的作用。

与 active, once 或 active, true 设置一起,每个框架值将作为单个消息传递。

示例:iserve 大量使用数据包 http 模式,ifastcgi 大量使用数据包 fcgi 模式。我可以想象很多其他的http服务器也使用包http。

【讨论】:

【参考方案11】:

.erlang 可以在 shell 启动时预加载库和运行命令,您还可以通过在节点名称上执行 case 语句来为特定节点执行特定命令。

【讨论】:

【参考方案12】:

如果要在列表推导中执行多个表达式,可以使用块。例如:

> [begin erlang:display(N), N*10 end || N <- lists:seq(1,3)].
1
2
3
[10,20,30]

【讨论】:

【参考方案13】:

可以定义自己的迭代器供 QLC 使用。例如,可以将来自 SQL 查询的结果集制成 QLC 表,从而受益于 QLC 查询的特性。

除了 mnesia 表之外,dets 和 ets 还具有 table/1,2 函数来为它们返回这样的“查询句柄”。

【讨论】:

【参考方案14】:

在选择 Erlang 作为开发平台时,不是那么隐蔽,而是最重要的方面之一:

可以在活动节点(服务中)上增强跟踪并成为最好的调试之一!

【讨论】:

【参考方案15】:

您可以隐藏 Erlang 节点,方法是:

erl -sname foo -hidden

你仍然可以连接到节点,但它不会出现在nodes/0返回的列表中。

【讨论】:

【参考方案16】:

与追加操作符匹配:

"pajamas:" ++ Color = "pajamas:blue"

Color 现在的值是“blue”。请注意,此技巧有其局限性 - 据我所知,它仅适用于上述顺序的单个变量和单个常量。

【讨论】:

【参考方案17】:

Hot code loading. 来自维基。

代码作为“模块”单元加载和管理,模块是一个编译单元。系统可以同时在内存中保存一个模块的两个版本,并且进程可以同时运行每个版本的代码。

版本被称为“新”和“旧”版本。进程在对其模块进行外部调用之前不会进入新版本。

【讨论】:

这是一个隐藏功能吗?肯定是一个显着的功能,但这是该语言的主要吹嘘点之一,根本没有隐藏。 但是为什么没有投票呢? :D

以上是关于Erlang 的隐藏特性的主要内容,如果未能解决你的问题,请参考以下文章

SpaceVim 语言模块 erlang

Rust学习--变量

akka 与 Erlang 相比如何? [关闭]

Erlang/OTP 18.0 正式版发布

erlang的热更新

消息队列集群配置