Category Archives: Ruby Tips and Tricks

Comes Now, DebugHelper

I have no idea how many times I’ve typed code like this (to do printf-style debugging):


my_hash.each_pair do |key, value|
  p [key, value]
end

I’ve finally wised up, and built a helper method to support this:

DebugHelper.printf(data)

The method allows any data, and specifically supports Hash-like and Array-like structures.

It also allows an optional name (defaults to data class-name) and message.

Typical outputs:


Hash (size=3)
  a => 0
  b => 1
  c => 2

Array (size=3)
  0: a
  1: b
  2: c

And here’s my helper class:

# Class to help in 'printf' debugging.
class DebugHelper
  def self.printf(data, name = data.class.to_s, description = '')
    size = data.respond_to?(:size) ? data.size : 1
    puts format('%s (size=%d) %s', name, size, description)
    case
      when data.respond_to?(:each_pair)
        # Hash-like.
        data.each_pair do |k, v|
          puts format('  %s => %s', k, v)
        end
      when data.respond_to?(:each_with_index)
        # Array-like or Set-like.
        data.each_with_index do |v, i|
          puts format('  %6d: %s', i, v)
        end
      else
        puts format('  %s', data.inspect)
    end
    nil
  end
end

Method Name As Documentation

Hey, Ruby coders!

Do you recognize this idiom?

Object.const_get(class_name)

Or this one?

Object.const_get(class_name).new(*args)

When I wanted to do these two things in my RubyTest project, I had to Google to find out how.

Now if I put this code into my project, will I recognize these idioms later on? Next month? Next year?

I could add comments to explain, but a comment can get stale (not keep up with code changes), or get separated from its code, or even get deleted.

You can help your downstream code enhancer/maintainer by pushing an unusual idiom into a well-named method.

(Hint: If you’re not sure who is the downstream enhancer/maintainer, it’s you!)

Thus, I created this:

class ObjectHelper

  def self.get_class_for_class_name(class_name)
    Object::const_get(class_name)
  end

  def self.instantiate_class_for_class_name(class_name, *args)
    self.get_class_for_class_name(class_name).new(*args)
  end

end

PS: My GitHub project is about test automation in Ruby. It has a Tester Tour of the demo testing for a web UI and for a REST API.