kip
ex_cldr Core Team
[snippet] Debugging Function Clause errors
A little while ago someone asked about how to get a full list of function clauses when there is a function clause error. I have some code that generates a lot of function clauses so I had a similar need. I couldn’t find my code at the time but I have now and post it here so I can find it again 
Example
iex> FunctionClause.match MyApp.Cldr.Number.Formatter.Decimal, :to_string, ["123", "#", []]
def to_string(number, format, options) when is_binary(format) and is_list(options)
def to_string(number, "#,##0%", options) when is_map(options)
def to_string(number, "#,##0.###", options) when is_map(options)
def to_string(number, "#,##0.00 ¤", options) when is_map(options)
def to_string(number, "#,##0.00 ¤;(#,##0.00 ¤)", options) when is_map(options)
def to_string(number, "#,##0 %", options) when is_map(options)
def to_string(number, "#E0", options) when is_map(options)
def to_string(number, "0", options) when is_map(options)
def to_string(number, "0 Billion", options) when is_map(options)
def to_string(number, "0 Billionen", options) when is_map(options)
def to_string(number, "0 Milliarde", options) when is_map(options)
def to_string(number, "0 Milliarden", options) when is_map(options)
.... and a lot more :-)
Code
defmodule FunctionClause do
@moduledoc """
Format function clauses using Exception.blame/3
"""
@doc """
Given a `module`, `function`, and `args` see
that function clause would match or not match.
This is useful for helping diagnose function
clause errors when many clauses are generated
at compile time.
"""
@spec match(module(), atom(), list(any)) :: :ok | no_return()
def match(module, function, args) do
case Exception.blame_mfa(module, function, args) do
{:ok, kind, clauses} ->
formatted_clauses(function, kind, clauses, &blame_match/2)
:error ->
raise ArgumentError,
"Function #{inspect(module)}.#{function}/#{length(args)} " <>
"is not known."
end
end
defp formatted_clauses(function, kind, clauses, ast_fun) do
format_clause_fun = fn {args, guards} ->
code = Enum.reduce(guards, {function, [], args}, &{:when, [], [&2, &1]})
" #{kind} " <> Macro.to_string(code, ast_fun) <> "\n"
end
clauses
|> Enum.map(format_clause_fun)
|> Enum.join()
|> IO.puts()
end
defp blame_match(%{match?: true, node: node}, _),
do: Macro.to_string(node)
defp blame_match(%{match?: false, node: node}, _),
do: IO.ANSI.red() <> Macro.to_string(node) <> IO.ANSI.reset()
defp blame_match(_, string), do: string
end
Popular in Guides/Tuts
I was preparing to deploy a production application to AWS Fargate, and to practice I wanted to play with DNS polling and node discovery o...
New
Hi folks! I wrote an article about BEAM and Haskell Interoperabilty. I'm describing the use of the erlang-ffi project, that impersonates ...
New
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
Did you know that IO.inspect/2 returns the the first argument and accepts a label option as a second argument. This makes it a perfect to...
New
Recently we partitioned a table with 28 million rows by its ULID to improve query speeds and reduce query timeouts. To do this I ended up...
New
Hello everyone,
I created a deployment tutorial for Phoenix applications with Kubernetes (microk8s) a few months back with the goal of s...
New
A question I had when first learning contexts and Ecto was how to expand the default context API to support more flexible queries. Usuall...
New
When we were figuring out how to use Phoenix LiveView we got stuck a few times.
So in order to save other people time, we created a comp...
New
Hey, today I give amnesia library a try and found a few problems. I would like describe how to setup it properly and solve problems which...
New
..or as and when you can think of one :icon_cool:
This thread my also be of interest: What took you way too long to figure out? :003:
New
Other popular topics
Hi! May someone helps me, please!
I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
Hi all,
Trying to get some more clarity over utc_datetime and naive_datetime for Ecto:
https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
I have followed this StackOverflow post to install the specific version of Erlang.
And When I am running mix ecto.setup then getting fol...
New
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
Hi,
I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
I have a User schema with a :from_id field set to type :string:
defmodule TweetBot.Repo.Migrations.CreateUsers do
use Ecto.Migration
...
New
Hello, I have map which I want to convert it to string like this:
the map:
%{last_name: "tavakkoli", name: "shahryar"}
the string I ne...
New
Hi,
I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New







