Feature #12299
closedAdd Warning module for customized warning handling
Description
This is another attempt to provide the same type of support for customized warning handling as #12026. matz had a couple of issues with #12026. First, he did not like the introduction of a new global variable. Second, he wanted the ability to control warning handling on a per-gem and/or per-class basis.
The approach in this patch adds a Warning module instead of using a global variable, and allows for per-gem customization by using separate processing for separate gems based on the path prefix in the warning message. I don't think per-class warnings are possible without major changes.
This changes all warnings raised call to Warning.warn, which by default does the same thing it does currently (rb_write_error_str). You can override Warning.warn to change the behavior.
To provide a common API that can be used to modify warnings, add a lib/warning.rb file, which offers three methods: Warning.ignore, Warning.process, and Warning.clear.
Warning.ignore takes a regexp and optionally a path prefix, and ignores any warning that matches the regular expression if it starts with the path prefix.
Warning.process takes an optional path prefix and a block, and if the string starts with the path prefix, it calls the block with the warning string instead of performing the default behavior. You can call Warning.process multiple times and it will be operate intelligently, choosing the longest path prefix that the string starts with.
Warning.clear just clears the current ignored warnings and warning processors.
By using path prefixes, it's fairly easy for a gem to set that warnings should be ignored inside the gem's directory.
Note that path prefixes will not correctly handle warnings raised by Kernel#warn, unless the warning message given to Kernel#warn starts with the filename where the warning is used.
Note that the current implementations of Warning.ignore, Warning.process, and Warning.clear in the patch are not thread safe, but that can be changed without much difficulty.
Examples from the RDoc in the patch:
# Ignore all uninitialized instance variable warnings
Warning.ignore(/instance variable @\w+ not initialized/)
# Ignore all uninitialized instance variable warnings in current file
Warning.ignore(/instance variable @\w+ not initialized/, __FILE__)
# Write warning to LOGGER at level warning
Warning.process do |warning|
LOGGER.warning(warning)
end
# Write warnings in the current file to LOGGER at level error
Warning.process(__FILE__) do |warning|
LOGGER.error(warning)
end
Files