Reputation: 11251
Using {:typed_struct, "~> 0.2.1"} library I have following struct:
defmodule RequestParams do
use TypedStruct
typedstruct do
field :code, String.t()
field :name, String.t()
end
end
I am trying to pattern match function parameters to struct:
def do_handle(params %RequestParams{}, _context) do
# instead of
# def do_handle(%{ "code" => code, "name" => name}, _context) do
But I get exception:
cannot find or invoke local params/2 inside match. Only macros can be invoked in a match and they must be defined before their invocation.
What is wrong? And is it possible at all to match function parameters to struct?
Upvotes: 0
Views: 3839
Reputation: 121000
In elixir, parentheses in function calls are not mandatory (although desirable.) That said, the code def foo(bar baz) do ...
is being parsed and treated as def foo(bar(baz)) do ...
because the parser suggests omitted parentheses in call to the function bar
. You should have got a warning from the compiler, saying exactly that. Warnings are supposed to be read and eliminated.
As it is pointed out by @peaceful-james, pattern matching inside parentheses would do.
def do_handle(%RequestParams{} = params, _context) do
You wrote
def do_handle(params %RequestParams{}, _context) do
# instead of
# def do_handle(%{ "code" => code, "name" => name}, _context) do
Even if it was syntactically correct, the code above is not equivalent to the code below. The code below would accept any map, having two keys "code"
and "name"
, while the code above allows instances of RequestParams
only. One might also make the code below more strict with:
def do_handle(%RequestParams{code: code, name: name}, _) do
But structs in elixir cannot have anything but atom
as a key. That said, if your initial code accepted %{"code" => _}
there is no way to turn it into accepting a struct without modifying the calling code.
Types are not the first-class citizens in elixir. I personally find it appropriate. You should start with understanding the language, OTP principles, the paradigm of the language and only after that decide whether you want and/or need types at all.
Upvotes: 6
Reputation: 2235
Do you actually mean to write this:
def do_handle(%RequestParams{}=params, _context) do
Upvotes: 3