Problem
I have a module that does a lookup and I structured in a way where you can pass either 1, 2 or 3 arguments.
defmodule FooExampleOne do
def lookup(id) do
IO.inspect("Lookup 1: #{id}")
end
def lookup(id, place_id) do
IO.inspect("Lookup 2: #{id} #{place_id}")
end
def lookup(id, place_id, company_id) when company_id in [:internal, :external] do
IO.inspect("Lookup 3: #{id} #{place_id} #{company_id}")
end
end
Adding a default date as another argument
I then got a requirement to provide a date as another argument. The user can always pass in another date but by default it would be today.
defmodule FooExampleTwo do
@default DateTime.utc_now()
def lookup(id, date \\ @default) do
IO.inspect("Lookup 1: #{id} #{date}")
end
def lookup(id, place_id, date \\ @default) do
IO.inspect("Lookup 2: #{id} #{place_id} #{date}")
end
def lookup(id, place_id, company_id, date \\ @default) when company_id in [:internal, :external] do
IO.inspect("Lookup 3: #{id} #{place_id} #{company_id} #{date}")
end
end
Compile Error
This won’t work as I will get a (CompileError) def lookup/3 defaults conflicts with lookup/2
. I looked at the docs and I saw this and then came up with this solution and it works with some changes.
defmodule FooExampleThree do
@default DateTime.utc_now()
def lookup(params, date \\ @default)
def lookup({id}, date) do
IO.inspect("Lookup 1: #{id} #{date}")
end
def lookup({id, place_id}, date) do
IO.inspect("Lookup 2: #{id} #{place_id} #{date}")
end
def lookup({id, place_id, company_id}, date) when company_id in [:internal, :external] do
IO.inspect("Lookup 3: #{id} #{place_id} #{company_id} #{date}")
end
end
Question About My Approach
I added a function head that declares the default and then put my arguments in a tuple. Is this style ok?
Part of me doubts that this solution is ideal. If it’s not a tuple I can alway pass in a map in the params position.
Any feedback or thoughts around the approach?