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 |