2010-02-18 65 views
3

我能看到爲什麼參數化的模塊使用了這麼多,因爲他們讓我們做這樣的事情:Erlang中有哪些參數化模塊可供選擇?

X = y:new("param"). 

X:action1(). 
X.get_property(): 

:這感覺非常OO。然而,這只是Erlang的一個實驗性功能,我聽說它可能會被刪除,所以我需要找到一個替代方案。

+0

你能否試着解釋你想要達到什麼目的?某種可以用OO語言解決的問題,可能可以在Erlang中以完全不同的方式解決...... – 2010-02-18 18:48:48

+0

我試圖構建一個易於使用的客戶端API,並且參數化模塊在很大程度上提供了此功能。 – Zubair 2010-02-18 19:37:33

回答

12

參數化模塊不過是函數第一個參數的快捷方式。看到這兩個例子:

-module(y, [Name,Age]). 
-compile(export_all). 

action1() -> io:format("Hello, ~p!~n",[Name]). 

get_age() -> Age. 

運行:

1> c(y). 
{ok,y} 
2> X = y:new("Fred",22). 
{y,"Fred",22} 
3> X:action1(). 
Hello, "Fred"! 
ok 
4> X:get_age(). 
22 

現在沒有參數化的東西:

-module(y). 
-compile(export_all). 

action1([Name,_]) -> io:format("Hello, ~p!~n",[Name]). 

get_age([_,Age]) -> Age. 

運行它:

1> c(y). 
{ok,y} 
2> X = ["Fred",22]. 
["Fred",22] 
3> y:action1(X). 
Hello, "Fred"! 
ok 
4> y:get_age(X). 
22 

最大的 '優勢' 的參數化模塊是你轉移b承載從變量到模塊名稱的狀態。對於不習慣'Erlang方式'的人來說,這看起來要簡單得多,但它與傳統的代碼風格相沖突。

這不僅僅是一個試驗與否的問題。你拋出了引用透明度,並且對不可變變量的語義變得有點奇怪。這方面的一個很好的例子是想象你添加以下功能到參數化模塊:

ret_fn() -> fun(Age) -> Age + 5 end. 

當編譯模塊,你得到的警告./y.erl:8: Warning: variable 'Age' shadowed in 'fun'。這是警告您,您正在匿名函數的head子句中使用預定義變量的名稱。但是,快速查看ret_fn/0函數顯示該變量的來源絕對沒有標誌。

現在假設您使用變量Name用於任何其他目的;你會得到一個運行時錯誤告訴你** error: no match of right hand side value <...>

我正在做的一點是,參數化模塊減少了打字量,您需要做的是犧牲邏輯簡單。不僅適用於您,還適用於其他Erlang程序員處理您的代碼。

最重要的是,透析器,TypEr,tidiers等工具並不能保證支持這些習語。這些工具也非常有用!不要解僱他們。 (編輯:Erlang(R13B04 +)的更新版本現在保證支持)

參數化模塊的最佳選擇是避開它們並使用mochiweb以外的其他每個Erlang編程器正在使用的內容。

+0

我想到了,你是對的。我只是通過使用參數化函數而成爲懶惰#$ rd,我不應該使用它們。但是所有使用它們的系統呢?他們爲什麼使用這些無證的功能 – Zubair 2010-02-18 19:14:00

+0

我真的不知道他們爲什麼使用它。來自freenode的#erlang頻道的其他人也不知道。我認爲它可能已經完成,使圖書館的用戶在概念上更簡單。我認爲執行'my_func(Mod) - > Mod:Call(Args)end'的簡單性與my_func(Mod,X) - > Mod:Call(X,Args) end'。除此之外,我在答覆中提到的問題,除了糟糕的決策或想要試驗代碼之外,我無法考慮其他問題。 – 2010-02-18 19:23:40

+0

但是我並沒有理解你對「ret_fn() - > fun(Age) - > Age + 5 end」所說的話。「這是因爲「年齡」作爲參數傳入模塊? – Zubair 2010-02-18 19:47:17

2

爲什麼不能使用通常的方式,即將消息發送到與模塊關聯的(註冊)服務器進程?

有問題的信息可以是任何你想要的,例如,配置等

你試圖解決什麼問題,不能用這種方式處理?

+0

以某個關鍵值存儲庫的客戶端庫爲例: {ok,C} = lib:client_connect(「ip address」)。
C:list_keys()。
C:get(Value)。
:看起來很方便。 – Zubair 2010-02-18 18:53:54

+0

這裏沒有太大的區別:lib:list_keys(C)lib:get(C,Value)。而且你知道被執行的代碼在哪裏啓動! – Lukas 2010-02-18 18:57:03

+0

你的權利。我不得不使用該功能。 – Zubair 2010-02-18 19:27:59