Hey guys.
I just wrote this code with two nested ifs and it got me wondering if there is a better way. I’m still strugling with functional programming in general. I think it would be “bad” to add a third if statement inside the last else, but I can’t see how to grow a logic like this. In other languages I would probably use early returns. Thanks!
def full_route(str) do
if has_protocol?(str) do
str
else
if String.starts_with?(str, "/") do
Application.get_env(:my_app, :url) <> str
else
Application.get_env(:my_app, :url) <> "/" <> str
end
end
end
wmnnd
September 12, 2017, 11:16pm
2
In principle, there is nothing wrong with if
statements. However, you could probably leverage pattern matching to simplify your code.
If you only have a handful of protocols, you could do something like this:
def full_route("http://" <> url), do: "http://" <> url
def full_route("https://" <> url), do: "https://" <> url
def full_route("/" <> path), do: do_full_route(path)
def full_route(path), do: do_full_route(path)
defp do_full_route(path), do: Application.get_env(:my_app, :url) <> "/" <> str
Alternatively, something like the following would also work:
def full_route(url), do: do_full_route(url, has_protocol?(url)
defp do_full_route(url, has_protocol?)
defp do_full_route(url, true), do: url
defp do_full_route(path, _) do
Application.get_env(:my_app, :url)
|> URI.merge(path)
|> URI.to_string()
end
As you see, the possibilities are endless
2 Likes
Wow, I didn’t think pattern matching could be a solution here. Now I see. Thanks for the help
Your example as cond
:
def full_route(str) do
cond do
has_protocol?(str) -> str
String.starts_with?(str, "/") -> Application.get_env(:my_app, :url) <> str
true -> Application.get_env(:my_app, :url) <> "/" <> str
end
end
Although this pattern breaks down a bit when you have many branches ‘inside’ of many branches. ^.^;
3 Likes
Thanks for the help. cond
seems to fit better in this example. I’ll definetly read the thread, thanks
NobbZ
September 13, 2017, 5:32am
7
Just to make sure we are using the correct terminology. There are no statements in elixir, only expressions.
The important difference is, that a statement does not return anything while the expression does.
4 Likes