Last active
June 20, 2018 15:33
-
-
Save andersonmcook/da201f7c665de5f317aab7a3acc5770b to your computer and use it in GitHub Desktop.
Naïve approaches to cross-module constants not using config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # use Mix.Config | |
| # config :constants, | |
| # :some_string: "some_string", | |
| # :range_i_like: 1..5, | |
| # :a_map: %{letters: ~w(a b c)} | |
| defmodule Constants.Macro do | |
| # Take code and convert to AST | |
| # Inject name into quoted expression as the name of the macro | |
| # Inject value into quoted expression as the value the macro returns | |
| defmacro create(name, value) do | |
| quote do | |
| defmacro unquote(name) do | |
| unquote(value) | |
| end | |
| end | |
| end | |
| # non-literal range in guard should be escaped with Macro.escape/2 | |
| defmacro create_escaped(name, value) do | |
| quote do | |
| defmacro unquote(name) do | |
| unquote(Macro.escape(value)) | |
| end | |
| end | |
| end | |
| end | |
| defmodule Constants do | |
| alias Constants.Macro, as: CM | |
| require CM | |
| CM.create(some_string, "some_string") | |
| CM.create_escaped(range_i_like, 1..5) | |
| CM.create_escaped(a_map, %{letters: ~w(a b c)}) | |
| end | |
| defmodule Impl.A do | |
| alias Constants, as: C | |
| # require module to use its macros | |
| require C | |
| # or import Constants | |
| # or import Constants, only: :macros | |
| def match(C.some_string), do: "you gave me that string I like" | |
| def match(_), do: "nooo" | |
| def in_range?(n) when n in C.range_i_like, do: "#{n} is good, I like it" | |
| def in_range?(_), do: "buh" | |
| def cap(letter) do | |
| case letter in C.a_map().letters do | |
| true -> letter |> String.upcase |> Kernel.<>(" is all grown up") | |
| false -> "i will not capitalize #{letter}" | |
| end | |
| end | |
| def types do | |
| IO.inspect IEx.Info.info(C.some_string) | |
| IO.inspect IEx.Info.info(C.range_i_like) | |
| IO.inspect IEx.Info.info(C.a_map) | |
| IO.inspect IEx.Info.info(C.a_map.letters) | |
| end | |
| end | |
| defmodule Constants.Using do | |
| defmacro __using__(_) do | |
| quote do | |
| @some_string "some_string" | |
| @range_i_like 1..5 | |
| @a_map %{letters: ~w(a b c)} | |
| end | |
| end | |
| end | |
| defmodule Impl.B do | |
| use Constants.Using | |
| def match(@some_string), do: "you gave me that string I like a second time" | |
| def match(_), do: "nooo, again" | |
| def in_range?(n) when n in @range_i_like, do: "#{n} is still cool with me" | |
| def in_range?(_), do: "buh, again" | |
| def cap(letter) do | |
| case letter in @a_map.letters do | |
| true -> letter |> String.upcase |> Kernel.<>(" is now a big boy") | |
| false -> "again, i will not capitalize #{letter}" | |
| end | |
| end | |
| def types do | |
| IO.inspect IEx.Info.info(@some_string) | |
| IO.inspect IEx.Info.info(@range_i_like) | |
| IO.inspect IEx.Info.info(@a_map) | |
| IO.inspect IEx.Info.info(@a_map.letters) | |
| end | |
| end | |
| defmodule Doublecheck do | |
| use Constants.Using | |
| require Constants | |
| def all_good? do | |
| IO.inspect Constants.some_string === @some_string and | |
| Constants.range_i_like === @range_i_like and | |
| Constants.a_map === @a_map, label: "these are the same" | |
| end | |
| end | |
| IO.puts "" | |
| IO.inspect Impl.A.match("some_string"), label: "Impl.A.match(\"some_string\")" | |
| IO.inspect Impl.A.match("nah"), label: "Impl.A.match(\"nah\")" | |
| IO.inspect Impl.B.match("some_string"), label: "Impl.B.match(\"some_string\")" | |
| IO.inspect Impl.B.match("nah"), label: "Impl.B.match(\"nah\")" | |
| IO.puts "" | |
| IO.inspect Impl.A.in_range?(3), label: "Impl.A.in_range?(3)" | |
| IO.inspect Impl.A.in_range?(9), label: "Impl.A.in_range?(9)" | |
| IO.inspect Impl.B.in_range?(3), label: "Impl.B.in_range?(3)" | |
| IO.inspect Impl.B.in_range?(9), label: "Impl.B.in_range?(9)" | |
| IO.puts "" | |
| IO.inspect Impl.A.cap("a"), label: "Impl.A.cap(\"a\")" | |
| IO.inspect Impl.A.cap("d"), label: "Impl.A.cap(\"d\")" | |
| IO.inspect Impl.B.cap("a"), label: "Impl.B.cap(\"a\")" | |
| IO.inspect Impl.B.cap("d"), label: "Impl.B.cap(\"d\")" | |
| IO.puts "" | |
| Doublecheck.all_good?() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment