I want to learn some basics of this great langauge. I have put this code together:
defmodule Xe do
def call(input) do
with {:ok, first} when is_integer(input) <- by_ten(input),
{:ok, second} <- by_five(first)
do
IO.puts second
else
_ ->
IO.puts "error"
end
end
def by_ten(input) do
{:ok, input * 10}
end
def by_five(input) do
{:ok, input * 5}
end
end
Xe.call("abc")
Here I am getting:
(ArithmeticError) bad argument in arithmetic expression
a.ex:16: Xe.by_ten/1
a.ex:5: Xe.call/1
(elixir) lib/code.ex:677: Code.require_file/2
How to avoid this using guards? Thank you.
guards in with match against the result not the input. So in this case it checks that the result of by_ten first matches {:ok,first} and then runs that against the guard. Put your guard on the function itself to guard against input params. Also make sure to have a by_ten without the guard to return an error.
1 Like
@jordiee
Thank you. Here is the refined code which gives the desired result:
defmodule Xe do
def call(input) do
with {:ok, first} <- by_ten(input),
{:ok, second} <- by_five(first)
do
IO.puts second
else
_ ->
IO.puts "error"
end
end
def by_ten(input) when is_integer(input) do
{:ok, input * 10}
end
def by_ten(_) do
{:error}
end
def by_five(input) do
{:ok, input * 5}
end
end
Xe.call("abc")
Any remarks are welcome.
1 Like
Yep looks good. The only thing I would change and its really preference is when my function is only one line I change it to shorthand syntax…so
def by_ten(_), do: {:error}
but again that is all preference.
1 Like