Hello,
I’ve come across a difference in behaviour between Elixir 1.9.4 and later Elixir versions (tested with 1.10, 1.10.4, 1.11.0, 1.11.2, 1.12, 1.12.3).
Reproduction
Here is a test module showing the issue:
defmodule TestDefaultArguments do
def test(
arg1,
arg2 \\ (
default = "default"
default
)
) do
arg1 <> "-" <> arg2
end
end
If you run then mix run -e "TestDefaultArguments.test(\"arg1\") |> IO.puts()"
:
- On Elixir 1.9.4, you see the expected output
arg1-default
. - On later Elixir versions (tested on Elixir 1.10, 1.10.4, 1.11.0, 1.11.2, 1.12, 1.12.3), you see the following error message:
** (MatchError) no match of right hand side value: "default"
(test_gettext 0.1.0) lib/test_gettext.ex:5: TestDefaultArguments.test/1
(stdlib 3.14.2.2) erl_eval.erl:680: :erl_eval.do_apply/6
(stdlib 3.14.2.2) erl_eval.erl:888: :erl_eval.expr_list/6
(stdlib 3.14.2.2) erl_eval.erl:411: :erl_eval.expr/5
(elixir 1.10.4) lib/code.ex:341: Code.eval_string_with_error_handling/3
(elixir 1.10.4) lib/enum.ex:783: Enum."-each/2-lists^foreach/1-0-"/2
Details
I believe it’s something to do with the pattern match default = "default"
within the default argument expression.
I came across this in a situation where the default argument expression is gettext("foo")
. This is a macro which compiles down to:
(
msgid = ManagerWeb.Gettext.dpgettext_noop("default", nil, "foo")
Gettext.dpgettext(ManagerWeb.Gettext, "default", nil, msgid, %{})
)
And I get a similar error message:
** (MatchError) no match of right hand side value: "foo"
So what I care about doing is having the gettext
call in the default argument expression, but I’ve tried to distill it down to what I think is going wrong.
My Question/Request
I know it’s possible to work around this by not having the gettext
macro call in the default argument expression.
However, this is code that was working with Elixir 1.9.4, so I wanted to bring it up to check whether it is an expected change in behaviour, or if it is an unexpected regression?
Many thanks,
Steve