class PrintyPrintyBangBang

Introduction

PrintyPrintyBangBang is a funny little class designed to do two things:

Use

A typical mrSCPI application will not directly use PrintyPrintyBangBang instead depending on a SCPIsession instance to manage the global PrintyPrintyBangBang instance. For example, while PrintyPrintyBangBang maintains a list of global options and a PrintyPrintyBangBang#set method, most mrSCPI applications will use the SCPIsession#set in the SCPIsession class – which will forward the appropriate options to the global PrintyPrintyBangBang instance. That said, it is perfectly acceptable to use PrintyPrintyBangBang directly – if you wish to log something outside of the SCPIsession for example.

PrintyPrintyBangBang is a Singleton. The normal way to use it is as follows

PrintyPrintyBangBang.instance.logPrinter(1, "ERROR: :url was malformed: #{urlString.inspect}", self, 70)

Note that when PrintyPrintyBangBang is made aware of a new output file, it will open that file and keep it open until close is called or another file is specified. Output files are specified by strings – not file handles!

Public Class Methods

new() click to toggle source
# File src/mrSCPI.rb, line 1391
def initialize ()
  @gblOpt    = { :log_file       => 'STDERR',
                 :out_file       => 'STDOUT',
                 :verbose        => 1,
                 :exit_0         => false,
                 :exit_on_error  => false,
                 :print_max_len  => 0,
                 :print_debug    => false
               }
  @openFiles = { 'STDERR'    => STDERR,
                 'STDOUT'    => STDOUT,
                 '/dev/null' => nil
               }
end

Public Instance Methods

close() click to toggle source

Close all open files except STDERR, STDOUT, & /dev/null. Sets @gblOpt[:log_file] to 'STDERR' & @gblOpt[:out_file] to 'STDOUT'.

# File src/mrSCPI.rb, line 1517
def close
  @openFiles.each do |fileName, fileDescriptor|
    if fileDescriptor
      fileDescriptor.close
    end
  end
end
logPrinter(level, msg, source, exitCode=nil) click to toggle source

Print a message to @gblOpt[:log_file]

  • level

    An integer. If @gblOpt[:verbose]>=level, then the message will be printed

  • msg

    The message to print (usually a string)

  • source

    The source of the message. It is prepended to all printed messages. Usually set to self.

  • exitCode

    If non-nil and @gblOpt[:exit_on_error] is non-nil, then causes a process exit with the given code

# File src/mrSCPI.rb, line 1460
def logPrinter (level, msg, source, exitCode=nil)
  #lineNumberThatCalledUs = caller.first.to_s.sub(/^.*:([0-9]+):in.*$/, '\1')
  begin
    if @gblOpt[:verbose] >= level then
      if @openFiles[@gblOpt[:log_file]] then
        @openFiles[@gblOpt[:log_file]].puts("#{((source && source.class.to_s.upcase) || 'UNKNOWN')}: #{msg}")
        @openFiles[@gblOpt[:log_file]].flush
        #@openFiles[@gblOpt[:log_file]].fsync
      end
    end
  rescue
      if @openFiles[@gblOpt[:log_file]] != 'STDERR' then
        @openFiles[@gblOpt[:log_file]] = 'STDERR'
        retry
      else
        # Not really sure what to do here...  We couln't print to the error log file or to STDERR...
      end
  end
  if exitCode && @gblOpt[:exit_on_error] then
    if @gblOpt[:exit_0] then
      exit 0
    else
      exit exitCode
    end
  end
end
outPrinter(msg, newline=true) click to toggle source

Print a message to @gblOpt[:out_file]

  • newline

    If non-nil, then puts will be used. Otherwise write is used.

# File src/mrSCPI.rb, line 1490
def outPrinter (msg, newline=true)
  if @openFiles[@gblOpt[:out_file]] then
    msgToPrint = msg
    truncMsg   = ''
    if @gblOpt[:print_debug] then
      msgToPrint = msgToPrint.inspect
    end
    if @gblOpt[:print_max_len] && (@gblOpt[:print_max_len] > 0) && (msg.length > @gblOpt[:print_max_len]) then
      msgToPrint = msgToPrint.slice(0, @gblOpt[:print_max_len]);
      truncMsg = "LAST LINE TRUNCATED (:print_max_len=#{@gblOpt[:print_max_len]})"
    end
    if newline || @gblOpt[:print_debug] then
      @openFiles[@gblOpt[:out_file]].puts(msgToPrint)
    else
      @openFiles[@gblOpt[:out_file]].write(msgToPrint)
    end
    if !(truncMsg.empty?) then
      @openFiles[@gblOpt[:out_file]].puts(truncMsg)
    end
    @openFiles[@gblOpt[:out_file]].flush
    #@openFiles[@gblOpt[:out_file]].fsync
  end
end
set(options) click to toggle source

Set options in @gblOpt. Possible options:

  • :log_file
  • :out_file
  • :verbose
  • :exit_0
  • :exit_on_error
  • :print_max_len
  • :print_debug

See the SCPIsession class for details on these options.

In normal mrSCPI operation, one sets these options on a SCPIsession#set, and the SCPIsession object will propagate the options through to the global PrintyPrintyBangBang instance. That said, in Ruby programs using SCPIsession, one can directly call PrintyPrintyBangBang#set if desired.

# File src/mrSCPI.rb, line 1428
def set(options)
  optionsWacked = Array.new
  [ :log_file, :out_file].each do |k|
    if options.member?(k) then
      if !(@openFiles.member?(options[k])) then
        begin
          @openFiles[options[k]] = open(options[k], "wb")
        rescue
          @openFiles.delete(options[k])
          # Note: The previous :log_file will still be set at this point, so hopefully we can print this error
          PrintyPrintyBangBang.instance.logPrinter(1, "ERROR: Failed to open file: #{options[k].inspect} for #{k.inspect}!", self, 84)
        end
      end
      optionsWacked.push(k)
    end
  end
  options.each do |opt, val|
    if @gblOpt.member?(opt) then
      @gblOpt[opt] = val
      optionsWacked.push(opt)
      options.delete(opt)
    end
  end
  return optionsWacked
end
validOptions() click to toggle source

Return an array of valid option keys.

This is used by SCPIsession to forward options to the global PrintyPrintyBangBang instance.

# File src/mrSCPI.rb, line 1410
def validOptions()
  return @gblOpt.keys
end