The question itself reveals your fundamental misunderstanding of what
do block is in a nutshell.
Kernel.SpecialForms.case/2 accepts two parameters:
do ... end syntax is nothing but syntactic sugar to
do: ... keyword list parameter, inlined by compiler.
When you have a function of arity 2, you don’t hesitate to use pipe operator to pass the first parameter there, leaving the second intact.
do ... end block is simply that second parameter.
Consider the following code:
case :ok, do: (:ok -> 42; _ -> nil) #⇒ 42
The above is equivalent to
case(:ok, [do: (:ok -> 42; _ -> nil)]) #⇒ 42
Now we evidently see two parameters, the first being of type
term() and the second being a keyword list. That’s it.
Hence there cannot be any captured parameter: we have no capture, we have a regular call (to a macro
That said, your second approach is correct.
CLICK HERE to find out more related problems solutions.