Onor.io

Onor.io

A new REPL on Replit to help demonstrate three techniques to safely share values between modules. DRY up your code in a safe way!

defmodule MyMath do
@moduledoc """
This repl documents three ways to share values between modules.  

The question may occur to the reader--why would I want to share values between modules?  It's a valid question.  It is often the case that we need to share some common piece of logic among different contexts.  For example if we use a regular expression (regex) to parse, for example, an address, we want to insure we use the same regex every place we need to parse an address.  We can certainly copy/paste the regex but that leads to a lot more work for later developers who if they find they need to modify the regex must insure they find all the uses of the regex and modify all of them.  This becomes an even larger issue when you have teams of developers, potentially distributed across geography.  Communication is already a problem in that case and it's far more likely that someone will miss something. 

The following repl is structured as one file with two modules to make it easy to run and observe the behavior.  The Main module gives examples of how to use the shared values across modules. 

You can try the following in the console to assure yourself that this all works as expected:

## Examples

iex>  radius = 3.0
3.0
iex>  Main.circle_area(radius) == Main.circle_area_alternate(radius)
true
iex>  Main.circle_area_macro_approach(radius) == Main.circle_area(radius)
true
"""

   #First symbolic constant technique: module attribute
   Module.register_attribute(__MODULE__, :pi, persist: true)
   @pi 3.141592653

   #Second symbolic constant technique: function to return constant value
   def pi, do: 3.141592653
   # this could also be: 
   # def pi, do: @pi

   #Third symbolic constant technique (many thanks to Paul Schoenfelder for this): macro 
   defmacro __using__(_) do
    quote do
       @pi 3.141592653
    end
  end
end

defmodule Main do
   defp get_pi do # module attribute approach
      [pi] = MyMath.__info__(:attributes)[:pi]
      pi
   end

   def circle_area(radius) when is_float(radius) do
      MyMath.pi() * radius * radius #constant function approach
   end

   # or
   def circle_area_alternate(radius) when is_float(radius) do
      get_pi() * radius * radius
   end

   # or
   use MyMath

   def circle_area_macro_approach(radius) when is_float(radius) do
    @pi * radius * radius
   end

end

Try it out on Replit here!

Showing Posts 1 to 2

Onor.io

Onor.io OP

Thanks for moving this to the right place. I tried posting under Learning Resources but I couldn’t.

Yeah I figured people would just click the Run button and then try the examples but I can see how that may be not as obvious as I would have hoped.

AstonJ

AstonJ

Awesome, updated your post and deleted mine :023:

— All posts loaded —

Where Next? Top

Trending in Guides/Tuts Top

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
raa-ziq
Hi everyone :waving_hand: I wanted to share something I’ve been building — NowBlind, a random chat app designed to help people discover ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
kip
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews