You've learned how to launch external programs using both system or backticks and using the exec method. These are both fine, but only on one condition: the program launched doesn't require any input. If it does require input, it'll sit there and wait forever (unless it's a GUI program). So how do we give programs input? Using the IO.popen method.
What IO.popen does is open another program in the background and give you an IO interface that looks just like a file, network socket, or any other IO interface in Ruby. You can then write strings to it (to the program, this will look like a user typing on the keyboard), and you can read its results (again, to the program, it will think it's writing text to the screen). As you can see, this opens up a whole new realm of possibilities when it comes to working with external programs, but is only really useful if the program accepts input.
IO.popen takes two arguments. The first is the command you'd like to launch along with any arguments in a string. The second is a mode, just like you'd pass when opening a file. For both read and write, use the mode string 'w+'. The popen method will then return an IO object, just like a file. Even if you don't know how to use those, just know that you can use the methods gets and puts on them (which everyone should be familiar with).
After that, you can start giving it strings and it'll return results (depending on what the program does). In this example, I've opened the bc command line calculator. The first puts you'll see sets the calculator's output base to 16, so it'll give results in hex. It'll then enter an infinite loop and any input you pass to it, it will pass to bc, then read one line back from bc.
bc = IO.popen('bc -q', 'w+')
bc.puts('obase=16') # Output numbers in hex
puts "Convert numbers to hex"
print "Enter a number: "