Comment on this RCR (edit wiki page) | RCRchive home

RCR 180: Warning framework

submitted by Paul Brannan on Mon Jan 05 2004 06:35:05 AM -0800

Status: pending


Abstract

Ruby should have a framework for capturing, suppressing, and logging warnings.

Problem

Ruby currently sends all warnings to stderr. Some applications (for example, Ruby embedded in a text editor) would probably do better if they could capture warnings and present them to a user in a text box or log window. With a proper "warning framework," this would be possible.

Proposal

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

The default action for the warn func should be:

  set_warn_func proc { |warning|
    $stderr.puts warning
  }

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

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

Analysis

Handling warnings this way allows:
  1. The user can hook into the existing warn func or redefine the existing warn func altogether.
  2. 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)
  3. It has a similar interface to set_trace_func, so users will be familiar with how to use it.

Vote for this RCR

Strongly opposed [0]
Opposed [0]
Neutral [0]
In favor [12]
Strongly advocate [6]

Change the status of this RCR to:

accepted

rejected

withdrawn


Add comments here


Back to RCRchive.


RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog