has_many :codes

A few more methods to format and beautify Ruby objects in console and logs

Published  

This is a sort of quick follow up to the previous post. Since then, I’ve seen a few other tricks that can be used to improve the display of output in a Ruby console, as well as in application logs, to make that information more useful for debugging or, also, for display in a dashboard.

The reason I have been looking for this kind of tricks is that I am now working on a component that should make it easier to investigate problems with applications in a production environment; this component (at a very early stage) works by collecting, parsing and interpreting the information in the application logs in a different way to how this is usually done. One of the goals, however, is also to make it possible to collect as much information as may be required, but without affecting too much the application’s performance.

This is because unfortunately, as I mentioned in the previous post, manipulating what is sent to stdout or to a log file with the purpose of prettifying what gets logged, usually results in some significant performance drawbacks that should seriously be taken into consideration if you wish to prettify logged information in a production environment. We’ll see what sort of performance penalty I am referring to – with a few examples – in the next post, anyways it can still be useful to prettify information that can help with debugging, at least in development. So, here’s a few more ways of formatting Ruby objects in a console and in logs.

Pretty print of JSON

The module JSON, available by requiring the standard library by the same name, exposes a method named pretty_generate that formats any JSON text passed as argument with indentation and new lines, making it easier to read:

ruby-1.9.2-p0 > require "json"
=> true

ruby-1.9.2-p0 > json = { :a => 1, :b => [1,2,3], :c => { :d => "e" } }
=> {:a=>1, :b=>[1, 2, 3], :c=>{:d=>"e"}}

ruby-1.9.2-p0 > puts JSON.pretty_generate json
{
"a": 1,
"b": [
1,
2,
3
],
"c": {
"d": "e"
}
}
=> nil

Pretty print of XML

It’s easy to do something similar with any XML text, by using the nokogiri gem as shown below:

require "nokogiri"

def xp(xml_text)
  xsl =<<XSL
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="/">
  <xsl:copy-of select="."/>
  </xsl:template>
  </xsl:stylesheet>
XSL

  doc = Nokogiri::XML(xml_text)
  xslt = Nokogiri::XSLT(xsl)
  out = xslt.transform(doc)

  puts out.to_xml
end

# then..

ruby-1.9.2-p0 > xp "<a><b>c</b></a>"
<?xml version="1.0" encoding="UTF-8"?>
<a>
<b>c</b>
</a>
=> nil

If you work frequently with JSON and XML, you can also add a couple shortcuts to your ~/.irbrc file:

require "rubygems"
require "json"
require "nokogiri"

def jp(json_text)
  puts JSON.pretty_generate json_text
end

def xp(xml_text)
  xsl =<<XSL
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="/">
  <xsl:copy-of select="."/>
  </xsl:template>
  </xsl:stylesheet>
XSL

  doc = Nokogiri::XML(xml_text)
  xslt = Nokogiri::XSLT(xsl)
  out = xslt.transform(doc)

  puts out.to_xml
end

Then, to use them in any console:

ruby-1.9.2-p0 > jp({ :a => { :b => "c" } })
{
"a": {
"b": "c"
}
}
=> nil

ruby-1.9.2-p0 > xp "<a><b>c</b></a>"
<?xml version="1.0" encoding="UTF-8"?>
<a>
<b>c</b>
</a>
=> nil

Pretty print of records and collections of records

Apart from awesome_print we’ve seen in the previous post, there’s another gem, named hirb, that can be even more effective in some cases, but especially with ActiveRecord objects and collections of objects, in that it displays them in a similar way to how tables and query results are formatted in a MySQL console. The easiest way to use it is as follows:

ruby-1.9.2-p0 > require "hirb"
=> nil

ruby-1.9.2-p0 > Hirb.enable
=> true

ruby-1.9.2-p0 > PageStatus.all
+----+-----------+
| id | name |
+----+-----------+
| 1 | Draft |
| 2 | Published |
| 3 | Scheduled |
| 4 | Deleted |
+----+-----------+
4 rows in set

Hirb allows more than this, so be sure to have a look at the documentation.

© Vito Botta