Ruby uses lexical scoping for constants, which means that when a module references a constant directly (like CONSTANT
), Ruby looks for
that constant in the module’s own namespace first. This happens even if the same constant is defined in a class that includes the module.
This behavior can be surprising to developers who expect the including class’s constant to override or customize the module’s behavior. The module
will always use its own constant, ignoring any constants with the same name defined in including classes.
This can lead to:
- Unexpected behavior where configuration constants don’t work as intended
- Difficult-to-debug issues where changes to class constants have no effect
- Code that appears to be customizable but actually isn’t
The lexical scoping rule exists for good reasons in Ruby, but when you want a module to be customizable by including classes, you need to
explicitly access the including class’s namespace.
What is the potential impact?
This issue can cause configuration problems and unexpected behavior in applications. When developers define constants in classes to customize
module behavior, those constants will be silently ignored, leading to the module using default values instead of the intended customized ones. This
can result in incorrect application behavior that may be difficult to debug.