Class: Mutant::Warnings Private
- Inherits:
-
Object
- Object
- Mutant::Warnings
- Defined in:
- lib/mutant/warnings.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Class to capture warnings generated by Kernel#warn and Ruby itself.
Note this API is fundamentally impure:
-
Unlike almost all of classes in the mutant code base it has internal mutable state
-
Its therefore NOT thread safe
-
And worst: Each instance, even after its not referenced anymore by user code: Leaks permanent global state as instances of this class hook itself into the ‘Warning` module.
So ideally only make one instance, and re-use it.
Also note, a more canonical implementation would prepend modules and simply call ‘super` in the event the capture is disabled. This sadly does not work as it would inference with various bad players in the ruby ecosystem that do not adhere to the semantics outlined in the documentation.
See: ruby-doc.org/core-2.6.3/Warning.html
For example in case rubygems is active it adds its own hook to warnings, that would in case of the super implementation cause infinite recursion.
Reproduction for this case is as simple as:
“‘ require ’rubygems’
module Warning
def warn(*)
super
end
end “‘
For that reason we do have to use the original method capture to dispatch in disabled state.
ignore :reek:RepeatedConditional
Defined Under Namespace
Classes: RecursiveUseError
Instance Method Summary collapse
-
#call ⇒ Array<String>
private
Run a block with warning collection enabled.
-
#initialize(warning) ⇒ undefined
constructor
private
Initialize object.
Constructor Details
#initialize(warning) ⇒ undefined
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Initialize object
69 70 71 72 73 74 75 76 77 78 |
# File 'lib/mutant/warnings.rb', line 69 def initialize(warning) @disabled = true @messages = [] @original = warning.public_method(:warn) capture = method(:capture) warning.module_eval do module_function define_method(:warn, &capture) end end |
Instance Method Details
#call ⇒ Array<String>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Run a block with warning collection enabled
83 84 85 86 87 88 89 90 91 |
# File 'lib/mutant/warnings.rb', line 83 def call assert_no_recursion @disabled = nil yield IceNine.deep_freeze(@messages.dup) ensure @disabled = true @messages.clear end |