elixir - una - variables y constantes en html
¿Cómo se definen las constantes en los módulos Elixir? (6)
En Ruby, si uno definiera constantes en clases, las definiría usando mayúsculas. Por ejemplo:
class MyClass
MY_FAVORITE_NUMBER = 13
end
¿Cómo haces esto en Elixir? Y si no existe tal equivalente, ¿cómo se soluciona el problema de los números mágicos en Elixir?
Los módulos Elixir pueden tener metadatos asociados. Cada elemento en los metadatos se llama atributo y se accede por su nombre. Usted lo define dentro de un módulo usando @name value
. Y se accede como @name
defmodule Example
@site '''' #defining attribute
def get_site do
@site #access attribute
end
end
Recuerde que esto funciona solo en el nivel superior de un módulo y no puede establecer un atributo de módulo dentro de una definición de función.
Mirando a Github veo que esto se usa y me atrae. Permite el acceso a la constante desde otros módulos.
ModuleA @my_constant 23 defmacro my_constant, do: @my_constant ModuleB Require ModuleA @my_constant ModuleA.my_constant
Una vez más, una solución de elixir simple y fascinante
Otro enfoque para definir constantes es uno que tomé con los archivos de encabezado wxErlang. Es decir, puede simplemente definir una función de línea única que devuelva el valor constante para usted. Al igual que:
def wxHORIZONTAL, do: 4
def wxVERTICAL, do: 8
def wxBOTH, do: (wxHORIZONTAL ||| wxVERTICAL)
y aquí hay otro ejemplo del mismo código fuente:
# 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)
Como puede ver, hace que sea un poco más fácil definir una constante en términos de otra constante. Y cuando quiero esas constantes en un módulo diferente, todo lo que necesito hacer es require WxConstants
en la parte superior del módulo. Esto hace que sea mucho más fácil definir una constante en un lugar y usarla en muchos otros; ayuda mucho con DRY.
Por cierto, puedes ver el repositorio here si tienes curiosidad.
Como digo, agrego esta respuesta principalmente para completar.
Puede anteponer su nombre de variable con @
:
defmodule MyModule do
@my_favorite_number 13
end
Aquí están los docs
Quería agregar cómo comencé a hacer constantes, que es similar a la respuesta de @Onorio Catenacci, pero utiliza las citas:
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
Y luego lo usa así en la parte superior del módulo donde desea consumirlos:
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
Entendí cómo Phoenix importa / usa cláusulas con MyApp.Web. No soy ni mucho menos un experto en Elixir, pero con este método puedes importar solo las constantes que quieras y no es necesario que las antepongas con ningún espacio de nombres / alcance. De esta forma, puede seleccionar y elegir fácilmente los grupos individuales de constantes.
Con funciones rectas, (creo) tendrías que dividirlas en múltiples módulos y luego importar el módulo.
No conozco las ramificaciones de optimización de estas funciones de módulos directas, pero pensé que era bastante ordenado, especialmente para la práctica entre las diversas formas de "importar" cosas en Elixir ( import
, use
, alias
, require
es muy confuso como principiante proveniente de otros idiomas donde esta es una sola declaración de using
o import
).
EDITAR: He cambiado las declaraciones de def
constante para defp
. Esto se debe a que cuando varios módulos import
el archivo de constantes, hay un conflicto de ambigüedad. Cambiarlos a funciones de ámbito privado evita este conflicto. Entonces cada módulo tiene su propia "copia privada" de la misma constante.
Quizás definas un archivo de módulo de constantes y en él puedes definir macros para esto como tal
defmodule MyApp.Constants do
defmacro const_a do
quote do: "A"
end
end
Lo usa importándolo a cualquier otro módulo
defmodule MyApp.ModuleA do
import MyApp.Constants
def get_const_a do
const_a()
end
end
El beneficio también es que no incurre en ningún costo de tiempo de ejecución, así como la ventaja de usarlo en caso de coincidencias
case something do
const_a() -> do_something
_ -> do_something_else
end