Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

reather

articles/reather.livemd

reather

setup

Mix.install([
  {:reather, "~> 0.1"},
  {:mok, "~> 0.1"}
])

example

defmodule Target do
  use Reather
  require Mok

  defmodule Impure do
    reather read("invalid") do
      Left.new(:enoent)
    end

    reather read("valid") do
      Right.new(99)
    end
  end

  reather read_and_multiply(filename) do
    env <- Reather.ask()
    input <- Impure.read(filename) |> Mok.inject(env)

    multiply(input)
  end

  reatherp multiply(input) do
    %{number: number} <- Reather.ask()

    Right.new(input * number)
  end

  def mock, do: Mok.mock(%{&amp;Target.Impure.read/1 => Right.new(77)})
end

private 함수인 multiply 에서 사용될 값을 Reather.run 을 통해 넣어줄 수 있다. (like Algae.Reader)

# 99 * 10
Target.read_and_multiply("valid") |> Reather.run(%{number: 10})

Reather.run 에 function capture 와 리턴값을 넣어두면, 함수를 쉽게 mocking 할 수 있다. (like definject)

# 77 * 10
Target.read_and_multiply("valid")
|> Reather.run(%{number: 10} |> Map.merge(Target.mock()))

defr vs reather

defr

defr get_moment_model_info(_, %{input: %{project_id: project_id}}, _) do
  monad %Right{} do
    moment_model_info <- ContentLogic.get_moment_model_info(project_id) |> run(%{})

    return %{moment_model_info: moment_model_info} |> ContentView.render()
  end
end

reather

reather get_moment_model_info(_, %{input: %{project_id: project_id}}, _) do
  moment_model_info <- ContentLogic.get_moment_model_info(project_id)
  %{moment_model_info: moment_model_info} |> ContentView.render()
end