Wrestling side effects on skis, in space.

Debugging Ruby code for non-rubyists

Suppose you program in Python, PHP, or some other popular language. But suddenly, you end up maintaining a Linux distribution package of a program written in Ruby. Or inherit a project that contains hacky Ruby scripts glued together by even more hacky shell scripts. Or you have to fix a Chef cookbook. And now you're supposed to track down a bug or understand a patch.

Here are some things that might come in handy for observing and debugging Ruby code - we'll be discussing methods that can help you in inspecting objects, logging, exploring execution context and looking up definitions of methods.


The following methods help with inspecting objects and data structures and putting them on the screen.


p is your best friend. It inspects an object. In other words, it calls object's inspect method, which returns its string representation. It then stdouts whatever it finds, be it a number - like 10, a list or an array, like 1, 2, 3, 4 or a hash (dictionary) of key-value pairs like 'foo' : 'bar' and 'bar' : 'baz':

p number
=> 10

p list
=> [1, 2, 3, 4]

p hash
=> {:foo=>:bar, :bar=>:baz}

p also accepts multiple arguments and each of those will be inspected in turn:

p number, list
=> 10
  [1, 2, 3, 4]

To send info to stderr, you can use the warn method. warn is useful as the stream representing the standard error is not buffered. However, unlike p, it does not call inspect automatically, so you need to call it explicitly.

warn hash.inspect
=> {:foo=>:bar, :bar=>:baz}

(Tip: unbufferred writes to standard output can be enabled by setting STDOUT.sync = true)


When viewing nested hashes or complex data structures, the output of p can be hard to read. JSON to the rescue! It pretty-prints the representation of any object that can be converted to JSON format.

First, require the JSON library:

require 'json'


puts JSON.pretty_generate(hash)
=> {
    "foo": "bar",
    "bar": "baz"


Using real logging instead of p or warn is handy when debugging existing applications. The ruby Logger has a simple interface. To log a message with certain log level, simply call an appropriate method:

log.fatal("Oh no, it crashed.")
log.error("This is an error.")
log.warn("This is a warning.")
log.info("Just wanted to say hi.")
log.debug("Too many details here!")

Frameworks like Rails often expose a logger that extends or at least has the same interface as the one from the Ruby standard library:

Rails.logger.info("Logging info about a web request").

but of course, you can create your own logger:

require 'logger'
log = Logger.new("debug.log")

Useful trick, especially when there are many messages already being logged, can be to add a 'tag' to the message body

log.debug("FOO This is important debug information.")

that can be easily grepped for:

$ tail -f debug.log | grep FOO
D, [2014-06-22T01:24:27.611669 #3814] DEBUG -- : FOO This is important debug information.

or to simply raise the minimal log level, so only messages above this level are actually written into the logfile:

log.level = Logger::WARN

State and context

Current time with microsecond precision

Sometimes a precise time stamp can reveal relative ordering of execution, or helps spotting slow parts of the program

=> 1402595441.01877

returns the current time as a UNIX time stamp with microseconds.

Current process info

The process pid and the (real) uid and gid are, somewhat unsurprisingly, accessible via Process.pid, Process.uid and Process.gid.

Current values of instance variables

In Ruby, it is possible to get current values of object instance variables in a very simple way:

instance_variables.each { |name| puts "#{name}=#{instance_variable_get(name)}" }


Where is this method called from? caller to the rescue! It is an array that contains the current backtrace. caller[0] is the current method's caller, caller[1] the caller's caller, etc...

=> ["/home/bkutil/.gem/ruby/2.1.0/gems/pry- `eval'",
  "/home/bkutil/.gem/ruby/2.1.0/gems/pry- `evaluate_ruby'",
  "/home/bkutil/.gem/ruby/2.1.0/gems/pry- `re'",
  "/home/bkutil/.gem/ruby/2.1.0/gems/pry- `rep'",
  "/home/bkutil/.gem/ruby/2.1.0/gems/pry- `block (3 levels) in repl'",


Current file and line

For logging the current file and line, Ruby provides two constants __FILE__ and __LINE__. A simple ruby script test.rb:

#!/usr/bin/env ruby
warn "I'm in #{__FILE__} on line #{__LINE__}"

will output I'm in ./test.rb on line 2.

Source location

source_location is super useful when you're digging into code of a library or an existing app - it shows where a certain method is defined.

Suppose you have code that creates a ftp connection via Net::FTP.new and logs in using login method.

require 'net/ftp'
ftp = Net::FTP.new("ftp://example.com")

and for some reason or other, you're interested in getting at the sources of the login method.

First, you'll need to get an object representing the method. Calling method on the ftp is the way to go:

m = ftp.method(:login)
=> #<Method: Net::FTP#login>

then, m.source_location will reveal the file and line, where the method is defined:

=> ["/home/bkutil/.rubies/ruby-2.1.0/lib/ruby/2.1.0/net/ftp.rb", 453]

and indeed, there it is:

453 def login(user = "anonymous", passwd = nil, acct = nil)
454   if user == "anonymous" and passwd == nil
455     passwd = "anonymous@"
456   end
567 ...

Similarly, given a class (which is also an object in ruby), one can look up the sources of one of its class methods (aka static methods). Here is an example with Net::HTTP get method:

require 'net/http'
=> ["/home/bkutil/.rubies/ruby-2.1.0/lib/ruby/2.1.0/net/http.rb", 454]

There are three small gotchas:

First, this approach above won't work for instance methods defined in a Ruby module. A module in Ruby cannot be instantiated, so instead of using method, instance_method is needed to get the method object:

require 'forwardable'

=> NameError: undefined method `delegate` for class `Module`

=> ["/home/bkutil/.rubies/ruby-2.1.0/lib/ruby/2.1.0/forwardable.rb", 132]

Second, native methods (those optimized in C for speed) will return nil, for example the empty? check of the String class:

=> nil

And finally, evaled code (this also applies for other *_eval methods you will encounter) won't have its source location defined properly, unless the file and line are explicitly passed as a parameter.

#!/usr/bin/env ruby

eval("class FooPrinter; def test; puts 'foo'; end; end")

x = FooPrinter.new
p x.method(:test).source_location

without extra params outputs

["(eval)", 1]

A simple grep for eval, class_eval or instance_eval might help in this case.


These are just a couple of tricks that I found useful while debugging. Here is cheat sheet in text, html and pdf with the snippets above for printing out or future reference.

Most of these methods are incorporated into advanced REPLs like pry, which also integrates documentation and has a shell-like syntax that is easy to grasp to non-rubyists. I really recommend taking a look at it as well.

Found these tricks useful? Have your own? Or do you have a question? Send me an email (balazs at kutilovi dot cz) or a tweet - I'd love to hear what you think and/or help you out!

P.S: Big thanks to @dmajda and @pepareidinger for proofreading and their insightful comments.

Arduino development with a makefile

Ondras asked me today whether it is necessary to use the Arduino IDE for development. It just happened that I did the googling for the exact same thing a week ago, when I started developing Ardulike and missed the convenience of a real text editor.

Getting everything going is actually quite easy, thanks to the Arduino Makefile project:

  1. The arduino IDE is needed (for avr gcc and possibly other things)
  2. python-serial library is required as well (run apt-get install python-serial on debian)
  3. $ mkdir ~/src/ && git clone git@github.com:sudar/Arduino-Makefile.git ~/src/
  4. Check and modify the arduino makefile example, put the makefile into the same directory as the sources (.cpp, .h files).
  5. Run make to compile, make upload to upload the sketch.

For reference, the Arduino Makefile has a really nice README.

Nrf24 on raspberry pi

NRF24, Raspberry PI & event handling, part 2

As mentioned in a previous post, I added support for callbacks on events triggered by the card, and rewrote the C++ port of the RF24 library into plain C in the process. The library is now on github.

After some discussion with @mvidner, I went the easy way and did not use threads, as only one pin needs to be polled.

The process of getting these 'user space IRQs' working boils down to:

  1. connecting the nRF's pin 8 to a free gpioX pin on the raspberry pi. I used GPIO7 (pin 4 on the BCM). The GPIO pin numbering can be pretty confusing, by the way.

  2. Echoing "falling" into /sys/class/gpio/gpioX/edge

  3. Call poll() on /sys/class/gpio/gpioX/value

The code does this via helpers in gpio.c.

Whenever an IRQ is triggered, the card writes into it's STATUS register info about the event and its origin. The library reads it and updates a radio 'status' struct accordingly. User callback can check this struct and can act based on that, so there's no need to fiddle with the low level stuff. Afterwards, the status is reset.

I still have to get batteries and boxes for all the nodes, but otherwise, it looks like this project is almost finished. The sketch for reporting the node data is here. Together with the libnrf24 library and the picasso framework, they should form a complete solution.

So now onto the Arduino roguelike thing, yay!

Nrf24 on arduino and raspberry pi

NRF24, Raspberry PI & event handling

The problem with the RF24 library ported to the Raspberry PI is that it is not possible to register an event handler to check for the incoming data from the network card. Instead, the library is continuously polling it for new data. This causes the raspi CPU load to go to 100%. So I went googling around for an alternative.

Ported library functions

The arduino version uses the 'native' attachInterrupt. and Maniacbug's version of the RF24 library has an example using it.

For the Raspberry PI, I found two libraries with a similar call - wiringPi's wiringPiISR, arduiPi's attachInterrupt.

Both use pthreads + poll() to watch for POLLPRI events on /sys/class/gpio/gpioX/value after writing "falling/raising/both" into /sys/class/gpio/gpioX/edge.

It'd be nice, though, if the RF24 provided this functionality itself. Then it wouldn't be necessary to link against another lib and/or call system() just to write to the GPIO IRQ pin, especially if the RF24 port already uses (a modified) GPIO lib to do that with the CE and CSN pins.

I decided to add it to the library. Although my C++-fu is close to nonexistent, it should be relatively trivial.

Update (2014-04-04): There is now a port of the nrf library that contains the changes available.

Documents relevant for the NRF24 and raspi

This is just a bunch of links to documents I found useful:

Roguelike for arduino

A guy on the nyx forum was selling an LCD Keypad shield. After playing with the shield for a while, I got this idea:

Arduino roguelike

After I'm done with the wireless sensor network, creating a roguelike for arduino will be my next project :)