Module: FeatureEnvy::FinalClass
- Defined in:
- lib/feature_envy/final_class.rb
Overview
Final classes.
### Definition
A final class is a class that cannot be inherited from. In other words, a final class enforces the invariant that it has no subclasses.
### Applications
Preventing subclassing of classes that weren’t specifically designed for handling it.
### Usage
-
Enable the feature in a specific class via ‘extend Feature::FinalClass`. The class has been marked final and there’s nothing else to do. Alternatively, …
-
Enable the feature in a specific scope using a refinement via ‘using FeatureEnvy::FinalClass` and call
final!in all classes that should be marked final.
### Discussion
A class in Ruby can be made final by raising an error in its inherited hook. This is what this module does. However, this is not enough to guarantee that no subclasses will be created. Due to Ruby’s dynamic nature it’d be possible to define a class, subclass, and then reopen the class and mark it final. This edge is taken care of and would result in an exception.
Defined Under Namespace
Classes: Error
Class Method Summary collapse
- .extended(final_class) ⇒ Object
-
.final?(klass) ⇒ Boolean
Determines whether a given class is marked final.
Instance Method Summary collapse
Class Method Details
.extended(final_class) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/feature_envy/final_class.rb', line 71 def extended final_class # The class must be marked final first, before we check whether there # are already existing subclasses. If the error were raised first then # .final? would return +false+ causing confusion: if the class isn't # final then why was the error raised? @classes << final_class subclasses = Internal.subclasses final_class return if subclasses.empty? raise Error.new(final_class:, subclasses:) end |
.final?(klass) ⇒ Boolean
Determines whether a given class is marked final.
88 89 90 |
# File 'lib/feature_envy/final_class.rb', line 88 def final? klass @classes.include? klass end |