2010-05-22 4 views
66

A menudo me encuentro haciendo lo siguiente:¿Un trazador de líneas en Ruby para mostrar un aviso, obtener entrada y asignar a una variable?

print "Input text: " 
input = gets.strip 

¿Hay una forma elegante de hacer esto en una línea? Algo así como:

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

El problema con esto es que se espera para la entrada antes de que aparezca el símbolo. ¿Algunas ideas?

+0

Que sea una función que toma el texto del mensaje y devuelve el texto de entrada? Si quiere ser más elegante y necesita múltiples ciclos de solicitud/entrada, puede hacer que la función tome una serie de instrucciones y un Bloquear, luego repita las instrucciones y ceda cada entrada. – asm

Respuesta

67

Salida highline:

require "highline/import" 
input = ask "Input text: " 
4

El problema con la solución propuesta es que la cadena que se va a imprimir no se puede construir hasta que se lea la entrada, despojado, y se le asignó. Se podía separar cada línea con un punto y coma:

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

Eso no es realmente una sola línea; está usando punto y coma, y ​​eso probablemente no correspondería a la parte elegante de su pedido. – alternative

+1

$ ruby ​​-e 'print ("Texto de entrada:") || (input = gets.strip) && (puts input)' –

64

Creo que ir con algo parecido a lo que Marc-Andre sugiere que va a ser el camino a seguir, pero ¿por qué traer a toda una tonelada de código cuando se puede definir una función de dos líneas en la parte superior de cualquier script que vaya a utilizar:

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

name = prompt "Input name: " 
+2

De hecho, eso funcionará bien también. Hasta que quieras agregar alguna verificación de entrada. O algún valor predeterminado.O no muestre lo que se tipea porque pide una contraseña ... –

+4

Para un guión de 5 segundos, diría que este es el camino a seguir. – javanut13

28

One liner hack sure. Graceful ... bueno, no exactamente.

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

¡Eso es lo suficientemente feo para funcionar! –

+1

Creo que 'input = (print 'Name:'; gets.rstrip)' es más legible. Pero ambas soluciones tienen problemas con valores 'nil'. En Ruby 2.3, pueden manejarse con gracia con 'input = (print 'Name:'; gets & .rstrip)'. – michau

11

Siguiendo el ejemplo de Bryn @:

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

Sé que esta pregunta es viejo, pero aunque me muestro lo que utilizo como mi método estándar para conseguir la entrada.

require 'readline' 

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

Esto es muy agradable ya que si el usuario añade espacios extraños al final o al principio, que va a eliminar aquellos, y se mantiene un historial de lo que entraron en el pasado (Cambiar el true a false no hacer que haga eso). Y, si ARGV no está vacío, entonces gets intentará leer de un archivo en ARGV, en lugar de recibir información. Además, Readline es parte de la biblioteca estándar de Ruby por lo que no tiene que instalar gemas. Además, no puede mover el cursor cuando usa gets, pero puede hacerlo con Readline.

Y, sé que el método no es una línea, pero es cuando se llama a que

name = input "What is your name? " 
+0

"NOTA: [[' Readline :: readline'] (http://www.ruby-doc.org/stdlib-2.1.1/libdoc/readline/rdoc/Readline.html#method-c-readline)] termina intérprete de ruby ​​y no devuelve el estado del terminal después de que el usuario presionó '^ C' cuando espera a ingresar la línea. " – ma11hew28

+0

Me gusta esto y la sugerencia de @Andrew Grimm como las mejores alternativas para usar 'highline/import' –

1

he encontrado la joya Inquirer por casualidad y me gusta mucho, creo que es mucho más limpio y fácil de usar que Highline, aunque carece de validación de entrada por sí mismo.
Su ejemplo se puede escribir como esto

require 'inquirer' 
inputs = Ask.input 'Input text' 
Cuestiones relacionadas