What's the Point of Argv in Ruby

what is ARGV in ruby and what does it do?

ARGV is basically an array that contains the elements passed to your script. You may find this StackOverflow question useful.

To test it, try creating .rb (let's say it's "test.rb") file in specific folder and put the following code there:

puts ARGV.inspect

Now, try opening a command line window/terminal and point it to the folder where "test.rb" is. Once you're there, type this in your terminal:

ruby test.rb a 1 b 

You should get ["a", "1", "b"] which is the content of ARGV.

ARGV in Ruby: The Meaning of a Constant

A constant has to have its value newly assigned at some point. If you take the meaning of constant as something that is never newly assigned its value, then there would be no constant at all. A constant is therefore, a relative notion; you cannot define what a constant is without the relevant domain/scope. A constant remains consistant within that domain, but has its value assigned/changed outside of the scope.

In mathematics, suppose some mathematician used a constant A = 3 at some point in their life solving a certain problem. That does not mean that everyone from that point on using the constant A would always have to assume its value to be 3. In mathematics, the domain of a constant can be a single proof, an article, a book, or a convention throughout a subfield, etc.

For a computer program, the domain for a constant is usually the execution lifespan of a program. A constant remains constant relative to the execution of the program. ARGV has its values set prior to the execution of the Ruby program.

What kind of variable is ARGV in ruby?

ARGV is a constant, but it's an Array. Values in a constant array can be freely changed without any warnings, like any usual array element.

irb(main)> ARGV.class
=> Array
irb(main)> QWERTY = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main)> QWERTY[1] = 5
=> 5
irb(main)> QWERTY
=> [1, 5, 3, 4]
irb(main)> QWERTY << 6
=> [1, 5, 3, 4, 6]
irb(main)> QWERTY = 3
(irb): warning: already initialized constant QWERTY
=> 3

Ruby escape ARGV argument or string as argument to shell command

Use require 'shellwords' and Shellwords.escape, which will fix this sort of stuff for you:

http://apidock.com/ruby/Shellwords/shellescape

Use ARGV[] argument vector to pass a regular expression in Ruby

Meditate on this:

I wrote a little script containing:

puts ARGV[0].class 
puts ARGV[1].class

and saved it to disk, then ran it using:

ruby ~/Desktop/tests/test.rb foo /abc/

which returned:

String
String

The documentation says:

The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. '\d' will match a backlash followed by ‘d’, instead of a digit.

That means that the regular expression, though it appears to be a regex, it isn't, it's a string because ARGV only can return strings because the command-line can only contain strings.

When we pass a string into sub, Ruby recognizes it's not a regular expression, so it treats it as a literal string. Here's the difference in action:

'foo'.sub('/o/', '') # => "foo"
'foo'.sub(/o/, '') # => "fo"

The first can't find "/o/" in "foo" so nothing changes. It can find /o/ though and returns the result after replacing the two "o".

Another way of looking at it is:

'foo'.match('/o/') # => nil
'foo'.match(/o/) # => #<MatchData "o">

where match finds nothing for the string but can find a hit for /o/.

And all that leads to what's happening in your code. Because sub is being passed a string, it's trying to do a literal match for the regex, and won't be able to find it. You need to change the code to:

sub(Regexp.new(ARGV[1]), '')

but that's not all that has to change. Regexp.new(...) will convert what's passed in into a regular expression, but if you're passing in '/o/' the resulting regular expression will be:

Regexp.new('/o/') # => /\/o\//

which is probably not what you want:

'foo'.match(/\/o\//) # => nil

Instead you want:

Regexp.new('o') # => /o/
'foo'.match(/o/) # => #<MatchData "o">

So, besides changing your code, you'll need to make sure that what you pass in is a valid expression, minus any leading and trailing /.

Am unable to combine gets.to_i with ARGV arguments, in Ruby

ARGV looks like an array, but it doesn't behave exactly like one. You won't have access to the second argument, unless you remove the first one first. Your code works if you rewrite it like this:

a, b, c, d, e, f = (0..5).map { ARGV.shift }

puts "you will first go to point #{a}, then #{b}, then #{f}, finishing off with #{e} and finally #{d}."

print "Give me a number: "
time = gets.to_i

puts "you can start at #{time}"


Related Topics



Leave a reply



Submit