Getting Input One Line at a Time

Problem

You e writing an interactive console program, and you want to get line-based input from the user. You present the user with a prompt, and he types some data before hitting enter.

Solution

Instead of reading standard input all at once, read it a line at a time with gets or readline.

This method populates a data structure with values obtained from user input:

	def confirmation_hearings
	 questions = [[What is your name?, :name],
	 [How old are you?, :age],
	 [Why would you like to be Secretary of the Treasury?, :why]]
	 answers = questions.inject({}) do |answers, qv|
	 question, value = qv
	 print question +  
	 answers[value] = gets.chomp
	 answers
	 end
	 puts "Okay, you
e confirmed!"
	 return answers
	end

	confirmation_hearings
	# What is your name? # <= Leonard Richardson
	# How old are you? # <= 27
	# Why would you like to be Secretary of the Treasury? # <= Mainly for the money
	# Okay, you
e confirmed!
	# => {:age=>"26", :why=>"Mainly for the money", :name=>"Leonard Richardson"}

Discussion

Most console programs take their input from command-line switches or from a file passed in on standard input. This makes it easy to programatically combine console programs: you can pipe cat into grep into last without any of the programs having to know that they e connected to each other. But sometimes its more user-friendly to ask for input interactively: in text-based games, or data entry programs with workflow.

The only difference between this technique and traditional console applications is that you e writing to standard output before you e completely done reading from standard input. You can pass an input file into a program like this, and itll still work. In this example, a Ruby program containing the questionnaire code seen in the Solution is fed by an input file:

	$ ./confirmation_hearings.rb < answers
	# => What is your name? How old are you? Why would you like to be
	# Secretary of the Treasury? Okay, you
e confirmed!

The program works, but the result looks differenteven though the standard output is actually the same. When a human is running the program, the newline created when they hit enter is echoed to the screen, making the second question appear on a separate line from the first. Those newlines don get echoed when they e read from a file.

The HighLine library requires that you install a gem ( highline), but it makes sophisticated line-oriented input much easier. You can make a single method call to print a prompt, retrieve the input, and validate it. This code works the same way as the code above, but its shorter, and it makes sure you enter a reasonable age for the question "How old are you?"

	require 
ubygems
	require highline/import

	def confirmation_hearings
	 answers = {}
	 answers[:name] = ask(What is your name? )
	 answers[:age] = ask(How old are you? , Integer) { |q| q.in = 0..120 }
	 answers[:why] = ask(Why would you like to be Secretary of the Treasury? )
	 puts "Okay, you
e confirmed!"
	 return answers
	end

	confirmation_hearings
	# What is your name? # <= Leonard Richardson
	# How old are you? # <= twenty-seven
	# You must enter a valid Integer.
	# ? # <= 200
	# Your answer isn	 within the expected range (included in 0..120)
	# ? # <= 27
	# …

See Also

  • Recipe 21.2, "Getting Input One Character at a Time"
  • Recipe 21.9, "Reading a Password"
  • The examples/basic_usage.rb script in the HighLine library has many more examples of data validation with HighLine
  • If you want your program to treat its command-line arguments as filenames and read from the files one line at a time, see Recipe 21.3, "Parsing Command-Line Arguments," for a shortcut


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net