Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinite yields from an iterator

I'm trying to learn some ruby. Imagine I'm looping and doing a long running process, and in this process I want to get a spinner for as long as necessary.

So I could do:

a=['|','/','-','\\']
aNow=0
# ... skip setup a big loop
print a[aNow]
aNow += 1
aNow = 0 if aNow == a.length
# ... do next step of process
print "\b"

But I thought it'd be cleaner to do:

def spinChar
  a=['|','/','-','\\']
  a.cycle{|x| yield x}
end
# ... skip setup a big loop
print spinChar
# ... do next step of process
print "\b"

Of course the spinChar call wants a block. If I give it a block it'll hang indefinitely.

How can I get just the next yeild of this block?

like image 859
dlamblin Avatar asked Nov 30 '22 12:11

dlamblin


1 Answers

Ruby's yield does not work in the way your example would like. But this might be a good place for a closure:

def spinner()
  state = ['|','/','-','\\']
  return proc { state.push(state.shift)[0] }
end

spin = spinner

# start working
print spin.call
# more work
print spin.call
# etc...

In practice I think this solution might be too "clever" for its own good, but understanding the idea of Procs could be useful anyhow.

like image 121
maxg Avatar answered Dec 05 '22 16:12

maxg