Home SEO Tools HTML Escape Tool Character Counter Guest post

Input and output in Ruby

0 comments


In this part of the Ruby tutorial, we will talk about Input & output operations in Ruby. The input is any data that is read by the program, either from a keyboard, file or other programs. The output is data that is produced by the program. The output may go to the screen, to a file or to another program.
Input & output is a large topic. We bring forward some examples to give you a general idea of the subject. Several classes in Ruby have methods for doing input/output operations. For example Kernel, IO, Dir or File.

Writing to console

Ruby has several methods for printing output on the console. These methods are part of the Kernel module. Methods of the Kernel are available to all objects in Ruby.
#!/usr/bin/ruby

print "Apple "
print "Apple\n"

puts "Orange"
puts "Orange"
The print and puts methods produce textual output on the console. The difference between the two is that the latter adds a new line character.
print "Apple "
print "Apple\n"
The print method prints two consecutive "Apple" strings to the terminal. If we want to create a new line, we must explicitly include the newline character. The newline character is '\n'. Behind the scenes. the print method actually calls the to_s method of the object being printed.
puts "Orange"
puts "Orange"
The puts method prints two strings to the console. They are on a separate line. The method includes automatically the newline character.
$ ./printing.rb
Apple Apple
Orange
Orange
Output of the printing.rb script file.

According to the Ruby documentation, the print method is an equivalent to the $stdout.print. The $stdout is a global variable which holds the standard output stream.
#!/usr/bin/ruby

$stdout.print "Ruby language\n"
$stdout.puts "Python language"
We print two lines using the $stdout variable.

Ruby has another three methods for printing output.
#!/usr/bin/ruby

p "Lemon"
p "Lemon"

printf "There are %d apples\n", 3

putc 'K'
putc 0xA
In the example, we present p, printf and putc methods.
p "Lemon"
The p calls the inspect method upon the object being printed. The method is useful for debugging.
printf "There are %d apples\n", 3
The printf method is well known from the C programming language. It enables string formatting.
putc 'K'
putc 0xA
The putc method prints one character to the console. The second line prints a newline. The 0xA is a hexadecimal code for the newline character.
$ ./printing3.rb 
"Lemon"
"Lemon"
There are 3 apples
K
Output of the example.

Printing data to the console using the kernel methods is a shortcut. A convenient way to print data. The following example shows a more formal way to print data to the terminal.
ios = IO.new STDOUT.fileno
ios.write "ZetCode\n"
ios.close
In the example, we open a standard output stream and write a string into it.
ios = IO.new STDOUT.fileno
The new method returns a stream to which we can write data. The method takes a numeric file descriptor. The STDOUT.fileno gives us the file descriptor for the standard output stream. We could also simply write 2.
ios.write "ZetCode\n"
We write a string to the opened stream.
ios.close
The input stream is closed.

On Unix systems the standard terminal output is connected to a special file called /dev/tty. By opening it and writing to it, we write to a console.
#!/usr/bin/ruby

fd = IO.sysopen "/dev/tty", "w"
ios = IO.new(fd, "w")
ios.puts "ZetCode"
ios.close
A small example in which we write to a /dev/tty file. This only works on Unix.
fd = IO.sysopen "/dev/tty", "w"
The sysopen method opens the given path, returning the underlying file descriptor number.
ios = IO.new(fd, "w")
The file descriptor number is used to open a stream.
ios.puts "ZetCode"
ios.close
We write a string to the stream and close it.

Reading input from console

In this section, we will create some code examples that will deal with reading from the console.
The $stdin is a global variable that holds a stream for the standard input. It can be used to read input from the console.
#!/usr/bin/ruby

inp = $stdin.read
puts inp
In the above code, we use the read method to read input from the console.
inp = $stdin.read
The read method reads data from the standard input, until it reaches the end of the file. The EOF is produced by pressing Ctrl + D on Unix or Ctrl + Z on Windows.
$ ./reading.rb
Ruby language
Ruby language
When we launch a program without a parameter, the script reads data from the user. It reads until we press Ctrl + D or Ctrl + Z.
$ echo "ZetCode" | ./reading.rb
ZetCode

$ ./input.rb < stones
Garnet
Topaz
Opal
Amethyst
Ruby
Jasper
Pyrite
Malachite
Quartz
The script can read data from another program or a file, if we do some redirections.

The common way to read data from the console is to use the gets method.
#!/usr/bin/ruby

print "Enter your name: "
name = gets
puts "Hello #{name}"
We use the gets method to read a line from the user.
name = gets
The gets method reads a line from the standard input. The data is assigned to the name variable.
puts "Hello #{name}"
The data that we have read is printed to the console. We use interpolation to include the variable in the string.
$ ./readline.rb
Enter your name: Jan
Hello Jan
Sample output.

In the following two scripts, we will discuss the chompmethod. It is a string method. It removes white spaces from the end of the string, if present. It is useful when doing input operations. The method name and usage comes from the Perl language.
#!/usr/bin/ruby

print "Enter a string: "
inp = gets

puts "The string has #{inp.size} characters"
We read a string from a user and calculate the length of the input string.
$ ./nochomp.rb 
Enter a string: Ruby
The string has 5 characters
The message says that the string has 5 characters. It is because it counts the newline as well.

To get the correct answer, we need to remove the newline character. This is a job for the chomp method.
#!/usr/bin/ruby

print "Enter a string: "
inp = gets.chomp

puts "The string has #{inp.size} characters"
This time we use we cut the newline character with the chompmethod.
$ ./chomp.rb 
Enter a string: Ruby
The string has 4 characters
The Ruby string has indeed 4 characters.

Files

From the official Ruby documentation we learn that the IO class is the basis for all input and output in Ruby. The File class is the only subclass of the IO class. The two classes are closely related.
#!/usr/bin/ruby

f = File.open('output.txt', 'w')
f.puts "The Ruby tutorial"
f.close
In the first example, we open a file and write some data to it.
f = File.open('output.txt', 'w')
We open a file 'output.txt' in a write mode. The open method returns an io stream.
f.puts "The Ruby tutorial"
We used the above opened stream to write some data. The puts method can be used to write data to a file as well.
f.close
At the end the stream is closed.
$ ./simplewrite.rb
$ cat output.txt
The Ruby tutorial
We execute the script and show the contents of the output.txt file.

We will have a similar example, which will show additional methods in action.
#!/usr/bin/ruby

File.open('langs', 'w') do |f|

f.puts "Ruby"
f.write "Java\n"
f << "Python\n"

end
If there is a block after the open method, then Ruby passes the opened stream to this block. At the end of the block, the file is automatically closed.
f.puts "Ruby"
f.write "Java\n"
f << "Python\n"
We use three different methods to write to a file.
$ ./simplewrite2.rb
$ cat langs
Ruby
Java
Python
We execute the script and check the contents of the langs file.

In the second example, we show a few methods of the File class.
#!/usr/bin/ruby

puts File.exists? 'tempfile'

f = File.new 'tempfile', 'w'
puts File.mtime 'tempfile'
puts f.size

File.rename 'tempfile', 'tempfile2'

f.close
The example creates a new file named 'tempfile' and calls some methods.
puts File.exists? 'tempfile'
The exists? method checks, if a file with a given name already exists. The line returns false, because we have not yet created the file.
f = File.new 'tempfile', 'w'
The file is created.
puts File.mtime 'tempfile'
The mtime method gives us the last modification time of the file.
puts f.size
We determine the file size. The method returns 0, since we have not written to the file.
File.rename 'tempfile', 'tempfile2'
Finally, we rename the file using the rename method.
$ ./testfile.rb
false
2011-11-05 16:19:36 +0100
0
Sample output.

Next, we will be reading data from the files on the disk.
#!/usr/bin/ruby

f = File.open("stones")

while line = f.gets do
puts line
end

f.close
This is a simple script, that will open a file called stones and print it contents line by line to the terminal.
f = File.open("stones")
We open a 'stones' file. The default mode is a read mode. The 'stones' file contains nine names of valued stones; each on a separate line.
while line = f.gets do
puts line
end
The gets method reads a line from the I/O stream. The while block ends when we reach the end of file.
$ ./readlines2.rb
Garnet
Topaz
Opal
Amethyst
Ruby
Jasper
Pyrite
Malachite
Quartz
Output of the example.

The next example will read data from a file.
#!/usr/bin/ruby

fname = 'alllines.rb'

File.readlines(fname).each do |line|
puts line
end
This script is another way, how we can read contents of a file. The code example will print its own code to the terminal.
File.readlines(fname).each do |line|
puts line
end
The readlines reads all lines from the specified file and returns them in the form of an array. We go through the array with the each method and print the lines to the terminal.
$ ./alllines.rb
#!/usr/bin/ruby

fname = 'alllines.rb'

File.readlines(fname).each do |line|
puts line
end
Output of the example.

Directories

In this section, we work with directories. We have a Dir class to work with directories in Ruby.
#!/usr/bin/ruby

Dir.mkdir "tmp"
puts Dir.exists? "tmp"

puts Dir.pwd
Dir.chdir "tmp"
puts Dir.pwd

Dir.chdir '..'
puts Dir.pwd
Dir.rmdir "tmp"
puts Dir.exists? "tmp"
In the script we use four methods of the Dir class.
Dir.mkdir "tmp"
The mkdir method makes a new directory called 'tmp'.
puts Dir.exists? "tmp"
With the exists? method, we check if a directory with a given name exists in the filesystem.
puts Dir.pwd
The pwd method prints a current working directory. It is a directory, where we have launched the script.
Dir.chdir '..'
The chdir method changes to another directory. The '..' directory is the parent directory of the current working directory.
Dir.rmdir "tmp"
puts Dir.exists? "tmp"
Finally, we remove a directory with the rmdir method. This time the exists? method returns false.
$ ./dirs.rb
true
/home/vronskij/programming/ruby/io
/home/vronskij/programming/ruby/io/tmp
/home/vronskij/programming/ruby/io
false
Output of the example.

In the second example, we retrieve all entries of a directory. Both files and directories.
#!/usr/bin/ruby

fls = Dir.entries '.'
puts fls.inspect
The entries method returns all entries of a given diretory.
fls = Dir.entries '.'
puts fls.inspect
We get the array of files and directories of a current directory. The '.' character stands for the current working directory in this constext. The inspect method gives us a more readable representation of the array.
$ ./allfiles.rb
["putc.rb", "simplewrite.rb", "readlines2.rb", "fileexists.rb~" ...
In the output we can see an array of files and directories.

The third example works with a home directory. Every user in a computer has a unique directory assigned to him. It is called a home directory. It is a place where he can place his files and create his own hierarchy of directories.
#!/usr/bin/ruby

puts Dir.home
puts Dir.home 'root'
The script prints two home directories.
puts Dir.home
If we do not specify the user name, then a home directory of a current user is returned. The current user is the owner of the script file. Someone, who has launched the script.
puts Dir.home 'root'
Here we print the home directory of a specific user. In our case the superuser.
$ ./homedir.rb
/home/vronskij
/root
Sample output.

Executing external programs

Ruby has several ways to execute external programs. We will deal with some of them. In our examples we will use well known Linux commands. Readers with Windows or Mac can use commands specific for their systems.
#!/usr/bin/ruby

data = system 'ls'
puts data
We call a ls command, which lists directory contents.
data = system 'ls'
The system command executes an external program in a subshell. The method belongs to the Kernel Ruby module.
$ ./system.rb
allfiles.rb characters.rb fileexists.rb homedir.rb~ ...
A sample output.

We show another two ways of running external programs in Ruby.
#!/usr/bin/ruby

out = `pwd`
puts out

out = %x[uptime]
puts out

out = %x[ls | grep 'readline']
puts out
To run external programs we can use backticks `` or %x[] characters.
out = `pwd`
Here we execute the pwd command using backticks. The command returns the current working directory.
out = %x[uptime]
Here we get the output of the uptime command, which tells how long a system is running.
out = %x[ls | grep 'readline']
We can use also a combination of commands.
$ ./system2.rb
/home/vronskij/programming/ruby/io
22:50:50 up 5:32, 1 user, load average: 0.46, 0.44, 0.45
readline.rb
readline.rb~
readlines2.rb
readlines2.rb~
Sample output.

We can execute a command with the open method. The method belongs to the Kernel module. It creates an IO object connected to the given stream, file, or subprocess. If we want to connect to a subprocess, we start the path of the open with a pipe character (|).
#!/usr/bin/ruby

f = open("|ls -l |head -3")
out = f.read
puts out
f.close

puts $?.success?
In the example, we print the outcome of the ls -l | head -3commands. The combination of these two commands return the first three lines of the ls -l command. We also check the status of the child subprocess.
f = open("|ls -l |head -3")
We connect to a subprocess, created by these two commands.
out = f.read
puts out
We read and print data from the subprocess.
f.close
We close the file handler.
puts $?.success?
The $? is a special Ruby variable, which obtains the status of the last executed child process. The success?method returns true, if the child process ended OK, false otherwise.
$ ./system3.rb
total 148
-rwxr-xr-x 1 vronskij vronskij 57 2011-10-30 23:33 allfiles.rb
-rwxr-xr-x 1 vronskij vronskij 58 2011-10-30 23:33 allfiles.rb~
true
Sample output.

Redirecting standard output

Ruby has predefined global variables for standard input, standard output and standard error output. The $stdout is the name of the variable for the standard output.
#!/usr/bin/ruby

$stdout = File.open "output.log", "a"

puts "Ruby"
puts "Java"

$stdout.close
$stdout = STDOUT

puts "Python"
In the above example, we redirect a standard output to the output.log file.
$stdout = File.open "output.log", "a"
This line creates a new standard ouput. The standard output will now flow to the ouput.log file. The file is opened in an append mode. If the file does not exist yet, it is created. Otherwise it is opened and the data is written at the end of the file.
puts "Ruby"
puts "Java"
We print two strings. The strings will not be shown in the terminal as usual, they will be appended to the output.log file.
$stdout.close
We close the handler.
$stdout = STDOUT

puts "Python"
We use a predefined standard constant STDOUT to recreate the normal standard ouput. The "Python" string is printed to a console.
In this part of the Ruby tutorial, we worked with input and output operations in Ruby.

Do you like this Tutorial? Please link back to this article by copying one of the codes below.

URL: HTML link code: BB (forum) link code:

No comments:

FAQs | Privacy Policy | Contact | | Advertise | Donate