Thoughtlets, Music, and Code from Noah Thorp

Scruffy Ruby Gem Debugging

Posted: July 16th, by Noah

In the process of creating some graphs in ruby I decided to go upstream from ruport and use the scruffy gem directly. I made some discoveries along the way that touch on issues that could be encountered by various permutations of scruffy, macport, and rubygems users.

A Storm Brewing

The first issue I encountered was this error:
testing_scruffy.rb:2:Warning: require_gem is obsolete.  Use gem instead.
/opt/local/lib/ruby/vendor_ruby/1.8/rubygems.rb:304:in `report_activate_error': Could not find RubyGem Scruffy (>= 0.0.0) (Gem::LoadError)
    from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems.rb:238:in `activate'
    from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems.rb:76:in `active_gem_with_options'
    from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems.rb:61:in `require_gem'
    from testing_scruffy.rb:2

This seems like a straightforward case of not installing the gem. However, in my case the the gem was installed and there was additional strange behavior: require ‘scruffy’ would load the library in irb but not from a script (even with require ‘rubygems’ before it).This seemed inconsistent because $LOAD_PATH (aka $:) variables were identical in irb and in the script. After investigating a number of possibilities I updated rubygems (which was at 0.9.4) to 1.2.0 and this seem to resolve the blatantly bizarre behavior.

You can check which version of ruby gems you are running with “gem -v”. If you are using macports you may have an older version of ruby gems, in which case you may find it useful to update rb-rubygems. Caveat emptor: dependent updates may also be installed – such as ruby. Here’s how you can update your macport rb-rubygems library on OS X:

sudo port upgrade rb-rubygems

Scruffy Needs A Shave

If you do upgrade ruby gems you may run into the another issue. With an updated version of ruby gems the require_gem method is obsolete. Because of this you may see the following error since scruffy 0.2.2 is not updated to use the gem method instead of require_gem:

NoMethodError: undefined method `require_gem' for main:Object
    from /opt/local/lib/ruby/gems/1.8/gems/scruffy-0.2.2/lib/scruffy.rb:18
    from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:32:in `gem_original_require'
    from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:32:in `require'
    from (irb):3

I used the hack below to get around this and to avoid unpacking the gem in to my project directory for modifications. Once again caveat emptor – you may ultimately be better off unpacking (freezing) the gem into a local directory and including it in your application directly. Here’s the hack which simply creates an alias to suspend the deprecation of the require_gem method indefinitely:

require 'rubygems'
alias require_gem gem #later versions of gem use gem instead of require_gem
require 'scruffy'

Case Of The Missing Pie

Ah, but that’s not all. It appears that tutorials and documentation are out of sync with the rubygem download… see example code at http://scruffy.rubyforge.org/ which suggests this usage (with my require hack at the top):

require 'rubygems'
alias require_gem gem
require 'scruffy'

graph = Scruffy::Graph.new
graph.title = "Favourite Snacks" 
graph.renderer = Scruffy::Renderers::Pie.new

graph.add :pie, '', {
      'Apple' => 20,
      'Banana' => 100,
      'Orange' => 70,
      'Taco' => 30
}

graph.render :to => "pie_test.svg" 
graph.render :width => 300, :height => 200, :to => "pie_test.png", :as => 'png'

Running the sample code throws this error:

test_scruffy.rb:7: uninitialized constant Scruffy::Renderers::Pie (NameError)

Well, this error occurs because there is no such class as Scruffy::Renderers::Pie. It’s not in the docs and if you do grep -r “pie” . from within the scruffy-0.2.2 folder it comes up with nothing that would lead to the creation of such a class. FYI, the docs are visible online here http://scruffy.rubyforge.org/doc/

Well, it’s hard to use a class that doesn’t exist. It appears that this may be present in scruffy 0.2.3 released on July 13th – but as of this writing it’s not downloaded via sudo gem update scruffy. If you need this and it it is not yet available through ruby gems – you may need to do a manual install. In the mean time let’s try something else instead.

Steady Into Port (Mind The Wireshark)

graph = Scruffy::Graph.new
graph.title = "Sample Line Graph" 
graph.renderer = Scruffy::Renderers::Standard.new

graph.add :line, 'Example', [20, 100, 70, 30, 106]

graph.render :to => "line_test.svg" 
graph.render  :width => 300, :height => 200, :to => "line_test.png", :as => 'png'

Well if you have RMagick installed that may have worked for you. If not you will need to make sure rmagick is installed. On my machine I had to remove some dependencies before reinstalling tiff with different compilation options. Here are the commands I ran. You will probably have different dependencies, so know what you are doing. Don’t just blindly run these commands or you may uninstall something you need:

sudo port uninstall wireshark
sudo port uninstall gtk2
sudo port uninstall tiff @3.8.2_1+macosx
sudo port install tiff -macosx imagemagick +q8 +gs +wmf
sudo gem install rmagick

Note that installing and compiling rmagick took several minutes. I would suggest looking at the rmagick installation page if you need to install this.

At this point you should be able to output your svg and png files.

Conclusion

Careful, or due to “environmental conditions” you could set out expecting a simple three hour tour happily outputting beautifully rendered svgs as you sail effortlessly through graph land; but instead, end up whistling along sympathetically to the Gilligan’s Island theme song as you set ground on the shore of an uncharted desert isle. Hopefully this will help you through some of the things you may run into, and you can have a smooth sail enjoying scruffy.

Proc.new, lambda, and proc

Posted: June 18th, by Noah

In response to the harmony of thought posting on good ruby interview questions I wrote the following (posted here for interest and to preserve formatting)...

One thing about lambdas and procs. Even though they appear to be the same class they do not behave completely the same. From running my_lambda.inspect and seeing the Proc instance you would never guess it but they are different.

Essentially lambda and Proc.new handle arguments and the “return” statement differently. Also the “proc” method returns a lambda not a Proc.

Here’s some code to prove the point. The argument handling is the easiest to demo:

my_proc = Proc.new {|x,y| print x,y}
my_lambda = lambda {|x,y| print x,y}
my_other_proc = proc {|x,y| print x,y}

# pass in one variable instead of 2
my_proc.call(1) #this doesn't throw an error and sets y to nil
my_lambda.call(1) #this throws an error
my_other_proc.call(1) #this throws an error like a lambda because it actually is a lambda not a proc in ruby 1.8.6

Also in Ruby 1.9 I think that the “proc” method (as seen in line three) will actually return a Proc and not a lambda. Ruby 1.9 will also add a “lambda?” method for you to clarify the difference between a Proc and a lambda.

O’Reilly’s book “The Ruby Programming Language” by Matz (Yukihiro Matsumoto) and David Flanagen has a great chapter on this.

Directed Graphs in Rails (Self Refering Many-To-Many Joins)

Posted: October 22nd, by Noah

Here is a simple example of a complex subject. An uncluttered implementation of a directed graph implemented in Rails (adaptable to other Ruby ActiveRecord projects).

Let the directed graph consist of nodes and links. Links join nodes together and are directed from a node to another node. Links also have a value associated with them.

I should mention that in standard digraph terminology nodes are called vertices, and edges are called links. I chose the terms nodes and links as I think it makes for easier reading.

Build The Model

Create the tables like this:
$ script/generate model node name:string
$ script/generate model link from_id:integer to_id:integer value:integer
$ rake db:migrate

The migration table definitions should look like this (surrounded by the usual migration code):

create_table :nodes do |t|
    t.column :name, :string
end

create_table :links do |t|
    t.column :from_id, :integer
    t.column :to_id, :integer
    t.column :value, :integer
end

Create the Node and Link models like this:

class Link < ActiveRecord::Base
    belongs_to :from_node, :foreign_key => "from_id", :class_name => "Node" 
    belongs_to :to_node, :foreign_key => "to_id",   :class_name => "Node" 
end

class Node < ActiveRecord::Base
    has_many :to_links, :foreign_key => 'from_id', :class_name => 'Link' #tricky!
    has_many :to_nodes, :through => :to_links  

    has_many :from_links, :foreign_key => 'to_id', :class_name => 'Link' #tricky!
    has_many :from_nodes, :through => :from_links
end

What’s Going On In The Model?

Did you see the lines labeled “tricky!” in the Node model. Why does has_many :to_links reference :foreign_key => “from_id”? Well, lets check it out.

Here is a diagram I created to explain directed relationships from one node to another node and how they are defined in the model. (Whispered aside: if you are feeling frisky and you want to compute the nodes that go to a given node rather than from it, you will have to traverse the diagram in reverse.)

Essentially we traverse in this order:

  1. From the :from_node via the from_id to the :to_link
  2. From the :to_link via the to_id to the :to_node

Here’s the corresponding code from the Node model that makes this hapen.

1) Traverse from the :from_node via the from_id to the :to_link
has_many :to_links, :foreign_key => 'from_id', :class_name => 'Link' 

2) Traverse :to_link via the to_id to the :to_node

has_many :to_nodes, :through => :to_links
“Where are the :from_node and :to_node terms defined?” you may ask. They are defined in the Link model along with the belongs_to statements.
belongs_to :from_node, :foreign_key => "from_id", :class_name => "Node" 
belongs_to :to_node, :foreign_key => "to_id",   :class_name => "Node"

SQL Nitty Gritty

Lets disect what all of this means in terms of SQL. If you are ready to get right to it, you can skip this section and go straight to playing with the model.

In SQL selecting nodes linked from node “a” to node “b” would look something like the following. Notice that I alias the node table as both from_node and to_node (the node table plays two roles).
SELECT to_nodes.name 
FROM nodes from_nodes, nodes to_nodes, links
WHERE from_nodes.id = links.from_id
AND to_nodes.id = links.to_id
AND from_nodes.name = 'a'
AND to_nodes.name = 'b'
Looking at our diagram we see this bit of code from the Node model which defines the relationship from a Node to a Link:
has_many :to_links, :foreign_key => 'from_id', :class_name => 'Link' 
This corresponds to this sql statment:
WHERE from_nodes.id = links.from_id
Looking at our diagram once again we see this bit of code from the Node model which defines the relationship between from a Link to a Node:
has_many :to_nodes, :through => :to_links
This corresponds to this sql statement:
AND to_nodes.id = links.to_id

One last note about the naming of the model. Although the symbols do represent an non-arbitrary relationship, the names for :from_nodes, :to_nodes, :from_links, and :to_links are arbitrary. I have selected a naming scheme that I believe reveals the structure of the relationships, but if you find something more suitable to your tastes ActiveRecord won’t complain.

Playing With The Model

Now that you have grokked that, lets try out the model. Here’s the diagram of the digraph that we are about to create:

Open up your rails app console:
$ script/console
Create some nodes and connect them with links:
a = Node.create(:name => "a")
b = Node.create(:name => "b")
c = Node.create(:name => "c")
d = Node.create(:name => "d")
Link.create(:from_node => a, :to_node => b, :value=>7)
Link.create(:from_node => b, :to_node => c, :value=>14)
Link.create(:from_node => c, :to_node => d, :value=>21)
Link.create(:from_node => b, :to_node => d, :value=>28)
Link.create(:from_node => d, :to_node => a, :value=>35)

Now run some queries.

a links to b:
a.to_nodes[0].name # returns: b
a.to_nodes.first.name #an alternate, also returns b
b links to c and d:
b.to_nodes[0].name #returns c
b.to_nodes[1].name #returns d
b.to_nodes.each {|node| puts node.name} # returns: c, d
There is a link to a from d:
a.from_nodes[0].name # returns: d
One way to retrieve a node two links away:
a.to_nodes[0].to_nodes[0].name #returns c
Get the value associated with a link between two nodes:
a.to_links[0].value #returns 7

There you go. Now you know how to make directed graphs in Ruby on Rails. Go forth and digraphify.

One final note, this posting was inspired by Josh Susser’s post on the same topic. He has some other great topics on “has_many :through” relationships – in fact that’s even what his blog is called. I recommend reading his posts if this type of model manipulation strikes your fancy.