Reputation: 337
E.g:
arg = "echo:hello"
prefix = "echo"
case arg do
<<^prefix, ":", msg::binary>> -> IO.puts("Echo message: #{msg}")
_ -> IO.puts("No match")
end
Result: No match
What if I want to use the value of prefix
as a pattern match?
Upvotes: 5
Views: 439
Reputation: 1364
This won't work because you can only match fixed size binaries if you're not matching the "rest" of the string. There are 3 different solutions, depending on your use-case
If you really want to use that binary pattern matching, you can manually calculate the size beforehand:
arg = "echo:hello"
prefix = "echo"
prefix_size = byte_size(prefix)
case arg do
<<^prefix::binary-size(prefix_size), ":", msg::binary>> -> IO.puts("Echo message: #{msg}")
_ -> IO.puts("No match")
end
Depending on your use case, you could use module attributes, which size is known at compile time so they do work:
defmodule MyModule do
@prefix "echo"
def test(arg) do
case arg do
<<@prefix::binary, ":", msg::binary>> -> IO.puts("Echo message: #{msg}")
_ -> IO.puts("No match")
end
end
end
Or, if you want to keep prefix
a runtime binary, you could use String.replace_prefix/3
arg = "echo:hello"
prefix = "echo"
case String.replace_prefix(arg, "#{prefix}:", "")do
^arg -> IO.puts("No match")
msg -> IO.puts("Echo match: #{msg}")
end
String.replace_prefix/3
returns the input string if there is no match found, so we match it via ^arg
. If this is not the case, we got a match and since we replaced the prefix with ""
, we just get the part after the :
.
Upvotes: 8