2016-07-04 13 views
5

Mam moduł, który jest najczęściej używany jako przestrzeń nazw. Nazwijmy to Bla. Istnieją inne submoduły, które mają metody z określonymi funkcjami tego modułu.Jaka jest różnica między defdelegate i def z funkcją modułu połączeń bezpośrednio w Elixir

Jednakże chcę mieć dwie opcje:

1) importować moduł główny Bla i korzystać ze wszystkich funkcji z submodules bezpośrednio (nie pisać wiele importu osobno)

2) import tylko specyficzny modułem jak Bla.Subbla korzystania z funkcji tylko z tego modułu bez importowania funkcji z innych submodules

to jest to, co mam:

defmodule Bla do 
    defdelegate bla_func(text), to: Bla.Subbla 
    defdelegate bla_func(text, opts), to: Bla.Subbla 
end 

defmodule Bla do 
    def bla_func(text), do: Bla.Subbla.bla_func(text) 
    def bla_func(text, opts), do: Bla.Subbla.bla_func(text, opts) 
end 

Co to jest właściwy sposób? Mam dwie opcje, ale nie mam pojęcia, być może jest o wiele lepsza. Czy te dwie opcje są równoważne? A który z nich jest lepszy? Czy jest jakaś różnica w wydajności?

+4

Myślę, że powinieneś rozważyć użycie 'use' i przekazanie mu opcji dotyczących tego, co chcesz zaimportować. – JustMichael

+0

brzmi nieźle, przeczyta o tej opcji (po prostu się uczę - obecnie nie wiem za bardzo) – kovpack

Odpowiedz

4

kilka różnic mogę myśleć:

  1. Kiedy używasz defdelegate intencję jest bardzo jasne, jesteś po prostu delegowania metodę do innej metody w innym module. I że to tylko głupi spedytor.
  2. Z defdelegate nie można zmienić arguments, niezależnie od tego, czy to kolejność, dodawanie czy usuwanie argumentów. Tak więc, jeśli naprawdę chcesz tylko przekazać wywołanie metody, użyj defdelgate, ponieważ jest mniej miejsca do zerwania.
  3. W niektórych przypadkach defdelegate nie jest opcją, ponieważ trzeba dodać więcej danych do funkcji przekazywania, w którym to przypadku tak naprawdę nie ma opcji.

Zatem podstawą jest: jeśli to możliwe, zawsze używaj defdelegate, unikniesz kilku klas błędów, które go używają. na przykład poniżej:

defmodule Greet do 
    def greet(name, greeting) do 
    IO.puts "#{greeting} #{name}" 
    end 
end 

defmodule DelegatedGreet do 
    defdelegate greet(name, greeting), to: Greet 
end 

defmodule BuggyGreet do 
    # scope for bugs like these 
    def greet(name, greeting), do: Greet.greet(greeting, name) 
end 
2

Jak powiedział @JustMichael, dobrze jest użyć use w tym przypadku. Robi dokładnie to, czego potrzebuję.

defmodule SomeModuleWhereINeedSubbla do 
    use Bla 

    useful_func # => Will print "Bla.Subbla.useful_func" 
end 

defmodule Bla do 
    defmacro __using__(_) do 
    quote do 
     import Bla.Subbla 
    end 
    end 
end 

defmobule Bla.Subbla do 
    def useful_func(), do: IO.puts "Bla.Subbla.useful_func" 
end 
+1

Ta odpowiedź jest akceptowana jako alternatywa, ale nie odpowiada na pierwotne pytanie. –

+0

yeap, naprawdę, to nie jest odpowiedź. Byłoby miło usłyszeć, jeśli znasz odpowiedź :) – kovpack

Powiązane problemy