views:

40

answers:

2

From what I have read ARGV should be a constant since it is all uppercase, but I was able to write a quick program that changed one of the values in ARGV without error. So what type of variable is ARGV?

p ARGV
ARGV[0] = "Not the orginal"
p ARGV
+5  A: 

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

irb(main):031:0> ARGV.class
=> Array
irb(main):032:0> QWERTY = [1,2,3,4]
=> [1, 2, 3, 4]
irb(main):033:0> QWERTY[1] = 5
=> 5
irb(main):034:0> QWERTY
=> [1, 5, 3, 4]
irb(main):035:0> QWERTY = 3
(irb):35: warning: already initialized constant QWERTY
=> 3
Nakilon
Silly me that makes perfect sense. I guess things are slipping now that its late.
Anton
+5  A: 

ARGV is an array. Keep in mind that "constant" just means that the variable shouldn't be reassigned, not that the object itself can't change. You may be confusing it with the idea of a const object in C++. That is more equivalent to a frozen object in Ruby. (And note that even "constants shouldn't be reassigned" is a weak guarantee in Ruby. Reassigning a constant doesn't fail; it just prints a warning. It is a bad practice, though.)

To illustrate the difference:

ruby-1.9.2-p0 > CONSTANT = [1,2,3]
 => [1, 2, 3] 
ruby-1.9.2-p0 > frozen = [1,2,3].freeze
 => [1, 2, 3] 
ruby-1.9.2-p0 > CONSTANT << 4
 => [1, 2, 3, 4] 
ruby-1.9.2-p0 > frozen << 4
RuntimeError: can't modify frozen array
Chuck
If I don't do mistake, in C++ constant array doesn't disallow it's elements editing. It just "freezes" the array starting pointer.
Nakilon
Correct me, if I wrong. I have no practice in C++ for a while.
Nakilon
It does. The following code does not compile: `const int a[1] = {0}; a[0] = 1;`. On a const instance of an object, you can only call const methods, and those are not allowed to change anything inside the object. Const is actually much more of an immutability guarantee than Ruby constants. What const does not do is prevent to touch the same memory from outside. It's very easy to do with a const_cast for example. So while const is a quite strong syntactic fence, it is by no means a real immutability guarantee either.
Jean