My Attempt at creating a simple animated shell spinner guy…
STDOUT.sync
# spinner stuff
spinner_running = false
chars = ['|', '/', '-', '\\']
@spinner = Thread.new do
loop do
unless spinner_running
Thread.stop
print "\b"
end
print chars[0]
sleep(1)
print "\b"
chars.push chars.shift
end
end
def start_spinner
spinner_running = true
@spinner.wakeup
end
def stop_spinner
spinner_running = false
end
print ".......X"
start_spinner()
sleep(5)
stop_spinner()
Just trying to create a simple spinner, and yes, I know there’s a gem for that…
Why wouldn’t I be seeing the progress of the spinner while it’s executing in this code?
Current Output: ruby spinner.rb
.......X< new prompt (no new line) >
spinner_runningneeds to be@spinner_running.It’s first defined as a local variable and then used in the thread, which is fine as the block will have access to the scope it’s defined in. However the
start_andstop_spinnermethods define their own scope, so whenspinner_runningis used there it is a newly defined, local variable.So the
spinner_runningused by the thread is never set to true – so the thread exits straight away when it is run.To fix it, it needs to be made into an instance variable by prefixing it with
@.In answer to your comment, I don’t think there’s an easy way for the thread to spot this – because the bug isn’t in the thread.