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 的隐藏特性的主要内容,如果未能解决你的问题,请参考以下文章