Submitted by Paul Brannan (Mon Jan 05 11:01:05 UTC 2004)
Ruby should call a method when a warning occurs; this will allow the user to define their own handler for warnings. This method should be a proc set via a method set_warn_func and should take as a parameter a String or a Warning object:
Warning = Struct.new(
:level, # integer from 1 to 10 :file, # file the warning came from (String) :line, # line number the warning came from (Numeric) :msg) # the actual warning message class Warning def to_s return msg() end end</pre>
The default action for the warn func should be:
set_warn_func proc { |warning|
$stderr.puts warning }</pre>
Calling set_warn_func with nil should reset Ruby to the default action.
The return value of set_warn_func should be the previously defined warn func so that warn funcs can be chained (Note: This differs from the behavior of set_trace_func, and I'm not sure how to reconcile this difference without giving up this feature).
In addition, the warn() method should be changed to accept:
1. warn(Warning) #=> call the warn func with the given warning
2. warn(String, Fixnum) #=> create a new Warning with the given message and # warn level and pass it to the warn func 3. warn(String) #=> create a new Warning with the given message and # default warn level and pass it to the warn func</pre>
An example:
set_warn_func proc { |warning|
warning = Warning.new(warning) if not Warning === warning if warning.level < 10 or warning.file == "a_file_I_want_to_ignore_warnings_in.rb" then # ignore this warning else $stderr.puts(warning) send_email_to_me_about(warning) end } class Foo def foo; end def foo; end # doesn't print anything since the warning's level is # too low end</pre>
<li>The user can hook into the existing warn func or redefine the existing warn func altogether. <li>The user can still call the warn() method with a String (so the existing interface for warn() is not broken) or with a Warning object (so, for example, drb can marshal warnings across the wire and have them show up as warnings on the client) <li>It has a similar interface to set_trace_func, so users will be familiar with how to use it.
Comments | Current voting | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
RCRchive copyright © David Alan Black, 2003-2005.
Powered by .
Having warnings behave like exceptions is an approach I have seen work well in. They can be rescued and logged, or converted into exception if appropriate (there might be areas of you code where particular warnings are unacceptable). This approach would require the addition of a "continue" (or equivalent) operation for rescue blocks which would simply continue the execution immediately following the raise statement. The "continue" operation would probably need to check the exception object and refuse to continue non-warning exceptions, just to be on the safe side.