Reputation: 96767
I have the following:
counter = 0
try do
for _ <- Stream.cycle([:ok]) do
IO.puts "Counter is #{counter}"
counter = counter + 1
IO.puts "After counter: #{counter}"
if counter == 3 do
throw :halt
end
end
catch
:halt -> IO.puts "Finished processing"
end
From what I've read, I thought that counter = counter + 1
would rebind the variable, and eventually the counter == 3
condition would be true. However, the output I get is like this:
Counter is 0
After counter: 1
Counter is 0
After counter: 1
Counter is 0
...
So, basically, counter gets back to the initial value. It feels like the rebinding inside the for is working like a local variable, or shadows the first one. How can I make it so that the value persists ( without recursion if possible )?
Upvotes: 2
Views: 181
Reputation: 1611
To answer the title question: It isn't being re-bound because a do block generally* cannot alter variables outside it's scope. Your IO statements show that it can alter the variable inside scope; but when the do block runs again, it runs again in a new scope, where the initial value is set from the original value.
To answer the inner question: It depends on what you are trying to do. Your example doesn't give much insight on why you are choosing the Stream
module over Enum
. One way to accomplish your goal, assuming you know there are to be three iterations is with a for comprehension:
for i <- (1..3) do
IO.inspect i
end
I might be over-interpreting your question, and I surely don't mean to be insulting, but you seem to have an aversion to recursion. That's something you are going to need to get over if you plan to write much code in Elixir- This is a functional language, where recursion is idiomatic - in any language, writing with the language is much more productive than trying to code around the parts you aren't as familiar with.
*for exceptions, see macro programming
Upvotes: 2