Aadarsh Bishen
Aadarsh Bishen

Reputation: 69

match operator in function argument in elixir?

I was going through elixir project code base and i encounter the following please help me out what is here the matching operation is doing in function argument??

{ result, errors } = validate(schema, data, "", data)
def validate(root = %{ custom: validator }, data, path, full_data) when is_function(validator) do
  { result, errors } = if Map.has_key?(root, :type), do: validate( Map.drop(root, [:custom]) , data, path ), else: { data, [] }
  case validator.(full_data, result, path) do
    { :ok, value } -> { value, errors }
    { :error, error } -> { result, errors ++ [ %{ param: path, code: :validation_error, message: error  } ]  }
  end
end

Upvotes: 1

Views: 170

Answers (2)

Greg
Greg

Reputation: 6648

As the other answer is like a fish, I'd like to contribute a bit and show you how to fish.. You can use this technique to quickly try out all the wacky edge cases you're not sure about and see the behavior.

You can fire up iex and type something like this:

defmodule Foo do                                     
   def validate(root = %{custom: validator}) do         
     IO.puts(inspect(root))                               
     IO.puts(inspect(validator))
   end
end

Then go crazy and try it out:

> Foo.validate(%{custom: "custom-value", other: "yes"})
%{custom: "custom-value", other: "yes"}
"custom-value"

> Foo.validate(%{other: "yes"})
** (FunctionClauseError) no function clause matching in Foo.validate/1    
    
    The following arguments were given to Foo.validate/1:
    
        # 1
        %{other: "yes"}
    
    iex:5: Foo.validate/1

inspect/1 returns a string representation of a structure, and IO.puts/1 prints it in the STDOUT.

Upvotes: 0

Konstantin Strukov
Konstantin Strukov

Reputation: 3019

This is very idiomatic code that serves several purposes:

  1. It ensures that the root parameter is a map that contains custom key (it might or might not contain other keys too, but we don't care about them)
  2. If so, it destructures it in place and binds custom's value to the validator
  3. It then additionally ensures (using a guard) that validator is a function

You can achieve the same via explicit checks within a function body, but this would be more verbose, probably less efficient, and for sure less idiomatic.

Upvotes: 5

Related Questions