My Mock Solution For Elixir Apps

May 14, 2020

After working through various options for mocking in Elixir, I decided to take the advice of the language author and go with an approach that I’ve often considered, but never actually tried.

Instead of using a library to hijack requests and return fake data, I created a fake version of the module I was mocking that returns the request I would get. I also set up some configuration to load the correct module. And then created some functions to call them.

Worth noting that I didn’t use any library.

Fakes look like this.

defmodule MyModule.FakeModule do
  def get(settings, config) do
    {:ok, %{some: data}
    }
  end
end

Each environment config has a line like this.

Test
config :my_app, :my_module, MyModule.FakeModule

Dev
config :my_app, :my_module, MyModule

Prod
config :my_app, :my_module, MyModule

Then in the actual module, I have this function

defp my_module() do
  Application.get_env(:my_app, :my_module)
end

Then when I need to call the get() function, I use my_module().get(settings, config), and it calls the appropriate module.

I’m a fan of this approach so far. I don’t like how the fake modules sprinkled in the lib directory. I’m sure there is a better way, but I really like the extraction and clarity of the fakes.

CRAP Software

May 12, 2020

Today I learned about C.R.A.P. design. Seriously, go Google C.R.A.P. design and have a read. It’s good stuff. I’m really surprised that I hadn’t heard of it before.

Although, I view it a little differently. I view it in the terms of source code. Which, in my opinion, is design. The way we structure and align things has a huge impact on its readability.

So, number one is Contrast. If you start to look at contrast, you may see a few meaningful things jump out at you. Things like group things that are the same together, or make things that are different stand out. If you’ve ever tried to find something in a log file, you know what I mean. It all looks the same and makes finding things extremely difficult. Same goes for a sea of if statements. When there is one thing buried in the middle of that, it’s really hard to find. This is just one of many reasons to reduce if statements.

Improving contrast can have big impact.

Number two is Repetition. This just screams do the same thing. Few things are worse than a codebase where everyone does their own thing. Different file naming conventions and different coding styles will almost always lead to a confusing codebase.

I usually try to follow the lead of the developers before me, or have a conversation about coding style and what’s preferred.

Number three is Alignment. Speaking of alignment, I have to admit that I was never a big fan of aligning equal signs and such, but I’ve started to come around. It really does help guide the eye to what sort of data structure it is, as long as it’s not too far apart.

This is nice and readable.

{
  "one"   = 1,
  "two"   = 2,
  "three" = 3
  "four"  = 4
}

This is not.

{
  "A-super-long-word-and-stuff"   = 1,
  "two"                           = 2,
  "three"                         = 3
  "four"                          = 4
}

Alignment also reminds me of the shape of code. Check out the Squint Test

And finally Proximity. I’ve just started to think about this as I structure code.

There are a couple of approaches when writing functions. Some developers add them to the top of the file or the bottom of the file as they come. They figure their editor will help them find what they need. There is also the camp that feels that alphabetizing is the best approach. While I like this in theory, it becomes difficult to navigate.

I’ve recently adopted the proximity approach. If I have a function that calls some other functions, I’ll order them near to where they are called to help when navigating around. With a large project, there can be a lot of jumping around. If you can try to keep the code you need together on one screen, you can reduce the complexity a lot.

I hadn’t considered graphic design principles in my code writing, but I will now.

First Time Testing in Elixir

May 8, 2020

I’ve had a heck of a time testing API calls in Elixir. It is not like testing API calls in Ruby.

But, I did get some tests to pass! They just use actual network calls for now.

What I struggled with:

  1. ENV variables don’t seem to be working when running tests. I can launch iex in the test environment and get them to work, but not when executing tests. I know it has something to do with compilation, but I don’t know exactly what yet.

  2. I have a cache that runs before the app starts. That doesn’t seem to work with tests either. It’s sort of a good thing because it forced me to guard against nil values, but it should work.

What I learned:

  1. Elixir tests are a lot different than Ruby tests.
  2. Elixir code needs to be designed in a way that limits scope. Testing is good for exposing that.
  3. There are some different opinions on how to mock things in the Elixir community. Somewhat related to Ruby, but never something I ever dug into too deeply with in Ruby.

Questions I still have:

  1. What is the preferred way to test APIs in Elixir? I can mock out requests or create dummy services. I’m not sure which approach is best.

  2. What’s the best way to have ENV variables used in testing? I would like to avoid all network requests in tests, but storing them locally seems to fail for me.

Get Yesterday's Date in Elixir

May 7, 2020

I’m working on my second production Elixir system and ran into something that’s a bit of a no-brainer in Ruby. I needed yesterday’s date. I’m working on an integration that needs to send a date range as start date and end date for an API request. That date is always yesterday and today. Basically, give me everything from yesterday until now.

Crazy simple in Ruby. Without Rails: Date.today.prev_day and with Rails: Date.yesterday.

I tried typing that in Elixir. Doesn’t work.

Elixir’s date library is really good, but doesn’t have something for yesterday. And this is rare, but the docs don’t really tell you how to do that.

The solution is to create a date and pipe into the add function with -1 as the parameter.

We can just use utc_today() to get today’s date and use that for our pipe.

Date.utc_today()
|> Date.add(-1)

The 10x Programmer Isn't What You Think It Is

Feb 28, 2020

If there is such a thing as a 10x programmer, it isn’t this mythical person that you feed Red Bull and Cheetos to, and they return tons of amazing code. Actually, all the programmers that I’ve been around that produced gross amounts of code, produced gross amounts of lower than average code. Code that needed to be refactored, took a long time to understand, and was difficult to update.

That’s not a 10x programmer. That’s a fast programmer. A fast programmer doesn’t mean a good programmer.

What a 10x programmer really is (Again. Assuming there is such a thing), is a programmer that doesn’t produce more code than other programmers, but uses years of experience and intangible skills to make the entire team better.

That’s what brings value to a company. A person that makes everyone else better. Not by isolating themselves and writing code that no one wants to work with, but by collaborating with others and sharing knowledge about architecture, the right abstractions, best practices, refactoring, database design, and even more technical things like algorithmic complexity.

That’s the 10x programmer. One that raises everyone up with things that are difficult for most people to see.

This was inspired by a great blog post about 10x programmers.Particularly this:

The most productive developers are solving big problems, and are bringing judgment and experience to bear on essential design, architecture, and “build vs use existing library” decisions. They’re designing key abstractions that will pay dividends through the life of the project

Remove all Double Spaces in Vim

Feb 18, 2020

If you’re like me and have the joy of a keyboard that doesn’t work on your expensive MacBook Pro, and your keyboard insert as many spaces as it feels like at random times. And if you are also a vim user, I have a hack that might help.

I use the following command to find all places with one or more spaces and replace them with a single space. It’s worth noting that in vim, you need to escape things you normally wouldn’t, like the { and }

Also worth noting that I am using the c modifier so I don’t make changes that I don’t want to.

:%s/\s\{2,\}/ /gc

Learning SQL Should be a Requirement

Feb 13, 2020

Yesterday I learned that computer science students do not learn about databases and SQL.

This came up in a conversation about database design and poor SQL execution being the bottle neck in poorly performing software applications, almost all the time.

A recent CS grad said “I guess I should learn SQL.” I laughed. I thought it was a joke. It wasn’t.

As I pried a little deeper, I learned that students didn’t learn about Relational Database Systems either. This means that the next round of developers that pay a gross amount of money to a University to learn how to build software graduate without being taught about foreign keys, primary keys, indexes, database normalization, etc..

But they can analyze various sorting algorithms, which are included in every programming language I’ve ever used. They can also talk theoretically about the speed of certain algorithms.

Analyzing algorithms is really important. But disproportionately favored over really important things for working software developers.

If you’re a CS student. Please take the electives. If you’ve graduated, please invest the time to learn about databases and best practices. It will serve you well.

Anonymous Functions in Elixir

Feb 6, 2020

While learning Elixir there are these little learning moments where the task would be simple in another language, but is a little more complex in a new language and new paradigm.

The task was to create an anonymous function that reacts to the value of the arguments.

From Programming Elixir:

If the first two are zero, return “FizzBuzz.” If the first is zero, return “Fizz.” If the second is zero, return “Buzz.” Otherwise return the third argument.

Seems simple enough, but I was stuck. Based on the examples I had to look back on, I was using the wrong syntax. Those examples used tuples, and I was passing in arguments directly.

Also, anonymous functions and their arguments can be a bit misleading. I thought I would need fn (a,b,c), but I actually leave that out, and just pattern match for those.

fizzbuzz = fn
  (0,0,_) -> "Fizz Buzz"
  (0,_,_) -> "Fizz"
  (_,_,c) ->  c
end

IO.puts(fizzbuzz.(3,3,1))

Then I tried to run it in an iex console. I could load it with iex fizzbizz.exs, but couldn’t call the function. Nothing worked.

I just decided to run it with elixir directly and print out the result of calling the function within the file.

elixir fizzbuzz.exs

Hackers And Engineers

Feb 2, 2020

There are software developers that love to start projects. Especially in the Rails ecosystem. And for good reason. It’s easy. It’s fun. It’s low risk and high reward. There isn’t any technical debt. And they look like a superhero. Business people love them. Just look at all the work that was done in such a short amount of time. What’s not to love?

Of course, we know that this is because of a clean slate. It’s easy to make amazing progress when there isn’t anything in your way.

Build up some technical debt. Add the need to stop and think about breaking the app. And the velocity and superheroism starts to fade.

I’ve spent the majority of my career coming in post-superhero. It’s no where near as glorious as the fresh start, but multitudes more important and difficult. In my opinion, this is where the term engineer fits a little better.

There is a lot to think about at this stage. Maintain existing functionality while extending the application to new ground. And debt must be paid here.

A developer will often be compared to the previous developer that seemed so fast. Clearly the previous developer must have been smarter, better. Probably one of those 10x developers we hear about.

Oliver Eidel has written a really good article comparing pioneers and process people. Where pioneers are the developers that can throw caution to the wind, move fast, and make something great. And process people come in behind them and stick to processes.

What I got from the article is that these two roles are distinctly different. I agree. And that once an app hits the process phase, it’s time for the pioneer to move on to build something else. I disagree.

The best developers I know are a hybrid. Builder when needed. (Everyone loves to hack a solution together.) And a more thoughtful engineer when needed.

These are two different roles, but you are far more valuable to your team and your company if you can do both.

Piping Elixir Functions Without Arguments

Jan 31, 2020

Yesterday as I was working on some Elixir code, I discovered something that wasn’t obvious to me before. If you have a function that takes an argument, you can leave the argument out if you piping functions.

In retrospect it makes sense. When you pipe functions in Elixir, the data being piped in becomes the first argument.

IO.inspect and Enum.reject are the examples that I was working with.

IO.inspect has two variations. One with two arguments and one with three arguments. I’m just using the one with two arguments. The functions signature is this:

inspect(item, opts \ [])

So, assuming I have some variables called coll, I can inspect that with IO.inspect(coll). The opts I always uses is label, so I can find it easily in the log. IO.inspect(coll, label: "Debug Collection")

But if I am piping my coll variable through a series of calls, I can leave out all arguments because opts is optional.

coll
|> some_function
|> IO.inspect
|> some_other_function

Previously, I was inserting the inspect call where I could to see what was there. This is just one of things that I didn’t expect and was not obvious to me, coming from an OOP background.

I only discovered this when I needed to get rid of some nils in an Enum type. I could not figure out how to skip nils. I could use Emun.reject(enumerable, fun), but I could only use it in the middle of a series of pipes. And I didn’t know what the variable would be, or how to use it. Turns out you don’t need it. Same style works perfectly.

coll
|> some_function
|> IO.inspect
|> Enum.reject
|> some_other_function