2015-11-22 8 views
23

Rubyでは、クラスで定数を定義していた場合、すべての大文字を使って定数を定義します。例:Elixirモジュールで定数をどのように定義しますか?

class MyClass 
    MY_FAVORITE_NUMBER = 13 
end 

これはどのようにしてエリクシルで行いますか?そのような同等物が存在しない場合、エリクサーの魔法の数字の問題をどうやって解決しますか?

答えて

25

あなたは@であなたの変数名を付加することができます:ここで

defmodule MyModule do 
    @my_favorite_number 13 
end 

docs

+1

ただし、@my_favorite_numモジュールの外部からアクセスできない。 –

+0

@lfx_coolが正しい。モジュールの外部からアクセスしたい場合は、その値を返す関数を定義することができます: 'def my_favorite_number、do:@ my_favorite_number' – AbM

+2

これを行うためのショートカットがあれば、getterメソッドです。 attr_reader:my_favorite_number –

4

エリクサーモジュールは、メタデータを関連付けることができます。メタデータの各項目は属性と呼ばれ、その名前でアクセスされます。 @name valueを使用してモジュール内で定義します。そして、この思い出してくれる@name

defmodule Example 
    @site 'StackOverflow' #defining attribute 

    def get_site do 
    @site #access attribute 
    end 
end 

としてアクセスされたモジュールのトップレベルでのみ動作しますが、関数定義内のモジュールの属性を設定することはできません。

7

定数を定義するもう1つの方法は、wxErlangヘッダーファイルで行ったものです。つまり、定数値を返す単一行関数を単純に定義することができます。これと同様に:あなたは、それは別の定数の面で定数を定義することが少し楽になり見ることができるように

# From "defs.h": wxDirection 
    def wxLEFT, do: 16 
    def wxRIGHT, do: 32 
    def wxUP, do: 64 
    def wxDOWN, do: 128 
    def wxTOP, do: wxUP 
    def wxBOTTOM, do: wxDOWN 
    def wxNORTH, do: wxUP 
    def wxSOUTH, do: wxDOWN 
    def wxWEST, do: wxLEFT 
    def wxEAST, do: wxRIGHT 
    def wxALL, do: (wxUP ||| wxDOWN ||| wxRIGHT ||| wxLEFT) 

def wxHORIZONTAL, do: 4 
    def wxVERTICAL, do: 8 
    def wxBOTH, do: (wxHORIZONTAL ||| wxVERTICAL) 

、ここでは、同じソースコードからの別の例です。そして私が必要とするのは、モジュールの上部にあるrequire WxConstantsです。これにより、1つの場所で定数を定義し、いくつかの場所で使用する方がはるかに簡単になります。

ところで、興味がある場合は、hereのレポを見ることができます。

私が言うように、私は主にこの答えを補完するために追加します。

+0

それは素晴らしいですが、時には定数が必要です明らかに関数のメモのウサギの穴につながっています。http://stackoverflow.com/questions/35465306/how-to-create-a-global-variable-in-elixir-module/35468186#35468186。必要が生じた場合に知っておくと便利です。 –

+0

_computed_value _が何を意味しているのかよく分かりません。計算された値が意味するものと、たとえば上記の 'wxALL'の違いは何ですか? –

+0

'wxALL'は定数の論理和ですが、私が考えていたのは' Time.now'のようなメソッド呼び出しでした。 –

1

私は@Onorio Catenacciの回答に似ている、定数をやって始めたが、引用使用してきた方法を追加したい:

defmodule IbGib.Constants do 

    @doc """ 
    Use this with `use IbGib.Constants, :ib_gib` 
    """ 
    def ib_gib do 
    quote do 
     defp delim, do: "^" 
     defp min_id_length, do: 1 
     # etc... 
    end 
    end 

    @doc """ 
    Use this with `use IbGib.Constants, :error_msgs` 
    """ 
    def error_msgs do 
    quote do 
     defp emsg_invalid_relations do 
     "Something about the rel8ns is invalid. :/" 
     end 
     # etc... 
    end 
    end 

    @doc """ 
    When used, dispatch to the appropriate controller/view/etc. 
    """ 
    defmacro __using__(which) when is_atom(which) do 
    apply(__MODULE__, which, []) 
    end 
end 

そして、あなたがどこのモジュールの先頭に次のようにそれを使用します

use IbGib.Constants, :ib_gib # < specifies only the ib_gib constants 
use IbGib.Constants, :error_msgs 

# ... then in some function 
Logger.error emsg_invalid_relations 

フェニックスがMyApp.Webでインポート/使用句をどのように扱うかを知ることができます。私はエリクシールのエキスパートの近くにいませんが、このメソッドを使用すると、必要な定数だけをインポートすることができ、名前空間/スコープを接頭辞として使用する必要はありません。こうすることで、個々の定数グループを簡単に選択して選択することができます。

ストレート関数を使用すると、それらを複数のモジュールに分割してモジュールをインポートする必要があります。

私が直接モジュール機能対本の最適化の波及効果がわからないが、私はそれはかなりきちんとした考え - 特にさまざまな方法間の練習のためにエリクサー(importusealiasで「インポート」のものは、requireですこれは単一のusingまたはimportステートメントである他の言語からの初心者としては非常に混乱します)。

編集:定数defの宣言をdefpに変更しました。これは、複数のモジュールimport定数ファイルの場合、あいまいな競合があるためです。非公開スコープの関数に変更することで、この競合が回避されます。したがって、各モジュールには同じ定数の独自の「プライベートコピー」があります。

2

たぶん、あなたは定数モジュールファイルを定義し、その中にあなたがそう

defmodule MyApp.Constants do 
    defmacro const_a do 
    quote do: "A" 
    end 
end 

あなたが利点でもある他のモジュールに

defmodule MyApp.ModuleA do 
    import MyApp.Constants 

    def get_const_a do 
    const_a() 
    end 
end 

それをインポートしてそれを使用するように、このためのマクロを定義することができます実行時のコストがかからず、一致する場合に使用する利点もありません。

case something do 
    const_a() -> do_something 
    _ -> do_something_else 
end 
関連する問題