Is there a way to suppress warnings about unused variables?

Our tests are structured like this:

response = say("Place order")
response = say("BITTREX 1 LTC 0.0116 BTC")
response = say("0.0109")
response = say("0.0159")

When we run them, we get a lot of warning: variable "response" is unused. Of course, we could just add underscore, but it’s inconvenient - sometimes “response” variable is actually used in assertion.

Is there a way to suppress the warning: variable "response" is unused in a general way, without underscoring its name?

Why is it inconvenient to replace response with _ or _response in the cases where it is not used? It would make your code easier to read and understand for other developers.

1 Like

Why in a variable at all?

response = say("foo")
assert "sayed foo" = response

This snippet will totally obfuscate your assertion when ExUnit prints it in the failure case. Instead of how the actual value was produced you’ll only get printed response didn’t match, where by using the function call directly you will be told that say("foo") didn’t match the expectation, which in my opinion is much more obvious.

Besides of that, assuming purity, it does not make sense to what you did there. Either you care for the returned value and assert against it, or you are only interested in the side effect which you then mark explicitely with an underscore(d name), or you are interested in both, this is usually when assert against the return value first and then against the expected effects.


Sometimes the variable is actually used in assertion, so keeping the same name for the same variable leads to good-looking code.

Is there a way to suppress the warning?

You’re right - the only issue is that response is actually a complex struct. We’re using custom asserts:

response = say("0.0159")
assert_text response, "Order to buy 1.0 LTC at 0.0116 BTC (stop-loss: 0.0109, take-profit: 0.0159) placed successfully."
assert_keyboard response, [
  ["#⃣ Go to main menu"]

In this case, I’d really rethink the API.

You seem to modify a global, invisible something with each call. When you do this from multiple processes this will probably be a big shoot in your own foot.

I really think its better than to do it like this:

response = init_say()
|> say("a")
|> say("b")

assert_text response, "a, b"

Or even:

|> say("a")
|> say("b")
|> assert_text("a, b")

Building the value this way is much more “thread”-safe and less likely to “race”.

1 Like

We have told you ways to get rid of the warning. Warnings appear for a reason. In this case, the reason is that there is stack-space wasted. For each time you rebind that variable, a new and fresh variable on the stack is “created”.

There is no way to turn of warnings in the elixir compiler except for touching either its sources or yours.

iex(2)> defmodule Blah do
...(2)>   def bloop, do: a = 42
...(2)> end
warning: variable "a" is unused

{:module, Blah,
 <<70, 79, 82, 49, 0, 0, 3, 124, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 83,
   0, 0, 0, 8, 11, 69, 108, 105, 120, 105, 114, 46, 66, 108, 97, 104, 8, 95, 95,
   105, 110, 102, 111, 95, 95, 9, 102, ...>>, {:bloop, 0}}
iex(3)> defmodule Blahs do     
...(3)>   def bloop, do: unquote(quote generated: true, do: a) = 42
...(3)> end
{:module, Blahs,
 <<70, 79, 82, 49, 0, 0, 3, 148, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 84,
   0, 0, 0, 8, 12, 69, 108, 105, 120, 105, 114, 46, 66, 108, 97, 104, 115, 8,
   95, 95, 105, 110, 102, 111, 95, 95, 9, ...>>, {:bloop, 0}}

You could always wrap it up in a macro too quite easily so you could do something like ignore_warnings(a) = 42 or so.

1 Like

I’d clearly prefer the _-prefix :wink:

1 Like

Likewise, just giving an alternative to those that dislike prefixing with _. :wink:

Mostly I was just showing that it was possible to silence it without _ or so, to the naysayers in this thread. ^.^

1 Like

To answer my own question:

defmodule ModuleName do
  @compile :nowarn_unused_vars

I do still hope though, that you reconsider your current API to something more explicit and less side-efficty despite the compiler-switch…