Ruby STDIN.getc не читает char при приеме

Кажется, что Ruby IO # getc ждет, пока не получит \ n, прежде чем возвращать символы.

Если вы попробуете запустить этот скрипт:

STDOUT.sync = true
STDIN.sync = true
while data = STDIN.getc
  STDOUT.puts "Char arrived"
end

Он вернет один "Char прибыл" для каждого символа, отправленного на стандартный ввод, но только после того, как \ n был отправлен.

Кажется, что все символы буферизуются, даже если я напишу STDIN.sync = true.

Кто-нибудь знает, как заставить скрипт печатать "Char прибыл" сразу после того, как char был отправлен в STDIN?


person Martinos    schedule 15.11.2011    source источник
comment
Возможный дубликат Получить один символ из консоли немедленно или Как получить один символ в Ruby, не нажимая Enter ( у которых есть несколько хороших ответов о том, как решить эту проблему).   -  person Phrogz    schedule 16.11.2011


Ответы (4)


Получил ответ от Матца: )

ОБНОВЛЕНИЕ

Кроме того, вы можете использовать гем под названием highline, поскольку использование приведенного выше примера может быть связано со странными экранными эффектами:

require "highline/system_extensions"
include HighLine::SystemExtensions

while k = get_character
  print k.chr
end
person WarHog    schedule 15.11.2011
comment
+1 за цитирование сообщения более 11,5 лет назад. :) См. Вопрос, на который я указал, для получения дополнительных ответов, которые вы можете скомпилировать в свой. - person Phrogz; 16.11.2011
comment
Да, этот пост древний, но, как видите, все еще актуален: D - person WarHog; 16.11.2011
comment
Спасибо за быстрый ответ. Это делает мой день. Это объясняет какое-то странное поведение, которое у меня было с другими программами. - person Martinos; 16.11.2011

Адаптировано из другого вопроса с ответом .

def get_char
  begin
    system("stty raw -echo")
    str = STDIN.getc
  ensure
    system("stty -raw echo")
  end
  str.chr
end

p get_char # => "q"
person Sean Vikoren    schedule 15.11.2011

https://stackoverflow.com/a/27021816/203673 и его комментарии - лучший ответ в мире рубинов 2+ . Это заблокирует чтение одного символа и выход при нажатии ctrl + c:

require 'io/console'

STDIN.getch.tap { |char| exit(1) if char == "\u0003" }
person drewish    schedule 25.07.2019

Из https://flylib.com/books/en/2.44.1/getting_input_one_character_at_a_time.html

def getch
  state = `stty -g`
  begin
    `stty raw -echo cbreak`
    $stdin.getc
  ensure
    `stty #{state}`
  end
end

while (k = getch)
  print k.chr.inspect
  sleep 0.2
end
person Amir    schedule 14.05.2020