Command-line Arguments in Ruby: Part I

In this article we’re going to explore the following topics:

  • the ARGV array
  • the ARGF (weird) object
  • my_cat.rb

the ARGV array

ARGV stands for ARGument Vector — as a vector is a one-dimensional array.

It contains the full list of arguments inserted in the given command-line order.

So, let’s have a look to the following example

$> cat list_argv.rb
p ARGV.class
p ARGV
$> ruby list_argv.rb arg1 arg2 arg3
Array
["arg1", "arg2", "arg3"]

ARGV contains the 3 arguments passed to the program ruby list_argv.rb.

Note that the filename list_argv.rb isn’t included in ARGV.

["arg1", "arg2", "arg3"]

the ARGF object

ARGF is a stream designed for use in scripts that process files given as command-line arguments or passed in via STDIN. Ruby-Doc

ARGF is an instance of a hard-coded class called ARGF.class

irb> ARGF
ARGF
irb> ARGF.class
ARGF.class
irb> ARGF.class.class
Class

So, here we see that ARGF is an instance of ARGF.class which is a class.

So let’s have a look to its ancestors chain

irb> ARGF.class.ancestors
=> [ARGF.class, Enumerable, Object, Kernel, BasicObject]

ARGF shares a bunch of method with the IO class such as read, each_line, etc..

It also includes the Enumerable module. This means that it acts as a collection of objects.

Now, let’s see what’s the purpose of ARGF by implementing an example.

NB: feel free to have a look to Ruby Object Model — Part 1 article if you’re unfamiliar with the Ruby Ancestors Chain concept.

my_cat.rb

The cat command-line utility allows you to concatenate and print files

$> cat test1 test2
I'm test1
I'm test2
$> echo "STDIN" | cat
STDIN
$> echo "STDIN" | cat test1 - test2
I'm test1
STDIN
I'm test2

It reads files sequentially, writing them to the standard output (STDOUT).

The file operands are processed in command-line order.

If one of the files is a single dash (-) or absent, cat reads from the standard input (STDIN).

Pretty cool. isn’t it ?

So, let’s see how to implement the cat utility in Ruby.

In my_cat.rb

puts ARGF.read

Now let’s start our program

$> ruby my_cat.rb test1 test2
I'm test1
I'm test2
$> echo "STDIN" | ruby my_cat.rb
STDIN
$> echo "STDIN" | ruby my_cat.rb test1 - test2
I'm test1
STDIN
I'm test2
$> ruby my_cat.rb --verbose
No such file or directory @ rb_sysopen - --verbose (Errno::ENOENT)

We get the same output as with the cat utility.

ARGF.read also handle the single dash - argument.

ARGF treats each entry of the ARGV array as a file or as the standard input if the entry is a single dash.

If ARGV is empty then ARGF will read on STDIN.

It raises a No such file or directory error if the argument isn’t a file.

So, feel free to clean the ARGV array before to use ARGF — as it treats each argument as a file.

Voilà !

Feel free to have a look to the Part II.

May I have your attention please 🎤🎤

Feel free to subscribe here: www.rubycademy.com


Thank you for taking the time to read this post :-)

Feel free to 👏 and share this Medium post if it has been useful for you.

Here is a link to my last medium post: The super keyword.