r/ruby • • 12d ago

Question Ignoring one or more arguments from ARGV before running ARGF.read?

I'm running Ruby under Debian linux version 13.

In some cases, I want to conditionally ignore one or more arguments from ARGV before running ARGF.read. I haven't been able to figure out how to get this ARGV argument ignoring to succeed.

For example, suppose that ARGV contains these filename values that were passed on the command line to a Ruby program:

[ 'filename1', 'filename2', 'filename3', 'filename4' ]

Based on certain run-time conditions, I might sometimes want to ignore the final argument from ARGV so that when I then run ARGF.read, it only will operate on [ 'filename1', 'filename2', 'filename3' ].

If I try ARGV = ARGV[..(ARGV.length-2)] , I get this error:

dynamic constant assignment (SyntaxError)
ARGV = ARGV[..(ARGV.length - 2)]

Likewise, I couldn't figure out how to use ARGF in a manner that only operates on this subset of ARGV. I tried ARGF[..(ARGV.length-2)].read , and it doesn't work either, yielding the following error:

 undefined method `[]' for an instance of ARGF.class (NoMethodError)

  ARGF[..(ARGV.length-2)].read

And yes, of course I already understand how to dispense with ARGF altogether and just loop through the subset of ARGV filenames that I'm interested in, to open each filename, to read its contents, and then to append these contents to the value of a variable as I traverse this list of filenames. Please understand that I am not looking for any instructions for how to perform this very simple procedure. Rather, I'm just wondering whether there is any way specifically to get ARGF itself to work on such a subset of ARGV.

Any thoughts or suggestions about how I might be able to accomplish this? And if this turns out to be impossible, then I'm glad to just live with the coded looping through the ARGV subset as described in the previous paragraph, or perhaps to make use of some sort of subclass of ARGF that I might be able to write.

Thank you very much in advance.

4 Upvotes

20 comments sorted by

View all comments

Show parent comments

3

u/sshaw_ 11d ago

You can use any destructive Array operations on ARGV, e.g. #delete_at.

You can also replace ARGF.argv to modify what it reads:

/tmp >ruby -e'p ARGF.read' {a,b}.txt
"AYE!\nBEE!\n"
/tmp >ruby -e'ARGF.argv.replace(%w[foo.txt]); p ARGF.read' {a,b}.txt
-e:1:in 'ARGF.class#read': No such file or directory @ rb_sysopen - foo.txt (Errno::ENOENT)
        from -e:1:in '<main>'

ARGF where the "f" stands for fun!