2014年1月23日

erlang basics - installation

安裝 erlang 開發環境並不難,以下我們分 Windows 與 CentOS 兩種作業系統說明。

Windows

erlang otp downloads 頁面下載安裝檔,32 bits: esl-erlang_16.b.3-1~windows_i386.exe 或是 64 bits: esl-erlang_16.b.3-1~windows_amd64.exe,然後直接執行就可以了,erlang會安裝到 c:\Program Files\erl5.10.4。

記得要設定環境變數,可在 電腦->內容->進階系統設定->環境變數 這裡設定:

ERLANG_HOME=c:\Program Files\erl5.10.4
PATH=%ERLANG_HOME%\bin;%PATH%

CentOS 6

CentOS 安裝有三種方式,第一種是 rpm 安裝,第二種是直接由 source code 編譯,第三種是從 CEAN 下載安裝檔。

rpm 安裝檔

erlang otp downloads 頁面下載安裝檔,首先取得 rpm 安裝檔,32 bits: esl-erlang_16.b.3-1~centos~6_i386.rpm 或是 64 bits: esl-erlang_16.b.3-1~centos~6_amd64.rpm,接下來依照下面的 sript 進行安裝。

# 因為 erlang 有些 gui 工具介面
yum install wxGTK
# 因為 rpm 相關的套件,openssl 安裝到最新版 1.0.1e-16.el6_5.1 即可
yum install openssl
# install erlang
rpm -Uvh esl-erlang_16.b.3-1~centos~6_i386.rpm
# 安裝的目錄為 /usr/lib/erlang

由 source 編譯

如果要從 source code 編譯,先到 erlang otp downloads 頁面下載原始檔 otp_src_R16B03.tar.gz

tar zxvf otp_src_R16B03.tar.gz
cd otp_src_R16B03
./configure

執行後出現以下的警告,所以我們要先安裝一些套件
odbc : ODBC library - link check failed
wx : wxWidgets not found, wx will NOT be usable
documentation :
fop is missing.
Using fakefop to generate placeholder PDF files.

yum install fop unixODBC* openssl-devel
yum install wxGTK
./configure

執行後還是一樣,出現警告,這表示 wxGTK 套件要自己編譯
wx : wxWidgets not found, wx will NOT be usable

cd ..
wget http://sourceforge.net/projects/wxwindows/files/3.0.0/wxWidgets-3.0.0.tar.bz2/download
tar jxvf wxWidgets-3.0.0.tar.bz2
# 把剛剛裝的 wxGTK 移除
yum remove wxGTK
cd wxWidgets-3.0.0
# 安裝 opengl 相關套件
yum install mesa*
./configure --with-opengl --enable-debug --enable-unicode --enable-graphics_ctx 
make
make install
export LD_LIBRARY_PATH=/usr/local/lib
ldconfig

接下來就可以正常地把 erlang otp 裝好。

cd otp_src_R16B03
./configure
make
make install

CEAN

CEAN: Comprehensive Erlang Archive Network 將主要的 Erlang Application 都集中在一起,並提供各種 OS, CPU 編譯好的 binary files,應該是依照網頁的說明去安裝就好了,這種安裝方式,我沒有測試。

Erlang shell: erl

在 Windows 可以直接從 Menu 選單中執行 werl,這會出現 erlang 的 GUI console,也可以自己在命令提示字元中,執行 erl。

查閱 erlang otp 版本資訊

> erl -version
Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 5.10.4

啟動 erlang shell,直接執行 erl 即可,畫面上的 1> 是 erlang shell 的系統提示符號,每一次輸入一個 expression 就會累加變成 2>,可以用上、下方向鍵或是Ctrl+P/Ctrl+N,直接上下切換剛剛輸入的每一行資料。erlang expression 每一句都是以 . 句號結束,不一定要在同一行裡面就把整個 expression 寫完,erlang shell 會馬上把計算的結果列印在畫面上。

> erl
Erlang R16B03 (erts-5.10.4) [source] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V5.10.4  (abort with ^G)
1> 40.
40
2> 12 +
2> 5.
17
3> h().
1: 40
-> 40
2: 12 + 5
-> 17
ok
4> v(1)+v(2).
57
5> "a test.".
"a test."

shell functions

在 shell 直接打 help(). 可以列印出 shell 可使用的函數,以下列出常用的函數 。

6> help().
** shell internal commands **
b()        -- display all variable bindings 列印所有變數連結
f()        -- forget all variable bindings  移除所有變數連結
f(X)       -- forget the binding of variable X 移除某個變數連結
h()        -- history
v(N)       -- use the value of query <N>
** commands in module c **
bt(Pid)    -- stack backtrace for a process
c(File)    -- compile and load code in <File>
cd(Dir)    -- change working directory

help()     -- help info

i()        -- information about the system
ni()       -- information about the networked system
i(X,Y,Z)   -- information about pid <X,Y,Z>

l(Module)  -- load or reload module
lc([File]) -- compile a list of Erlang modules
ls()       -- list files in the current directory
ls(Dir)    -- list files in directory <Dir>

m()        -- which modules are loaded
memory()   -- memory allocation information

nc(File)   -- compile and load code in <File> on all nodes
nl(Module) -- load module on all nodes

pid(X,Y,Z) -- convert X,Y,Z to a Pid
pwd()      -- print working directory
q()        -- quit - shorthand for init:stop()

quitting shell

要離開 shell 有幾種方式:

  1. 使用 q()init:stop()
    q() 是 init:stop() 的簡寫,這是最安全的跳出方式。

  2. Ctrl-G
    Ctrl-G 可打開使用者命令選單,鍵入 Ctrl-G 的時候,會出現 User switch command --> 的提示字元,再鍵入 h 或 ? 可以列印所有的指令。

    這個功能在 linux 裡面的 erl 有作用,在 windows 的 werl 也有作用,但 windows 的 erl 卻是直接產生一個新的 shel。我還沒找到要怎麼在 windows erl 打開這個功能的熱鍵。

     6>
     User switch command
      --> h
       c [nn]            - connect to job
       i [nn]            - interrupt job
       k [nn]            - kill job
       j                 - list all jobs
       s [shell]         - start local shell
       r [node [shell]]  - start remote shell
       q                 - quit erlang
       ? | h             - this message
  3. BREAK
    在 linux 可以按 Ctrl-C,Windows 的 werl 可以按 Ctrl-Break,這會出現 BREAK 選單,進入選單後,再以 (a) 退出系統 (c) 返回 shell (v) 列印目前 erlang 的版本 (k) 可瀏覽所有 erlang 內部活動,並強制關閉某個故障的 process。BREAK 選單位於底層,可以在 Ctrl-G 之後,再呼叫出 BREAK 選單。

     BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
            (v)ersion (k)ill (D)b-tables (d)istribution

process處理

如果有某個 process crash,或不慎進入了無窮迴圈,我們可以在 Ctrl-G User switch command 裡面,進行處理。

以 timer:sleep(infinity) 模擬無窮迴圈的狀況。

Eshell V5.10.4  (abort with ^G)
1> timer:sleep(infinity).

這時候,shell 會被鎖死,不管打什麼指令都沒有反應,按 Ctrl-G 進入 user switch command。

j 列出目前的 process
s 啟動一個新的 process
c 2 連接到新的、正常的 process

User switch command
 --> j
   1* {shell,start,[init]}
 --> s
 --> j
   1  {shell,start,[init]}
   2* {shell,start,[]}
 --> c 2

進入第二個 process 後

k 1 把第一個掛掉的 process 砍掉
c 連接到目前預設的 process(有 * 記號)

Eshell V5.10.4  (abort with ^G)
1>
User switch command
 --> j
   1  {shell,start,[init]}
   2* {shell,start,[]}
 --> k 1
 --> j
   2* {shell,start,[]}
 --> c

1>

erlide in Eclipse

在 Help -> Install new software 裡面把 http://erlide.org/update 網址貼到安裝網址上,選擇安裝 Erlang IDE 與 Erlang add-ins。在 Window -> Preference -> Erlang -> Installed runtimes 裡面,可看到 erlide 有自動找到 erlang runtimes。

erlide 是個好用的開發 ide,但當我們把 eclipse 直接關閉時,在 eclipse 的 working directory 會出現一個檔名類似 rpc_monitor-20140108_155607.dump 的檔案,這個 dump 檔,有時後會出現 erl_crash.dump。

erlide 對錯誤訊息的列印還有些問題,一直看不到結果的時候,原因應該跟 No error message in Eclipse consloe/erang shell 一樣,因為 erlide 並不是直接跟 shell 互動,而是透過一層遠端呼叫,再呼叫 shell,這個問題到現在還沒解決。

erlide 好用,但以上面的問題來看,程式測試可能還是要回到 console 自己用 erl 測試,才會得到比較確切的回應結果。

調整開發環境

設定載入程式碼的搜尋路徑

  1. @spec code:get_patha(Dir) -> true | {error, bad_directory}
    將新目錄加入到載入路徑的頭
  2. @spec code:get_pathz(Dir) -> true | {error, bad_directory}
    將新目錄加入到載入路徑的尾
  3. @spec code:get_path() -> [string()]
    得知目前載入路徑
  4. @spec code:all_loaded()
    得知目前所有載入的模組
  5. @spec code:clash()

當系統開始時,執行一組命令 .erlang

在 home 目錄,放一個 .erlang 檔案,當 erl 啟動時,會先讀入此檔案,且執行裡面的內容。

如果是在 Windows ,則把檔案放在 c:\Users{username}\ 這個目錄中。

%% .erlang
io:format("Running Erlang~n").
code:add_patha(".").
code:add_pathz("/home/bin").

啟動 erl 時會看到

>erl
Running Erlang
Eshell V5.10.4  (abort with ^G)
1> code:get_path().
[".","c:/PROGRA~1/ERL510~1.4/lib/kernel-2.16.4/ebin",
 "c:/PROGRA~1/ERL510~1.4/lib/stdlib-1.19.4/ebin",
 "c:/PROGRA~1/ERL510~1.4/lib/xmerl-1.3.5/ebin",
 "c:/PROGRA~1/ERL510~1.4/lib/wx-1.1.1/ebin",
 "c:/PROGRA~1/ERL510~1.4/lib/webtool-0.8.9.2/ebin",
 [...]|...]

另一種方式,也可以在 erl 加上參數 -pa -pz ,將搜尋路徑加入到路徑的頭或尾

erl -pa Dir1 -pa Dir2 ... -pz DirK1 -pz DirK2

crash dump

如果 erlang 當機,會產生一個 erl_crash.dump 的檔案,如果要分析此 dump,有一個網頁版的 dump 分析器

>erl
Running Erlang
Eshell V5.10.4  (abort with ^G)
1> webtool:start().
WebTool is available at http://localhost:8888/
Or  http://127.0.0.1:8888/
{ok,<0.35.0>}
2>

然後在瀏覽器瀏覽網址 http://localhost:8888/ ,就可以啟動 CrashDumpViewer 上傳並分析 erl_crash.dump。

escript

escript 可直接執行用 erlang 寫的 script file,在 linux 環境,可以直接編輯一個執行檔

>vi hello
#!/usr/bin/env escript
main(_) ->
    io:format("Hello World.~n").
>chmod 755 hello
>./hello
Hello World.

在 Windows 環境

% file: hello.escript
main(_) ->
    io:format("Hello World.~n").

可直接在命令提示字元中,執行此 script

>escript hello.escript
Hello World.

參考

Erlang and OTP in Action
Programming Erlang: Software for a Concurrent World