PiperWarrior PiperWarrior - 6 months ago 8
Ruby Question

Assignment to constant within body of method

"The Ruby Programming Language" by David Flanagan & Yukihiro Matsumoto states the following in Section 4.5.2 Assigning to Constants


Assignment to constants is not allowed within the body of a method.


I understand the premise and try two variations of code:

PERSONS = {}

def create_persons(filename)
File.foreach(filename).with_index do |line, number|
array = line.split(' ').unshift(number+1)
hash = {:id => array[0],:first_name => array[1], :last_name => array[2], :email => array[3]}
PERSONS = hash
end
end


I get an error:

santa.rb:13: dynamic constant assignment
PERSONS = hash
^


The I try second version, where instead of assigning using the equal operator, I initialize an empty array as constant and use the append operator to append hash to empty array. This works!

PERSONS = []

def create_persons(filename)
File.foreach(filename).with_index do |line, number|
array = line.split(' ').unshift(number+1)
hash = {:id => array[0],:first_name => array[1], :last_name => array[2], :email => array[3]}
PERSONS << hash
end
end


My question is why does the second version work when I use the << assignment operator, but does not work with = assignment operator.

Answer

The odd thing about constants in Ruby is you can define them once, but modify them endlessly unless they're frozen. The first one is a problem because you're switching which object PERSONS refers to. In the second case you're adding something to an existing object, this is allowed.

Technically it's possible to redefine constants but this is best avoided.