我只想知道当你刚接触 Erlang 时,你和最终解决方案之间的所有小问题。
例如,这是我遇到的第一个减速带:
- 如果您在多个线程中生成,请使用 control_process(Socket, Pid)。正确的数据包到正确的线程。
- 您要开始与另一台服务器通话吗?记住 net_adm:ping('car@bsd-server')。在外壳中。否则无法进行任何沟通。
- Timer:sleep(10),如果你什么都不想做。调试时总是有用的。
我只想知道当你刚接触 Erlang 时,你和最终解决方案之间的所有小问题。
例如,这是我遇到的第一个减速带:
Learning to browse the standard documentation
Once you learn how the OTP documentation is organised it becomes much easier to find what you're looking for (you tend to need to learn which applications provide which modules or kinds of modules).
Also just browsing the documentation for applications is often quite rewarding - I've discovered lots of really useful code this way - sys
, dbg
, toolbar
, etc.
The difference between shell erlang and module erlang
Shell erlang is a slightly different dialect to module erlang. You can't define module functions (only funs), you need to load record definitions in order to work with records (rr/1
) and so on. Learning how to write erlang code in terms of anonymous functions is somewhat tricky, but is essential for working on production systems with a remote shell.
Learning the interaction between the shell and {start,spawn}_link ed processes - when you run some shell code that crashes (raises an exception), the shell process exits and will broadcast exit signals to anything you linked to. This will in turn shut down that new gen_server you're working on. ("Why does my server process keep disappearing?")
The difference between erlang expressions and guard expressions
Guard expressions (when clauses) are not Erlang expressions. They may look similar, but they're quite different. Guards cannot call arbitrary erlang functions, only guard functions (length/1
, the type tests, element/2
and a few others specified in the OTP documentation). Guards succeed or fail and don't have side effects. Erlang expressions on the other hand can do what they like.
Code loading
Working out when and how code upgrades work, the incantation to get a gen_server to upgrade to the latest version of a callback module (code:load(Mod), sys:suspend(Pid), sys:change_code(Pid, Mod, undefined, undefined), sys:resume(Pid).
).
The code server path (code:get_path/0
) - I can't count how many times I ran into undefined function errors that turned out to be me forgetting to add an ebin directory to the code search path.
Building erlang code
Working out a useful combination of emake (make:all/0
and erl -make
) and gnu make took quite a long time (about three years so far :).
My current favourite makefiles can be seen at http://github.com/archaelus/esmtp/tree/master
Erlang distribution
Getting node names, dns, cookies and all the rest right in order to be able to net_adm:ping/1
the other node. This takes practise.
Remote shell IO intricacies
Remembering to pass group_leader()
to io:format
calls run on the remote node so that the output appears in your shell rather than mysteriously disappearing (I think the SASL report browser rb
still has a problem with sending some of its output to the wrong node when used over a remote shell connection)
将它集成到 msvc 6 中,这样我就可以使用编辑器,并在输出窗口中查看结果。
我创建了一个工具,
命令- erlc 的路径
参数- +debug_info $(FileName)$(FileExt)
初始目录- $(fileDir)
选中使用输出窗口。
控制进程()
如果您在多个线程中生成,请使用 control_process(Socket, Pid)。正确的数据包到正确的线程。
net_adm:ping()
您要开始与另一台服务器通话吗?记住 net_adm:ping('car@bsd-server')。在外壳中。否则无法进行任何沟通。
定时器:睡眠()
暂停 X 毫秒。
让我花最多时间思考的事情就是完全围绕函数调用和消息传递来构建我的代码的想法。其余部分要么只是从那里掉出来(生成,远程节点),要么感觉就像你必须用任何新语言(语法,stdlib)学习的常见东西。