Declaring Constants

Problem

You want to prevent a variable from being assigned a different value after its initial definition.

Solution

Declare the variable as a constant. You can't absolutely prohibit the variable from being assigned a different value, but you can make Ruby generate a warning whenever that happens.

	not_a_constant = 3
	not_a_constant = 10

	A_CONSTANT = 3
	A_CONSTANT = 10
	# warning: already initialized constant A_CONSTANT

 

Discussion

A constant variable is one whose name starts with a capital letter. By tradition, Ruby constant names consist entirely of capital letters, numbers, and underscores. Constants don't mesh well with Ruby's philosophy of unlimited changability: there's no way to absolutely prevent someone from changing your constant. However, they are a useful signal to the programmers who come after you, letting them know not to redefine a constant without a very good reason.

Constants can occur anywhere in code. If they appear within a class or module, you can access them from outside the class or module with the double-colon operator ( ::). The name of the class or module qualifies the name of the constant, preventing confusion with other constants that may have the same name but be defined in different scopes.

	CONST = 4

	module ConstModule
	 CONST = 6
	end

	class ConstHolder
	 CONST = 8

	 def my_const
	 return CONST
	 end
	end

	CONST # => 4
	ConstModule::CONST # => 6
	ConstHolder::CONST # => 8
	ConstHolder.new.my_const # => 8

The thing that's constant about a constant is its reference to an object. If you change the reference to point to a different object, you'll get a warning. Unfortunately, there's no way to tell Ruby to treat the redeclaration of a constant as an error.

	E = 2.718281828 # => 2.718281828
	E = 6 # warning: already initialized constant E
	E # => 6

However, you can use Module#remove_const as a sneaky way to "undeclare" a constant. You can then declare the constant again, without even triggering a warning. Clearly, this is potent and potentially dangerous stuff:

	# This should make things a lot simpler.
	module Math
	 remove_const(:PI)
	 PI = 3
	end
	Math::PI # => 3

If a constant points to a mutable object like an array or a string, the object itself can change without triggering the constant warning. You can prevent this by freezing the object to which the constant points:

	RGB_COLORS = [:red, :green, :blue] # => [:red, :green, :blue]
	RGB_COLORS << :purple # => [:red, :green, :blue, :purple]
	RGB_COLORS = [:red, :green, :blue]
	# warning: already initialized constant RGB_GOLORS
	RGB_COLORS # => [:red, :green, :blue]

	RGB_COLORS.freeze
	RGB_COLORS << :purple
	# TypeError: can't modify frozen array

Freezing operates on the object, not the reference. It does nothing to prevent a constant reference from being assigned to another object.

	HOURS_PER_DAY = 24
	HOURS_PER_DAY.freeze # This does nothing since Fixnums are already immutable.

	HOURS_PER_DAY = 26
	# warning: already initialized constant HOURS_PER_DAY
	HOURS_PER_DAY # => 26

 

See Also

  • Recipe 8.15, "Freezing an Object to Prevent Changes"


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net