Saturday 14 March 2009

Constants

The Ruby interpreter will take anything that has a name beginning with a capital letter as being a constant.
# Variables
n = 67
s = 'my string'

#Constants
N = 89
TITLE = 'My great program'
class MyClass end


Not really constant?
Variables and constants are really pointers to objects. This has some practical consequences that may be unexpected. Let us set some up:
S = s = 'My string'
N = n = 23
X = x = 12.6

Then we can see what happens what we modify the object:
s << ' is longer'
n += 4
x += 3.5

Perhaps the odd thing here is that modifying s also modifies the constant, S. But is that so odd? Both s and S point to the same string. Modify the string, and naturally what they both point to has changed. So what is surprising is that the others have not changed (as an aside, this is also the situation in Java, but in Java, numbers are primitives, not objects; in Ruby everything is an object). Numbers have one object each to represent each value (though they will not all exist in te virtual machine t any one time of course). Change the value, and it will point to a new instance that stands for the new value.

Note that for the string, I used << rather than +=. Although they both concatenate strings, The former changes the existing string, while the latter creates a new string. If I had used += in the above, s would change to point to the new string, while S would still point to the old string.

So you can readily modify the object that a constant points to, but you cannot change what object it points to... Can you? Well, yes you can. The only issue is that the interpreter gives a warning. Here is an IRb session:
irb(main):011:0> Constant = 'My string'
=> "My string"
irb(main):012:0> Constant = 56
(irb):12: warning: already initialized constant Constant
=> 56

It turns out that constants are only really constant by convention, and there is nothing to stop you changing them and no guarantee that they will remain the same (just as setting a method as private is no guarantee that it cannot be invoked from anywhere).

Struggling with Ruby: Contents Page

1 comment:

daze said...

hey, I just thought to inform you that I enjoy your blogs tremendously :)

keep it up...