2014-10-06 58 views
0

我是Elixir/Erlang編程中的新成員。模塊特性Elixir

如何實現Elixir模塊的模塊屬性,以便我的模塊的用戶可以在模塊構造函數中設置。

例如,

defmodule Config do 
    some_property: nil 
    other_property: nil 

    def constructor(one, two) do 
     some_property = one 
     other_property = two 
    end 

    def get_property_one do 
     some_property 
    end 
end 

謝謝

+0

除了下面的答案,你可能會認爲默認的getters/setters(即使在OO中)也有點代碼味道,我。即他們有點打破封裝,因爲默認情況下它們揭示了該類的內部細節。 getters/setters沒有什麼本質上的錯誤 - 他們只需要小心使用。 – 2014-10-06 15:39:13

回答

5

藥劑模塊沒有在他們裏面定義的類和變量沒有屬性,所以不存在這樣的事情構造函數和析構函數。藥劑是基於Erlang的,所以,首先,我會建議一些閱讀有關Erlang和麪向對象編程:

這應該給你的基本理念,爲什麼具有getter和setter的對象不被支持。與擁有狀態的對象最接近的是具有狀態server。因此,在服務器循環,你可以做這樣的事情:

def loop(state) do 
    newstate = receive do 
    { :get_property_one, pid } -> 
     pick_the_property_from_state_and_send_to_pid(state, pid) 
     state 
    { :set_property_one } -> 
     set_property_one_and_return_new_state(state) 
    end 
    loop(newstate) 
end 

產卵場的初始態新的服務器已經接近createing使用構造新的對象。發送:get_property_one就像getter一樣,但是是異步的(在等待回覆之前可以做其他事情)。發送:set_property_one不等待回覆,因此它是非阻塞的。

這可能看起來繁瑣,但它解決了兩個問題:

  • 你不會有讀者,在二郎作家的問題,因爲所有的請求都通過一個
  • 如果你的getter和setter方法處理一個需要一些複雜的操作,就可以異步的(沒有阻塞調用進程)

這種模式是如此普遍,有behaviour called gen_server,這消除了大部分循環的樣板。如果你仍然認爲,有太多的樣板來寫,你可以閱讀my article about it(這個人是在二郎山)

+0

似乎稱爲gen_server的行爲的鏈接是404 – simo 2016-05-11 05:35:53

+0

謝謝!更新了鏈接。 :) – tkowal 2016-05-12 06:16:39

1

的最接近OO我認爲你可以將這個

defmodule Config do 

    defstruct [ 
    some_property: nil, 
    other_property: nil 
    ] 

    def new(one, two) do 
    %Config{ 
     some_property: one, 
     other_property: two 
    } 
    end 

    #Getter 
    def property_one(this) do 
    this.some_property 
    end 

    #Setter 
    def property_one(this, value) do 
    %{this | some_property: value} 
    end 
end 

你必須像這樣使用它

conf = Config.new("a", 2) 
Config.property_one(conf) # == "a" 
conf = Config.property_one(conf, "b") # == %Config{some_property: "b", other_property: 2} 

正如你所看到的,它們只是提取/集成某些信息/在結構中的函數。我喜歡C#和Dart中的getter和setter,但是在FP世界中,他們只是函數,不多不少。