Jedna linijka w Rubim do wyświetlania zachęty, pobierania danych wejściowych i przypisywania do zmiennej?


79

Często robię następujące rzeczy:

print "Input text: "
input = gets.strip

Czy jest na to wdzięczny sposób w jednej linii? Coś jak:

puts "Input text: #{input = gets.strip}"

Problem polega na tym, że czeka na dane wejściowe przed wyświetleniem zachęty. Jakieś pomysły?


Czy ma być funkcją pobierającą tekst zachęty i zwracającą tekst wejściowy? Jeśli chcesz uzyskać bardziej wyrafinowany wygląd i potrzebujesz wielu cykli podpowiedzi / wprowadzania danych, możesz sprawić, że funkcja pobierze tablicę podpowiedzi i blok, a następnie zapętli podpowiedzi i wygeneruje każde wejście.
asm

Odpowiedzi:



76

Wydaje mi się, że najlepszym rozwiązaniem będzie coś takiego, jak zasugerował Marc-Andre, ale po co wprowadzać całą masę kodu, skoro można po prostu zdefiniować funkcję dwuwierszową na początku dowolnego skryptu, którego zamierzasz użyć :

def prompt(*args)
    print(*args)
    gets
end

name = prompt "Input name: "

2
Rzeczywiście, to też będzie działać dobrze. Dopóki nie zechcesz dodać sprawdzania danych wejściowych. Lub jakąś domyślną wartość. Lub nie pokazuj, co zostało wpisane, ponieważ pytasz o hasło ...
Marc-André Lafortune

4
W przypadku scenariusza 5-sekundowego powiedziałbym, że to jest droga.
Will Richardson,

1
Dołączyłbym .chompmetodę po, w getsprzeciwnym razie zmienna zawierałaby \nna końcu znak nowej linii.
Toma Nistor

32

Jedna linijka pewnie. Pełen wdzięku ... no nie do końca.

input = [(print 'Name: '), gets.rstrip][1]

2
Myślę, że input = (print 'Name: '; gets.rstrip)jest bardziej czytelny. Ale oba rozwiązania mają problemy z nilwartościami. W Rubim 2.3 można je z wdziękiem obsługiwać input = (print 'Name: '; gets&.rstrip).
michau

14

Wiem, że to pytanie jest stare, ale pomyślałem, że pokażę, czego używam jako standardowej metody uzyskiwania danych wejściowych.

require 'readline'

def input(prompt="", newline=false)
  prompt += "\n" if newline
  Readline.readline(prompt, true).squeeze(" ").strip
end

To naprawdę fajne, ponieważ jeśli użytkownik doda dziwne spacje na końcu lub na początku, usunie je i zachowa historię tego, co wprowadził w przeszłości (zmień na, trueaby falsetego nie robić). Jeśli ARGVnie jest pusty, getsspróbuje odczytać plik w formacieARGV zamiast pobierać dane wejściowe. Dodatkowo Readlinejest częścią standardowej biblioteki Ruby, więc nie musisz instalować żadnych klejnotów. Nie możesz również przesuwać kursora podczas używania gets, ale możesz to zrobić za pomocąReadline .

Wiem, że metoda nie jest jedną linijką, ale jest tak, jak ją wywołujesz

name = input "What is your name? "

"UWAGA: [Readline::readline ] kończy działanie interpretera ruby ​​i nie zwraca statusu terminala po naciśnięciu przez użytkownika '^ C' podczas oczekiwania na wprowadzenie wiersza."
ma11hew 28

Podoba mi się to i sugestia @Andrew Grimm jako najlepsza alternatywa dla używaniahighline/import
Chux Uzoeto

12

Podążając śladem @ Bryn:

def prompt(default, *args)
  print(*args)
  result = gets.strip
  return result.empty? ? default : result
end

4

Problem z proponowanym rozwiązaniem polega na tym, że napisu do wydrukowania nie można zbudować, dopóki dane wejściowe nie zostaną odczytane, usunięte i przypisane. Możesz oddzielić każdą linię średnikiem:

$ ruby -e 'print "Input text: "; input=gets.strip; puts input'
Input text: foo
foo

5
To nie jest tak naprawdę jedna linia; używasz średników i prawdopodobnie nie pasowałoby to do pełnej wdzięku części jego prośby.
alternatywa

1
$ ruby ​​-e 'print ("Tekst wejściowy:") || (input = gets.strip) && (puts input)'
Lars Haugseth

1

Znalazłem klejnot Inquirer przez przypadek i bardzo mi się podoba, uważam, że jest o wiele bardziej schludny i łatwiejszy w użyciu niż Highline, chociaż brakuje mu własnej weryfikacji danych wejściowych.
Twój przykład można zapisać w ten sposób

require 'inquirer'
inputs = Ask.input 'Input text'
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.