Blankman
Blankman

Reputation: 267290

Understanding pattern matching and the pipe operator

I'm having a hard time understanding the following code snippet:

Comeonin.Argon2.add_hash("hello123") |> Comeonin.Argon2.check_pass("hello123")

which outputs:

{:ok,
 %{
   password: nil,
   password_hash: "$argon2i$v=19$m=65536,t=6,p=1$thCv1TGdiLszGx+bRugcqQ$EH8PpUqpCGTevihslOdSRPWS6+UlQJwv2pMOvwBJUS4"
 }}

I want to understand 2 things here:

  1. the order of the arguments passed to the 2nd function when using |>, is it always just passed as the 1st argument to the function? What if it needs to be passed as the 2nd argument to the function?

  2. how to pattern match and deconstruct the return values

So running the 1st function I see this:

Comeonin.Argon2.add_hash("hello123")

%{
  password: nil,
  password_hash: "$argon2i$v=19$m=65536,t=6,p=1$GCmClx6W8PyzKjvh3UcKYQ$d3IMfhiEULCmMBuMF7eyBYgkPrXCBQdqQNOJNGr/3qI"
}

So it is returning a map. How can I pattern match against this?

Why doesn't this work?

{a, b} = Comeonin.Argon2.add_hash("hello123")

Or if I wanted to ignore the 1st key:

{_, b} = Comeonin.Argon2.add_hash("hello123")

For pattern matching I tried this:

case Comeonin.Argon2.add_hash("hello123") do
 {password, password_hash} -> ...

end

But I think once I understand how to deconstruct the pattern matching will be the same?

Upvotes: 0

Views: 147

Answers (1)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121010

the order of the arguments passed to the 2nd function when using |>, is it always just passed as the 1st argument to the function? What if it needs to be passed as the 2nd argument to the function?

Yes, it is always passed as the first argument. If you need to pass it as the 2nd argument, you don’t use pipe.


how to pattern match and deconstruct the return values

result =
  "hello123"
  |> Comeonin.Argon2.add_hash()
  |> Comeonin.Argon2.check_pass("hello123")

To deconstruct and raise if the response is not expected

{:ok, %{password: password, password_hash: password_hash}} = result

To handle whatever response is possible:

case result do
  {:ok, %{password: password, password_hash: password_hash}} -> ...
  _ -> :error
end

To pattern match and return any successful response:

case result do
  {:ok, %{} = password_map} -> password_map
  _ -> :error
end

Upvotes: 2

Related Questions