This is basically the same question I’ve asked before, I’m just wondering if anything has changed since I last asked, or if there’s any other ways to do this thing that I am doing.
I know there’s been proposals for alternate ways to pipe some input into an argument slot other than the first position, and I understand why those got shot down, so I’m not really asking about that.
Here’s an example of a function I wrote recently, and shows a style I’ve been doing kind of frequently.
def get_meter(num, total) do
Decimal.div(num, total)
|> Decimal.mult(10)
|> Decimal.round(0)
|> Decimal.to_integer()
|> (fn level ->
Enum.map(0..10, fn ^level -> "|"; _ -> "-" end)
|> Enum.join()
end).()
end
And this is another way to do the same thing, which I kind of like because we don’t have to add the extra parentheses, but we do have to add an extra level of indentation, which I find annoying.
def get_meter(num, total) do
Decimal.div(num, total)
|> Decimal.mult(10)
|> Decimal.round(0)
|> Decimal.to_integer()
|> case do
level ->
Enum.map(0..10, fn ^level -> "|"; _ -> "-" end)
|> Enum.join()
end
end
Using case is really nice when we truly have different conditions to handle in different ways, and I love that we can then pipe the result from the case statement/operator/function/macro/whatever-the-correct-term-is into whatever else comes after, but in the example shown, I don’t like it much.
The best alternative I can find to make this a little cleaner would be this:
def do_func(arg, func), do: func.(arg)
def get_meter(num, total) do
Decimal.div(num, total)
|> Decimal.mult(10)
|> Decimal.round(0)
|> Decimal.to_integer()
|> do_func(fn level ->
Enum.map(0..10, fn ^level -> "|"; _ -> "-" end)
|> Enum.join()
end)
end
Would be nice if Elixir had a built-in Kernel.do_func/2
.