vinibrl

vinibrl

Case with multiple values

I refactored a code from:

def do_something(attribute) do
  bar = get_bar(attribute)
  baz = get_baz(bar)

  do_something_else(attribute, bar, baz)
end

defp do_something_else(_first, _second, 12381), do: {:ok, :ignored}
defp do_something_else(_first, second, _third) when length(second) > 100, do: {:ok, :ignored}
defp do_something_else(first, second, third), do: ExternalService.call(first, second, third)

to:

def do_something(attribute) do
  bar = get_bar(attribute)
  baz = get_baz(bar)

  case {attribute, bar, baz} do
    {_first, _second, 12381} -> {:ok, :ignored}
    {_first, second, _third} when length(second) > 100 -> {:ok, :ignored}
    {first, second, third} -> ExternalService.call(first, second, third)
  end
end

I replaced the private functions with a case. AFAIK I can’t use multiple values on the case clause, I wrapped them in a tuple. Is this the idiomatic way to do it?

Marked As Solved

yurko

yurko

I actually like the original version with private functions better.

Your context module will grow too big no matter how you organize its logic. I’d suggest to only have delegates and documentation in context module and delegate to multiple specific “private” modules that have actual logic, if you do that, then the size of each such module will not be a problem.

Also Liked

hauleth

hauleth

This is one of the ways to do so, yes. However in case of case you do not need to pass first, so you could do:

case {bar, baz} do
  {_, 12381} -> {:ok, :ignored}
  {list, _} when length(list) -> {:ok, :ignored}
  _ -> ExternalService.call(attributes, bar, baz)
end

Or you could squash the two cases:

case {bar, baz} do
  {list, num} when num == 12381 or length(list) > 100 -> {:ok, :ignored}
  _ -> ExternalService.call(attributes, bar, baz)
end

However in that case whole pattern matching is needless, so we can do:

cond do
  baz == 12381 or length(bar) > 100 -> {:ok, :ignored}
  true -> ExternalService.call(attributes, bar, baz)
end

Or you could use if macro if it is clearer for you:

if baz == 12381 or length(bar) > 100,
  do: {:ok, :ignored},
  else: ExternalService.call(attributes, bar, baz)

EDIT:

@tushar as length(baz) is used only once then it is much better to not cache it, as if baz == 12381 the length(baz) will not be called at all which can save time, as counting length of the list can be needlessly expensive for long lists.

dmkit

dmkit

But is it ideal to convert it from multi funs to case block / cond block? Or it’s just a matter of preference?

Where Next?

Popular in Questions Top

tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
RisingFromAshes
I've read in another post that it may be possible with a router helper - but I couldn't find an appropriate one, and tbh, I'm still just ...
New
ycv005
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
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New

Other popular topics Top

JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
nobody
Hi! In PHP: $SERVER['SERVERADDR'] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31107 143
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 47849 226
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement