Project

General

Profile

Feature #2975

Updated by nahi (Hiroshi Nakamura) about 12 years ago

=begin 
  
  Kernel.warn always writes despite $VERBOSE value 
 
  The RDoc say: 
  http://www.ruby-doc.org/core/classes/Kernel.html#M005921 
  warn(msg) => nil 
  Display the given message (followed by a newline) on STDERR unless warnings are disabled (for example with the -W0 flag).  
 
  (from Ruby.h, ver 1.8.6, line 562..564, Language="C" ) 
  void rb_warning __((const char*, ...)); /* reports if `-w' specified */ 
  void rb_sys_warning __((const char*, ...)); /* reports if `-w' specified */ 
  void rb_warn __((const char*, ...)); /* reports always */ 
 
  In ver 1.8.6, in practice Kernel.warn (and by inclusion,) anyobject's instance method warn, outputs no matter what the setting of $VERBOSE. It then appears to work as though it's calling rb_warn in the core, but the RDoc seems to say it should act like it's calling rb_warning in the core. 
 
  This has forced me to make my 'warn' calls work the way they should, by doing this: 
 
  # Send warning only if in Verbose mode 
  warn('My Informational Message') if $VERBOSE 
 
  # Send warning unless in Silent mode 
  warn('My Important Message') unless $VERBOSE.nil? 
 
  # Send warning no matter what Verbose mode 
  warn('My Critical Message that MUST be displayed!') 
 
  I'm tired of this workaround: 
  I think we need something like this overrride, where I define 3 methods, 
  warn, warn?, warn! 
  and in addition, I have them return a boolean result (the original warn just returned nil.) 
 
  #!ruby warn_ovr.rb 
  # Make Warnings work the way they should. 
  # by: Dan Rathbun - 16 MAR 2010 - Palm Bay, FL, USA 
  # TERMS: Public Domain, Take it, Use it, Abuse it! 
 
  module Kernel 
 
    # alias the old warn method 
    alias_method(:old_warn,:warn) 
 
    # warn! will always send to $stderr 
    # regardless of $VERBOSE setting 
    def warn!(msg) 
      unless msg.is_a?(String) 
        raise(TypeError,'String argument expected.',caller(1)) 
      end 
      $stderr.write(msg + "\n") 
      return true # no IO error occured 
    end 
 
    # warn will now send to $stderr 
    # ONLY if $VERBOSE is not Silent mode (nil) 
    def warn(msg) 
      unless msg.is_a?(String) 
        raise(TypeError,'String argument expected.',caller(1)) 
      end 
      unless $VERBOSE.nil? 
        $stderr.write(msg + "\n") 
        return true 
      else 
        return false 
      end 
    end 
 
    # warn? will send to $stderr 
    # ONLY if $VERBOSE is in Verbose mode (true) 
    def warn?(msg) 
      unless msg.is_a?(String) 
        raise(TypeError,'String argument expected.',caller(1)) 
      end 
      if $VERBOSE 
        $stderr.write(msg + "\n") 
        return true 
      else 
        # We return false if $VERBOSE is nil or false 
        return false 
      end 
    end 
 
  end # Kernel 
 
  NOTE: The above override script does not override the Module method Kernel.warn, only the instance method. (I could have just run the script in the ObjectSpace without the Kernel wrapper, and added the methods to class Object. Their use either way is the same.) 
 
 =end 
 

Back