DeepTest 2.0 in the works

June 24th, 2009

I’ve started on a significant overhaul of DeepTest which will be released as version 2.0 when it’s finished. I thought I’d share some of my plans for what 2.0 will include and some thoughts about what might come versions after. I don’t have a timetable for yet, but work so far is going fairly quickly.

Plans for DeepTest 2.0

  • A revamped distributed DeepTest architecture that will help ease setup and maintenance.
  • A new console user interface that will provide much more information about what is going on during the test run
  • Much better error handling & reporting (no more “Maybe an error was printed above?”!)
  • RSpec integration that doesn’t break with every new release of rspec.
  • Automatic configuration for Rails projects

What comes after 2.0? The next big feature I’d like to implement is support for cloud testing with deep test on EC2. Other than that, the features coming after 2.0 will likely be driven be requests. Is there a feature you’d like to see in DeepTest? Comment here or message me (qxjit) on github and we’ll get it rolling!

Some time ago Tom, a friend, presented a math programming challenge to a me and a few others. The challenge was to create a function that when given a positive number would return a set of all the sets of positive numbers whose sum was the original number. He wasn’t so much interested in the result itself as he was in what sort of techniques were used in the implementation—memoization of course being a choice candidate for this problem. I was toying a lot with Haskell at the time, and since this was fundamentally a math problem, Haskell seemed well suited to the problem too.

Read the rest of this entry

When Philippe and I worked on SystemTimer together we went back and forth about how much to write in Ruby and how much to write in C. Writing purely at the C level gave us more control over what was happening in the Ruby process as we installed and cleared signal handlers and such, but working in Ruby produced far more readable code.

Read the rest of this entry

The Ruby documentation for the lambda method (a.k.a. proc) says “Equivalent to Proc.new, except the resulting Proc objects check the number of parameters passed when called.” This is almost exactly right. There are, however, at least two cases where this turns out to be false.

Read the rest of this entry

Ruby’s timeout method operates by raising a exception, Timeout::Error. Timeout::Error inherits from Interrupt, SignalException, and finally Exception. In particular, it doesn’t inherit from StandardError, which means it isn’t caught by a default rescue clause with no exception class specified. When I first encountered this, I was annoyed that I had to explicitly catch timeout errors anytime I wanted to recover from errors in general, whether they were timeout errors or not. I realized something the other day that changed my opinion on this however.

Read the rest of this entry

In Ruby every object has an object_id that uniquely identifies that object in that particular instance of the Ruby process. Ruby also treats integers as objects—they are instances of Fixnum. For efficiency reasons, though, Ruby implements integers internally as simple values. That is, it doesn’t allocate heap memory for every integer you use, it just passes the value around instead. So how does Ruby generate object ids for all these integers?

Read the rest of this entry

RubyGems and I had a fight. It was about what version of net-ssh we wanted to have installed on my machine. RubyGems wanted the latest (2.0.2) and I wanted a 1.x version (1.1.4). Apparently net-ssh 2 has an issue with sshing into Fedora Core 4, which I needed it to do. Specifically I needed to use capistrano 1.4.1 to deploy an app to Fedora Core 4

Read the rest of this entry

When we first started trying to use distributed DeepTest, we quickly ran into an issue with DRb servers not binding to the correct addresses. DRb does provide a way to bind to 0.0.0.0 to listen to all addresses, but there’s a downside to the way it does it. The url you provide to DRb to accomplish this must omit the hostname (e.g. druby://:0/). DRb then determines what hostname to report to clients by calling getaddrinfo with the empty hostname. Unfortunately for us getaddrinfo didn’t provide a hostname that could be used by our developer machines to connect to the DeepTest servers. For a brief moment we thought we were stuck.

Read the rest of this entry

  class DearSoul
    def self.new(first, last)
      ObjectSpace.define_finalizer(allocate, proc {|id|
        puts "Goodbye, #{first}.  We'll miss you." 
      })
    end
  end

  DearSoul.new("George", "Carlin")

Here’s a little hack for Ruby classes that comes from a project.


  class Class
    def to_proc
      method(:new).to_proc
    end
  end

If you’ve ever used map (a.k.a. collect) to create a bunch of objects you might be familiar with code that looks something like this.


   value_list.map {|v| Something.new(v)}

With Class#to_proc this can be simplified to


  value_list.map(&Something)

This works very well for map, but I haven’t seen Class#to_proc become useful in any other situation to date. Even changing map to collect changes my opinion of it’s expressiveness. I don’t know that Class#to_proc is pulls its weight in our situation, but I just like the map statement above too much to give it up.

You can do object oriented programming in both Ruby and Javascript. I think most people would agree that Ruby is “more” object oriented than Javascript, whatever subjective judgement they’re using. One thing that’s interesting to me, though, is that Javascript has a syntax for literal objects built in where as Ruby does not.

Read the rest of this entry

mixology is a Ruby extension implemented by some of the Something Nimble collaborators. In short, it allows you to add modules to Objects (much like Ruby’s extend), but in such a way that they can also be removed. Mixology refers to these operations as mixin and unmix. If you want to know more about Mixology and the people behind it, here is a good resource. For the purposes of our discussion, here’s a simple example:


  irb(main):001:0> require 'rubygems'; require 'mixology'
  => true
  irb(main):002:0> module A
  irb(main):003:1> def foo; puts "bar"; end
  irb(main):004:1> end
  => nil
  irb(main):005:0> o = Object.new
  => #<Object:0x4f2b8>
  irb(main):006:0> o.foo
  NoMethodError: undefined method `foo' for #<Object:0x4f2b8>
          from (irb):6
  irb(main):007:0> o.mixin A
  => #<Object:0x4f2b8>
  irb(main):008:0> o.foo
  bar
  => nil
  irb(main):009:0> o.unmix A
  => #<Object:0x4f2b8>
  irb(main):010:0> o.foo
  NoMethodError: undefined method `foo' for #<Object:0x4f2b8>
          from (irb):10

We can see that after o.unmix A the foo method is no longer accessible on the object o. But is there any way we could end up executing the foo method anyhow? It turns out there is. Let’s look at this example:


  irb(main):001:0> require 'rubygems'; require 'mixology'
  => true
  irb(main):002:0> module A
  irb(main):003:1> def foo; puts self.inspect; end
  irb(main):004:1> end
  => nil
  irb(main):005:0> o = Object.new
  => #<Object:0x4d1ac>
  irb(main):006:0> o.mixin A
  => #<Object:0x4d1ac>
  irb(main):007:0> o.foo
  #<Object:0x4d1ac>
  => nil
  irb(main):008:0> foo = o.method(:foo)
  => #<Method: Object(A)#foo>
  irb(main):009:0> o.unmix(A)
  => #<Object:0x4d1ac>
  irb(main):010:0> o.foo
  NoMethodError: undefined method `foo' for #<Object:0x4d1ac>
          from (irb):10
  irb(main):011:0> foo.call
  #<Object:0x4d1ac>
  => nil

In this second example we can see that even though foo can’t be invoked through the object (since module A is no longer mixed in), Ruby has no problem invoking the method using the Method object that was grabbed before unmixing A. So yes, we can access foo if we should absolutely need to. There is one gotcha with this technique, however—even though we are in foo, no other methods from A are available!


  irb(main):001:0> require 'rubygems'; require 'mixology'
  => true
  irb(main):002:0> module A
  irb(main):003:1> def called_as_method_object
  irb(main):004:2> puts "got in, executing method_no_longer_available" 
  irb(main):005:2> method_no_longer_available
  irb(main):006:2> end
  irb(main):007:1> 
  irb(main):008:1* def method_no_longer_available
  irb(main):009:2> raise "Will never make it" 
  irb(main):010:2> end
  irb(main):011:1> end
  => nil
  irb(main):012:0> o = Object.new
  => #<Object:0x366dc>
  irb(main):013:0> o.mixin A
  => #<Object:0x366dc>
  irb(main):014:0> method = o.method(:called_as_method_object)
  => #<Method: Object(A)#called_as_method_object>
  irb(main):015:0> o.unmix A
  => #<Object:0x366dc>
  irb(main):016:0> method.call
  got in, executing method_no_longer_available
  NameError: undefined local variable or method `method_no_longer_available' for #<Object:0x366dc>
          from (irb):5:in `called_as_method_object'
          from (irb):16:in `call'
          from (irb):16
          from :0

The implication of this is significant. If the code in called_as_method_object becomes complicated, you can’t even perform extract method to refactor it! Given that this technique is obscure to begin with and has this major limitation, I recommend you not use it if at all possible. That being said, you may find yourself in a situation where it’s the best option available, at least for the moment. I mean, how else would I come up with this stuff?

Ruby has instance_eval that accepts a block and executes it with self set to the receiver of instance_eval. Ruby also has a method called method that returns a Method object representing a callable method on an object. Method objects, in turn, have a method called to_proc which allows them to be converted to blocks. These are all facts I knew when the day began, but never before had this question occurred to me: what happens when you pass the result of Method#to_proc into instance_eval? What is self? The answer surprised me actually…

Read the rest of this entry

If you’re using prototype.js for Ajax and updating your page with HTML that defines new javascript functions, you’re likely to encounter issues. One solution is to pull the function definitions out of the HTML to a javascript file that is loaded when the page first loads. More often than not this is the correct solution. However, understanding the problem is quite instructive and leads to another solution that can be used in a pinch when pulling the function out is not an option. ...

Read the rest of this entry

ruby-doc.org describes Module.nesting as “the list of Modules nested at the point of call.” What does this really mean? ...

Read the rest of this entry