#ruby #iteration #pause
#ruby #итерация #пауза
Вопрос:
Я пытаюсь создать программу на Ruby, которая выводит текст и делает паузу для каждой полной остановки «.» или «…» в строке. Я получил это до сих пор, но не знаю, что делать дальше.
def talk(text, speed = 0.008)
pause = speed * 100
text.each_char do |char|
print char
if char == '.'
sleep(pause)
end
sleep(speed)
end
return
end
# e.g. talk("I can see something... It's getting closer... Oh no.")
Он отлично останавливается на одну полную остановку, но, очевидно, не работает для трех подряд, поскольку он просто повторяет паузу три раза. Я скорее новичок и изо всех сил пытаюсь найти решение. Спасибо за чтение
Ответ №1:
Вот мое предложение — выводите все .
буквы s по мере их появления, переходя в режим ожидания перед печатью следующего символа.
def talk(text, speed = 0.008)
pause = speed * 100
last_char = nil # keep track of the previous character.
text.each_char do |char|
if char == '.'
# no sleep at all for periods
print('.')
else
# we're going to print something, if the last character was a period,
# pause before doing it.
sleep(pause) if last_char == '.'
print char
# finally, a regular sleep
sleep(speed)
end
# and update the last character we saw
last_char = char
end
end
Конечно, есть много разных способов решить эту проблему!
Ответ №2:
def talk(text, speed = 0.008)
pause = speed * 100
r = /(.{3}|.)/
text.split(r).each do |str|
if str.match?(r)
sleep(pause)
else
print str
end
end
puts
end
talk("Mary had .a lit...tle .lamb", 0.04)
#=> Mary had a little lamb
^ ^ ^
После печати каждого символа, обозначенного шапкой участника, произошла четырехсекундная задержка.
Шаги следующие.
text = "Mary had .a lit...tle .lamb"
speed = 0.04
pause = speed * 100
r = /(.{3}|.)/
Это регулярное выражение гласит: «сопоставьте три периода или ( |
) один период в группе захвата 1″ (группа захвата определяется круглыми скобками)». Это не то же самое, что /(.|.{3})/
, который соответствовал бы каждому периоду каждой группы из трех по отдельности (то есть, .
before |
будет успешным для каждого периода, части группы или нет).
a = text.split((r))
#=> ["Mary had ", ".", "a lit", "...", "tle ", ".", "lamb"]
Смотрите Строку #split , которая объясняет необходимость для группы захвата включать строки разделения в возвращаемый массив.
Продолжение,
a.each do |str|
if str.match?(r)
sleep(pause)
else
print str
end
end
Это печатает (без символа новой строки) "Mary had "
, спит в течение четырех секунд, печатает "a lit"
, спит еще четыре секунды и так далее.
puts
Этот последний оператор необходим для печати символа новой строки для завершения строки.
Другой способ — внести несколько небольших изменений в метод, указанный в вопросе.
def talk(text, speed = 0.008)
pause = speed * 100
text.squeeze('.').each_char do |char|
if char == '.'
sleep(pause)
else
print char
end
end
puts
end
Смотрите String#squeeze, который преобразует каждую строку из двух или более периодов в один период.
Этот метод отличается от предыдущего тем, что он обрабатывает два или более трех периодов подряд.