Для этого ответа Я написал код типа:
def show_wait_spinner
dirty = false
spinner = Thread.new{
loop{
print "*"
dirty = true
sleep 0.1
print "\b"
dirty = false
}
}
yield
spinner.kill
print "\b" if dirty
end
print "A"
show_wait_spinner{ sleep rand }
puts "B"
Цель состоит в том, чтобы конечный вывод был "AB"
— напечатать окончательный "\b"
если он еще не был напечатан нитью. Этот код кажется мне беспорядочным в Ruby, где существует begin/rescue/ensure
. Поэтому я попробовал некоторые другие реализации show_wait_spinner
; все они не гарантируют, что "AB"
всегда является выходом, и никогда "A*B"
или "AB*"
.
Есть уборщица,больше Ruby -esque способ реализовать эту логику?
def show_wait_spinner
stop = false
stopm = Mutex.new
spinner = Thread.new{
loop{
print "*"
sleep 0.1
print "\b"
stopm.synchronize{ break if stop }
}
}
yield
stopm.synchronize{ stop = true }
STDOUT.flush
end
…но моя логика должна быть отключена, так как это всегда приводит к «A *B».
Эта вторая попытка приводит к тому, что иногда печатается «A *B», иногда «AB»:
def show_wait_spinner
stop = false
spinner = Thread.new{
Thread.current[:stop] = false
loop{
print "*"
sleep 0.1
print "\b"
stopm.synchronize{ break if Thread.current[:stop] }
}
}
yield
spinner[:stop] = true
STDOUT.flush
end
def show_wait_spinner
spinner = Thread.new{
dirty = false
begin
loop{
print "*"
dirty = true
sleep 0.1
print "\b"
dirty = false
}
ensure
print "\b" if dirty
end
}
yield
spinner.kill
STDOUT.flush
end
def show_wait_spinner
spinner = Thread.new{
dirty = false
begin
loop{
print "*"
dirty = true
sleep 0.1
print "\b"
dirty = false
}
rescue
puts "YAY"
print "\b" if dirty
end
}
yield
spinner.raise
STDOUT.flush
end