2015-05-28 11 views
29

मैं गतिशील रूप से फ़ंक्शन नाम बनाना चाहता हूं। मैं इस मैक्रोइलीक्सिर मैक्रो का उपयोग करके गतिशील फ़ंक्शन नाम कैसे बनाएं?

defmacro generate_dynamic(name) do 
    quote do 
    def add_(unquote(name)) do 
    end 
    end 
end 

लिखा था और मैं इसे इस तरह इस्तेमाल किया:

defmodule AnotherModule do 
    generate_dynamic :animal 
end 

अब, मैं केवल मिल AnotherModule.add_ समारोह में परिभाषित किया गया है, जबकि मैं AnotherModule.add_animal समारोह की उम्मीद है।

उत्तर

36

इसे प्राप्त करने के लिए, आप नाम से पहले पूर्ववत कर सकते हैं। साथ ही, इस मामले में विधि नाम के बाद कोष्ठक अस्पष्टताओं को रोकने के लिए आवश्यक हैं। एक मैक्रो एक गंदें शब्द बोलना टुकड़ा का उपयोग कर लिखे बिना,

defmacro generate_dynamic(name) do 
    quote do 
    def unquote(:"add_#{name}")() do 
     # ... 
    end 
    end 
end 
17

कभी कभी एक उपयोगी शॉर्टकट के रूप में आप एक ही परिणाम प्राप्त कर सकते हैं इनलाइन: इस चाल करना चाहिए।

defmodule Hello do 
    [:alice, :bob] |> Enum.each fn name -> 
    def unquote(:"hello_#{name}")() do 
     IO.inspect("Hello #{unquote(name)}") 
    end 
    end 
end 

Hello.hello_bob # => "Hello bob" 
Hello.hello_alice # => "Hello alice" 
+1

मैंने सोचा था कि 'unquote' केवल से काम किया ** एक मैक्रो में किसी एक **। यह एक अज्ञात फ़ंक्शन के अंदर कैसे काम कर रहा है? – asymmetric

+7

मैं खुद का जवाब देता हूं: अनकोट और [अनजान टुकड़े] (http://elixir-lang.org/docs/stable/elixir/Kernel.SpecialForms.html) दो अलग-अलग चीजें हैं। – asymmetric

+0

जुसी उपर्युक्त को स्पष्ट करने के लिए: अनजान टुकड़े 'उद्धरण' हैं जो 'उद्धरण' ब्लॉक के बाहर हैं। – asymmetric

5

मैं कोशिश करने के लिए एक सार में बात की इसी तरह से किया था और नकल रूबी के attr_accessor:

defmodule MacroExp do 
    defmacro attr_accessor(atom) do 
    getter = String.to_atom("get_#{atom}") 
    setter = String.to_atom("set_#{atom}") 
    quote do 
     def unquote(getter)(data) do 
     data |> Map.from_struct |> Map.get(unquote(atom)) 
     end 
     def unquote(setter)(data, value) do 
     data |> Map.put(unquote(atom), value) 
     end 
    end 
    end 

    defmacro attr_reader(atom) do 
    getter = String.to_atom("get_#{atom}") 
    quote do 
     def unquote(getter)(data) do 
     data |> Map.from_struct |> Map.get(unquote(atom)) 
     end 
    end 
    end 
end 


defmodule Calculation do 
    import MacroExp 
    defstruct first: nil, second: nil, operator: :plus 

    attr_accessor :first # defines set_first/2 and get_first/1 
    attr_accessor :second # defines set_second/2 and get_second/1 
    attr_reader :operator # defines set_operator/2 and get_operator/1 

    def result(%Calculation{first: first, second: second, operator: :plus}) do 
    first + second 
    end 
end 

https://gist.github.com/rcdilorenzo/77d7a29737de39f0cd84

संबंधित मुद्दे

 संबंधित मुद्दे