Magic Numbers are hard coded, static values. That said, they can be of several types like Integer, String or others. Very often they are supplied with additional describing comments. However they are a code smell.
Magic Numbers are bad
- Magic Numbers are a maintenance risk (the same value could be used in a different context and be changed by accident)
- Magic Numbers decrease readability (even if the are decorated with comments)
- Magic Numbers tempt to excessive code (that holds true for String in particular)
Basically the same rule applies to to Magic Numbers as it does for code repetitions: duplicates have to be extracted and referenced.
Named Constants are good
Named Constants are the appropriate remedy for Magic Numbers. As a result comments are dispensable and value changes are narrowed down to a single place (no risky search & replace any more).
At this point the term Named Constant was choosen, although in most literature (like Refactoring, Improving The Design Of Existing Code by Martin Fowler) they are called Symbolic Constant. The reason why is the possible confusion with the concept of a Symbol in Ruby.
Ruby already provides some meaningful constants. For instance inside the class Math:
Math::PI # => 3.141592653589793
A simple example
The method color either returns the defined color or the default color:
module Inkable
attr_writer :color
def color
color || '#178C18'
end
end
Introducing a constant is a win from the readability perspective alone:
module Inkable
DEFAULT_COLOR_GREEN = '#178C17'
attr_writer :color
def color
color || DEFAULT_COLOR_GREEN
end
end
Ruby helps
Moreover Ruby is designed to prevent the extensive use of numbers anyway.
Some language certainly necessitate such practice:
numbers = [1, 2, 3]
language = "Ruby"
# bad
numbers[0] # => 1
numbers.size > 0 # => true
language.length == 0 # => false
but Ruby does not:
# good
numbers.first # => 1
numbers.any? # => true
language.zero? # => false
Big salutes go to Dave Aronson and Todd Knarr for proofreading and discussing.