30 Days of Tech: Day 29 - C, Ruby, & Threads, Oh My!
June 29th, 2008
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 entry30 Days of Tech: Day 28 - lambda args
June 28th, 2008
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.
30 Days of Tech: Day 27 - Short Circuited Timeout
June 27th, 2008
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.
30 Days of Tech: Day 26 - Fixnum#object_id
June 26th, 2008
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?
30 Days of Tech: Day 25 - Gem dependency version
June 25th, 2008
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
30 Days of Tech: Day 24 - drubyall
June 24th, 2008
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.
30 Days of Tech: Day 23 - DearSoul
June 23rd, 2008
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")
30 Days of Tech: Day 22 - Class#to_proc
June 22nd, 2008
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.
30 Days of Tech: Day 21 - Object Literals
June 21st, 2008
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 entry30 Days of Tech: Day 20 - Unmixed Methods
June 20th, 2008
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?
30 Days of Tech: Day 19 - instance_eval & Method#to_proc
June 19th, 2008
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…
30 Days of Tech: Day 18 - Ajax Defined JS
June 18th, 2008
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 entry30 Days of Tech: Day 17 - Nesting
June 17th, 2008
ruby-doc.org describes Module.nesting as “the list of Modules nested at the point of call.” What does this really mean? ...
30 Days of Tech: Day 16 - Line Animation
June 16th, 2008
Here’s a little something pulled out of one of my personal projects. It’s a class to help with single line animations on the command line. You construct it with an output device (something supporting <<, like STDOUT) and a list of objects (components). When you tell it to draw, it blanks out the current line and then draws it by converting the list of components to a string and writing it to the display. ...
Read the rest of this entry30 Days of Tech: Day 15 - Git Uncommit
June 15th, 2008
One nice feature of git’s distributed nature is that if you haven’t pushed a commit to another repository, you can actually undo the commit, erasing it from git’s history. This is nice if you screwed up a commit and want to redo it before sharing it with the world. It’s simple to do too. The command line excerpt below demonstrates initializing a new repository, adding a file, editing it, undoing a commit, fixing a typo, and recommitting it…
Read the rest of this entry30 Days of Tech: Day 14 - Minlength Enum
June 14th, 2008
Here’s a hack I cooked up some time ago for situations where you want an enumerable with a minimum length. It decorates an existing enum instance (an object supporting the each method) to contain a minimum number of objects, returning a “filler” object if the end of the wrapped enum is reached before hitting the minimum length. It’s probably easier understood through a simple code example.
MinLengthEnum.new(4,[1,2],"filler").to_a #=> [1, 2, "filler", "filler"]
And then the implementation, which is quite simple
class MinLengthEnum
include Enumerable
def initialize(length,enum,filler = nil)
@length = length
@enum = enum
@filler = filler
end
def each
filler = [@filler] * @length
@enum.each {|o| yield o; filler.shift}
filler.each {|o| yield o}
end
end
There you have it. Nothing special, but something. Have a great day!
30 Days of Tech: Day 13 - Self Eval
June 13th, 2008
Ruby provides a method, eval that accepts a string and evaluates it as Ruby code, returning the result. Since all Ruby code is evaluated in the context of an object, what is self for eval? ...
30 Days of Tech: Day 12 - Class Vars
June 12th, 2008
Ruby has class variables, which are somewhat similar to static members of classes in Java. They can be used to conveniently share references between class methods and instance methods on classes. Ruby’s class variables have some very surprising behavior at times, however. I’ll illustrate just two cases here.
Order of Initialization
Suppose we have a class and a subclass that use a class variable of the same name? Is there one variable or two? Well, that all depends on the order in which they are initialized. Suppose the classes are defined as such.
class Superclass
def self.superclass_value=(v)
@@shared_class_var = v
end
def self.superclass_value
@@shared_class_var
end
end
class Subclass < Superclass
def self.subclass_value=(v)
@@shared_class_var = v
end
def self.subclass_value
@@shared_class_var
end
end
If you set the value through the superclass first, all behaves as you might expect:
def test_setting_in_superclass_first
Superclass.superclass_value = 1
Subclass.subclass_value = 2
assert_equal 2, Superclass.superclass_value
assert_equal 2, Subclass.subclass_value
end
However, if you set the value through the subclass first, you end up with two separate variables!
def test_setting_in_subclass_first
Subclass.subclass_value = 2
Superclass.superclass_value = 1
assert_equal 1, Superclass.superclass_value
assert_equal 2, Subclass.subclass_value
end
Note that if you want to run these two tests in the same Ruby instance, you’ll need to do some setup since both tests use the same variable name.
def setup
Superclass.send(:remove_class_variable,"@@shared_class_var") if Superclass.class_variables.member?("@@shared_class_var")
Subclass.send(:remove_class_variable,"@@shared_class_var") if Subclass.class_variables.member?("@@shared_class_var")
end
When I first learned that class variables depended on the order initialization in this way, it was enough to make me never want to use them. I did, however, want to know more about how they worked. In that exploration, I found out another oddity.
Lookup Context
Class variables also behave somewhat strangley with respect to how they are looked up with some eval contexts. For instance, if you access a class variable from within a class_eval block, you would naturally expect class variable references to be looked up within the target class. Instead they’re looked up in the context of the caller.
def test_variable_lookup_in_class_eval_block_uses_calling_context
@@shared_class_var, Superclass.superclass_value = 9,3
assert_equal 9, Superclass.class_eval {@@shared_class_var}
end
On the other hand, if you pass class_eval a string instead of a block, you get the opposite behavior!
def test_variable_lookup_in_class_eval_string_uses_target_context
@@shared_class_var, Superclass.superclass_value = 9,3
assert_equal 3, Superclass.class_eval("@@shared_class_var")
end
I haven’t verified this, but my belief is that this difference is because by the time Ruby parses the code passed to class_eval in the second example the context has already changed to Superclass, while Ruby parses the block in the first example in the context of the test class. Ok, so we’ll cut Ruby a break since it’s all dynamic and doesn’t have all the information when it parses. Then what about instance_eval? Let’s try it with a block first.
def test_variable_lookup_in_instance_eval_block_uses_calling_context
@@shared_class_var, Superclass.superclass_value = 9,3
assert_equal 9, Superclass.new.instance_eval {@@shared_class_var}
end
So far so good—the rules are consistent. Ruby parsed the block and is resolving the reference to the test class’s @@shared_class_var. Unfortunately, passing a string to instance_eval is not so nice…
def test_variable_lookup_in_instance_eval_string_uses_calling_context
@@shared_class_var, Superclass.superclass_value = 9,3
assert_equal 9, Superclass.new.instance_eval("@@shared_class_var")
end
I can’t come up with an explanation for this case. How the variable referenced in the String is resolved to find the class variable from the test rather than the class of the instance where the eval is done is a mystery to me. Perhaps one day I’ll dive into the C code and figure it out, but for now I’m content to simply avoid using class variables if at all possible. They are certainly convenient at times, but not worth the cost to me.
30 Days of Tech: Day 11 - Method Sorta Missing
June 11th, 2008
Method missing magic can often be a code smell leading you to question your design. Sometimes, however, it can be a boon. For those of us who have trouble spelling or remembering the exact names of methods, we can make method missing help with method lookup. Since we’re good TDDers, we’ll start with some tests specifying the behavior we want …
Read the rest of this entry30 Days of Tech: Day 10 - Super Stub!
June 10th, 2008
If you’re a Rubyist, doing TDD, and using mocks and stubs of any sort you may have encountered difficulties with mocking or stubbing super calls in subclasses. The reason is simple: super isn’t a method, so you can’t mock it with a method mocking framework. There are a number of ways to get around this problem—I’ll discuss four possible techniques below with short discussion of potential strengths and weaknesses …
Read the rest of this entry30 Days of Tech: Day 9 - MacBrick
June 9th, 2008
Some colleagues on my current project got together tonight to do some Rubinius hacking. Pat organized the event as a way to jump start us with the goal of getting Rubinius working on everybody’s laptop and start digging into the code, possibly producing a couple of patches. I was pretty gung-ho about it until about 30 minutes in when my MacBook turned into a MacBrick. Here was the sequence of events:
- Clone the Rubinius get repository
- rake build #=> get error message complaining about libgcc_s.1.dylib not being found
- copy libgcc_s.1.dylin found in /Developer to /usr/lib
- try to rake build again #=> get error message complaining about loading said library
- try to rm /usr/lib/libgcc_s.1.dylib #=> get error message complaining about loading said library
- try to delete /usr/lib/libgcc_s.1.dylib through finder #=> see finder take a very long time trying to delete the file
- try to shutdown system through menu #=> see finder refuse to shutdown because it is deleting a file
- power down system by holding the power button #=> see screen go black
- try to power system on #=> get macintosh grey screen of death
At this point I wasn’t sure what to do, but fortunately I had some people around with some suggestions. Holding Command-S (to boot to single user mode) while attempting to boot at least showed the output of the kernel booting up, the interesting parts of which are
pid 1 exited (signal 0, exit 1)panic(cpu 1 caller 0x00338986): init died
...
Debugger called: <panic>
...
No mapping exists for frame pointer
Backtrace terminated-invalid frame pointer 0xbffff968
Other magical boot options didn’t help the situation at all. The only promising option was holding T and booting, which booted the MacBrick into target mode. After making a trip to best buy to pick up a firewire cable, we were able to hook the brick up to another Mac and look at the drive. We tried various combinations of removing the offending library, removing the file of the same name from the .Trashes directory and doing a repair from withing Disk Utility. None of these had any substantial effect.
I’ve learned a lot about troubleshooting Macs tonight—various boot options and using target mode to get at the disk of a borked machine. So far it has all been to no avail. My MacBook remains a brick at this point (thanks Pat for letting me write my post from your machine). I suspect that shutting the machine down during the delete is the culprit, which is corroborated by some google searching. I strongly advise that you avoid doing so if at all possible. Next stop for me? The Apple store.
30 Days of Tech: Day 8 - Cron Woes
June 8th, 2008
Yesterday I wrote about a Ruby script I set up to be run by cron that would make sure pages cached by Mephisto were cleared for future-dated articles that I publish. After I wrote the script and added the cron entries for it…
Read the rest of this entry30 Days of Tech: Day 7 - Mephisto Hacking
June 7th, 2008
f you were paying close attention, you may have thought I missed a day on Thursday with the 30 days of tech. It turns out that you would be both right and wrong. I wrote the post on Wednesday night and asked Mephisto to publish in on Thursday since I generally go straight from work to the airport on Thursdays. Only when I went to write my post for Friday did I realize that the old index page was still cached, so the post never showed up. Today I endeavored to find a solution to that problem. This solution is a total hack, and for all I know the latest version of Mephisto has a standard way to do this.
Read the rest of this entry30 Days of Tech: Day 6 - Overloading
June 6th, 2008
One thing new Ruby users are sometimes surprised by is Ruby’s lack of overloaded methods. Once you get used to duck typing you quickly realize why this is a strength for Ruby rather than a weakness. Nonetheless I have often wondered what it would look like to implement something resembling method overloading in Ruby. To find out, I put together the hack below allowing overloaded methods to be defined on a class. It allows for adding of new overloaded definitions in a single class, but currently doesn’t have very good behavior when dealing with subclasses or modules. To reiterate, I don’t think this is a good idea, something Ruby should support, or that you should actually use the code below. I hope you find it interesting though.
the spec:
require 'method_overloading'
describe "Method overloading" do
it "should allow methods to be invoked" do
klass = Class.new do
overloading :my_method do
_(Fixnum) {|n| n*2}
end
end
klass.new.my_method(3).should == 6
end
it "should maintain receiver as self within method block" do
klass = Class.new do
overloading :my_method do
_(Object) {|n| self}
end
end
instance = klass.new
instance.my_method(3).should equal(instance)
end
it "should raise error if no matching implementation can be found" do
klass = Class.new do
overloading :my_method do
_(Fixnum) {|n| n}
end
end
lambda {
klass.new.my_method("String")
}.should raise_error(NoMethodError, "No implementation found for my_method(String)")
end
it "should invoke different implementations based on argument type" do
klass = Class.new do
overloading :my_method do
_(Fixnum) {|n| n*2}
_(String) {|s| s.upcase}
end
end
klass.new.my_method(3).should == 6
klass.new.my_method("A String").should == "A STRING"
end
it "should invoke superclass implementations for arguments in type of subclass" do
klass = Class.new do
overloading :my_method do
_(Numeric) {|n| n * 2}
end
end
klass.new.my_method(3).should == 6
klass.new.my_method(3.0).should == 6.0
end
it "should invoke implementation that most closely matches argument type" do
klass = Class.new do
overloading :my_method do
_(Numeric) {|n| n * 2}
_(Integer) {|n| n * 3}
_(Object) {|n| n * 4}
end
end
klass.new.my_method(3).should == 9
end
it "should allow reopening to change a single overloaded method" do
klass = Class.new do
overloading :my_method do
_(String) {|n| "original string implementation"}
_(Fixnum) {|n| "original fixnum implementation"}
end
end
klass.class_eval do
overloading :my_method do
_(String) {|n| "new string implementation"}
end
end
klass.new.my_method("a").should == "new string implementation"
klass.new.my_method(1).should == "original fixnum implementation"
end
it "should allow multiple methods to be overloaded with separate implementations" do
klass = Class.new do
overloading :method_1 do
_(String) {|n| "method_1 string implementation"}
end
overloading :method_2 do
_(String) {|n| "method_2 string implementation"}
end
end
klass.new.method_1("a").should == "method_1 string implementation"
klass.new.method_2("a").should == "method_2 string implementation"
end
end
the implementation:
class Class
def overloading_definition_context(method_name)
@definition_contexts ||= {}
@definition_contexts[method_name] ||= OverloadingDefinitionContext.new(self, method_name)
end
def overloading(method_name, &block)
overloading_definition_context(method_name).instance_eval &block
define_method(method_name) do |arg|
send(self.class.overloading_definition_context(method_name)[arg.class],
arg)
end
end
class OverloadingDefinitionContext
attr_accessor :implementation_block
def initialize(klass, method_name)
@klass = klass
@method_name = method_name
@implementations = {}
end
def _(arg_type, &block)
method_name = "__#{@method_name}_#{arg_type.object_id.abs}"
@klass.send(:define_method, method_name, &block)
@implementations[arg_type] = method_name
end
def [](target_arg_type)
@implementations[implementation_arg_type(target_arg_type)]
end
def implementation_arg_type(target_arg_type)
possible_arg_types = @implementations.keys.select do |arg_type|
target_arg_type <= arg_type
end
if possible_arg_types.empty?
raise NoMethodError.new("No implementation found for #{@method_name}(#{target_arg_type})")
end
possible_arg_types.sort.first
end
end
end
30 Days of Tech: Day 5 - The UnModule
June 5th, 2008
There are many ways to change the behavior of an existing class in Ruby. Every so often you run into a new set of constraints that lead to to a way of doing it that you might normally reject, but is surprisingly sound in context. Here is an example that a couple of colleague’s encountered today and I had the pleasure of talking through with them.
Suppose we’re working on a Rails application with a service like the one below:
module AirspeedService
def self.get_velocity(bird_description)
return 24
end
end
Now let’s suppose that in the development environment we want to be able to simulate an error by providing a certain agreed upon input, but otherwise have the same behavior as the normal production service. One way to skin that cat is to simply use a Rails style stub to reopen the class and add the behavior we want, making sure the stub is required in the development environment. In this solution the stub would look something like this:
module AirspeedService
class <<self
alias_method :original_get_velocity, :get_velocity
end
def self.get_velocity(bird_description)
if key == "unladen swallow"
raise "What do you mean? An African or European swallow?"
end
original_get_velocity(bird_description)
end
end
This is a fine solution, provided we don’t care about testing our stub. If we want to make sure our stub works as we expect, it will have to be loaded in the test environment. This will allow us to test the behavior that the stub adds to the service, but there is a cost. Now the tests written for the unmodified AirspeedService are calling a modified version, running the risk that we are not testing the production code. It avoid this problem we need to extract the stub behavior to a separate module and then inject that behavior into the service only in the environment where it is desired. We can change our stub to look like this:
module AirspeedServiceStubs
def self.extended(mod)
mod.module_eval do
class <<self
alias_method :original_get_velocity, :get_velocity
remove_method :get_velocity
end
end
end
def get_velocity(bird_description)
if key == "unladen swallow"
raise "What do you mean? An African or European swallow?"
end
original_get_velocity(bird_description)
end
end
and then add a line like this to development.rb:
AirspeedService.extend(AirspeedServiceStubs)
This approach gives us the ability to test AirspeedServiceStubs and AirspeedService separately—a big win. We have, however, sacrificed readability and intentionality. In order for the stubbed version of the method to be called we must now use remove_method to move the original one out of the way (since the module’s methods effectively superclass methods to those in AirspeedService). Furthermore we had to use the extended hook to do the method aliasing, which is more difficult to read and understand than simply reopening the same class. We can, however, simplify our code somewhat while still using a module:
module AirspeedServiceStubs
def self.extend_object(mod)
mod.module_eval do
class <<self
alias_method :original_get_velocity, :get_velocity
end
def self.get_velocity(bird_description)
if key == "unladen swallow"
raise "What do you mean? An African or European swallow?"
end
original_get_velocity(bird_description)
end
end
end
end
By moving the definition of the stubbed get_velocity method inside the module_eval, we’ve largely regained the readability of the original implementation. The method aliasing code and new definition of get_velocity are closer to one another, meaning you can concentrate on the implementation without having to process the noise surrounding it (contrast this with the previous approach, where the get_velocity definition and method aliasing were occurring in two different scopes). This implementation also uses extend_object instead of extended. extend_object is the method Ruby invokes on a module to have it add behavior to a object instance. Normally it simply includes the module into the metaclass of the object being extended and then calls the extended hook we used in the previous example. Since AirspeedServiceStubs no longer behaves very much like a module, I’ve changed it to take over the extend_object process completely and do its work. Note that super is never called from extend_object, so if you were to add an instance method to the module it would never get added to AirspeedService.
There’s one more change I would consider making in this case. Changing the extend line in development.rb from
AirspeedService.extend(AirspeedServiceStubs)
to something like
AirspeedServiceStubs.add_stub_behaviour(AirspeedService)
might convey more intent to the reader. Rather than tricking the reader into thinking that AirspeedServiceStubs is a module that simply adds methods to the service, using a custom method name calls out that something different is happening that might be worthy of further investigation. The implementation of this is simple, since we have already taken over the job of adding the stub behaviour ourself. Here it is, with the inner code omitted for brevity this time:
module AirspeedServiceStubs
def self.add_stub_behaviour(mod)
mod.module_eval do
...
end
end
end
I like this solution for its readability and what it communicates to someone reading the code for the first time. It’s worth noting that we’ve made a tradeoff with the very last change we made, however. Since our stub code previously looked like a normal Ruby module (i.e. it was added using the extend method), we were free to refactor the innards without worrying about how it was called. We’ve now sacrificed that flexibility in favor of communicating more to the first time reader. Personally, I like this trade-off. There are sure to be situations where it doesn’t make sense though, so it’s a good idea to stop and think about which way is better for any particular case.
In the end we’ve added only a small bit a complexity to get a lot more control over where the stub code loaded and where it actually stubs the behavior of the original service. We can now test the stub and the service completely independently and still apply the stub to the service in a specific environment. I think that’s a good thing.
30 Days of Tech: Day 4 - monkey_patch.js
June 4th, 2008
Yesterday I posted a fix for prototype.js that ensures that the Ajax active request count remains correct even if an application provided hook causes an exception. In the fix I showed a snippet of code from respondToReadyStateChange function of prototype.js along with the snippet’s replacement that corrects the problem. The easiest way to get this change applied in your application would be to simply change prototype.js in place and forget about, but is this really a good idea?
What if you want to upgrade prototype? You could accidentally wipe out this fix, which you may or may not have written a test for (depending on how diligently you test your monkey patching). Even if you remember that you have changes you’ve made to prototype, how do you track them down so you can check whether they are still needed or if they are compatible with the new version? You could use comments around each change, but these comments can quickly become out of date and you’re likely to forget to comment at least one change somewhere.
Fortunately, there is a better answer. Monkey patching in Javascript can be done in a fashion quite similar to Ruby. Since objects in Javascript are simply hashes of functions and variables, all objects (including prototypes used to create new objects) can be changed at anytime. Using this feature you can pull your monkey patch changes out to a separate file. As long as the monkey patch file is included in the HTML page after the code it is patching, you’ll have no problem changing the functionality of the library. Here’s an example:
in app.html:
<html>
<head>
<script type="text/javascript" src="library.js"></script>
<script type="text/javascript" src="library_monkeypatches.js"></script>
</head>
<body>
<a href="#" onclick="new UsefulObject().solveMyProblem();">Solve My Problem</a>
</body>
</html>
in library.js:
UsefulObject = function() {};
UsefulObject.prototype = {
solveMyProblem : function() {
alert("There is no problem.");
}
};
in library_monkeypatches.js:
UsefulObject.prototype.originalSolveMyProbem = UsefulObject.prototype.solveMyProblem;
UsefulObject.prototype.solveMyProblem = function() {
alert("Help me with my problem!");
this.originalSolveMyProbem();
alert("Phew... I feel better now.");
};
Here library_monkeypatches.js copies the original solveMyProblem function to a new name on the same class, then redefines solveMyProblem with some additional behavior, including a call to the original function. If you’re used to Ruby metaprogramming, here’s what it would like in Ruby:
class UsefulObject # re-opening UsefulObject
alias_method :original_solve_my_problem, :solve_my_problem
def solve_my_problem
puts "Help my with my problem!"
original_solve_my_problem
puts "Phew... I feel better now"
end
end
Because Javascript gives us some metaprogramming capabilities similar to Ruby, it’s not surprising that a solution we apply in Ruby (pulling out our monkey patches to a separate file) applies equally well to Javascript. Using this technique makes it completely transparent what changes the developers have added to the library. When you upgrade all you need to do is go to the monkeypatches file and verify that all the patches still make sense and work as expected. Much less painful than hunting through the library code discerning what changes were applied!
30 Days of Tech: Day 3 - WaitForAjax
June 3rd, 2008
Here’s a quick one that came out of writing Selenium tests for an application with a fair amount of Ajax calls. Selenium provides a waitForPageToLoad command that does exactly what it says. It’s typically used after an action (such as clicking a link) would cause a page refresh and you don’t want to continue your test until the page is finished loading (which is most of the time).
Unfortunately, waitForPageToLoad is not so useful clicking a link that causes an Ajax request to happen. Since there is no new page loading, waitForPageToLoad doesn’t make any sense. Selenium provides a host of other waitFor commands to wait for such things as elements appearing on the page or form values to change. These waitFor commands can be used to wait until an Ajax request finishes as long as it the request affects the page in a way that can be detected. For example, if the request adds a div whose id is “new_div” to the page, you can use waitForElementPresent(‘new_div’) to have the test wait until “new_div” present, ensuring that the Ajax request has finished.
Unfortunately, this approach turns out to be error prone and brittle. For instance, if the Ajax request doesn’t change the page in the manner the test is expecting (say the you changed the div’s id to “brand_spanking_new_div”), the test must wait for the entire length of the timeout to fail. If only you could simply wait for the Ajax request to finish just like waitForPageToLoad instead of waiting on side effects of the Ajax call.
If you’re using the prototype.js library for Ajax’s requests, this is actually fairly easy. There are two key components. The first is Selenium’s waitForCondition command, which repeatedly executes a snippet of javascript, waiting for it to produce a true value. The second is prototype’s Ajax.activeRequestCount, which indicates the number of pending Ajax requests on the page. By the power of these two tools combined, your tests can wait for the Ajax request to finish nicely and then make assertions about the state of the page following the call. It looks something like this (if you’re using Selenium RC in Ruby):
selenium.open "/page_with_an_ajax_link"
selenium.click "link_that_triggers_ajax"
selenium.wait_for_condition "selenium.browserbot.getCurrentWindow().Ajax.activeRequestCount == 0", 10000
assert selenium.is_element_present("new_div"), "new_div was not present"
In practice this works amazingly well. Writing tests around Ajax goes much faster since you don’t have to divine what the proper page change to wait for is. Furthermore, the technique naturally works for multiple Ajax requests triggered from a single action. And finally it puts your test assertions where they should be—as assertions rather than flow control waiting for the application. I highly recommend the approach.
There is one caveat, however. At least in prototype 1.5.0 (I haven’t checked other versions), if your application specifies a state change hook (like onComplete) for an Ajax request and that hook causes an exception, prototype never decrements the activeRequestCount even though the request is done. In prototype.js, in the respondToReadyStateChange function, you can change this:
try {
(this.options['on' + state] || Prototype.emptyFunction)(transport, json);
Ajax.Responders.dispatch('on' + state, this, transport, json);
} catch (e) {
this.dispatchException(e);
}
to this:
try {
(this.options['on' + state] || Prototype.emptyFunction)(transport, json);
} catch (e) {
this.dispatchException(e);
} finally {
Ajax.Responders.dispatch('on' + state, this, transport, json);
}
to fix the problem. In 1.5.0 the change is on line 942.
There you have it. A simple recipe to make your tests wait for Ajax requests to finish. I wouldn’t be surprised if a similar technique is applicable when you’re using a javascript library other than prototype. If you implement one, share it with the world!
30 Days of Tech: Day 2 - DeepTest
June 2nd, 2008
Zak Tamsen and Dan Manges gave a wonderful talk about the testing practices developed on projects we’ve been on. One of the themes throughout the presentation was the speed with which your tests should provide you with feedback. They mentioned DeepTest when talking about functional tests, which is a gem that will run your Test::Unit tests or RSpec examples in parallel. It will even distribute your tests to multiple machines so that you can speed up your test runs by adding more hardware.
I authored (with Zak’s and Dan’s support) an article for Something Nimble, which you can read here. It covers the ways DeepTest has grown since the first article that Zak and Dan wrote, which you might also find useful. DeepTest is still in it’s formative years and we’re always looking for suggestions and help for taking it to the next level. If you use it let us know what you wish it did better, and if you extend we welcome your contributions to the project. I hope working with DeepTest brings you as much enjoyment and I’ve gotten from working on it.
30 Days of Tech: Day 1 - SystemTimer
June 1st, 2008
Since this is the first 30 Days of Tech post, I’ll give you just a bit of background. If you read my earlier posts, it should be obvious that this commitment to 30 Days of Tech is an extension of the “30 Days of Gratitude” than Annie embarked on. Participating in her experiment by trying to post a grateful comment to her blog every day in response to her grateful post had some real, tangible benefits for me. If I’m lucky, similar benefits will come on the technical side by committing to tech posting. So, without any further ado, on with the tech! Since I’m traveling today, we’ll start with something that is pretty easy for me to post.
Philippe Hanrigou mentioned SystemTimer yesterday during his Mongrel talk as a potential solution to what he referred to as the second most common scenario in which Mongrel is hung. Philippe has a great post on the issue and using SystemTimer here, so I’ll just give you a bit of my perspective.
So what’s the problem? On a client project we ran into a situation in production where Mongrel would hang forever waiting for a webservice call to an external system to finish. This was particular frustrating since we had planned for this situation by setting timeouts and implementing fallback strategies for when the webservice failed. Unfortunately for us, the external system was unreliable enough that this had a significant impact.
When we investigated why the timeout and fallback were not happening, we discovered a disconcerting interaction between the os native threads, ruby green threads, and blocking system calls. Ruby’s timeout.rb is implemented using green threads. Basically it starts a homicidal thread charged with taking a nap, and then waking up and killing the working thread. If the working thread can finish it’s work and kill the homicidal thread in it’s sleep, everything is copasetic. If the homicidal wakes up and kills the working thread (by raising an exception), the work is effectively aborted. (Props to Patrick for sharing the homicidal thread metaphor).
When a blocking system call enters the picture, we have a problem. Ruby’s green threads can never be scheduled to run unless the Ruby interpreter’s native thread is scheduled to run by the OS. The OS assumes that as long as Ruby is waiting on a blocking system call, there is no reason to schedule the Ruby native thread—it has no idea that green threads even exist. So if the working thread makes a blocking system call while the homicidal thread is sleeping, the entire Ruby process will be put to sleep by the OS. Since the homicidal thread cannot wake up without OS scheduling the Ruby process, there is no way for it to kill the working thread. In a typical Rails setup, this can add up to very sleepy Mongrels that simply can’t wake up to handle another request… poor Mongrels ;(
Clearly Ruby’s timeout facility was not sufficient to timeout our webservice calls. Philippe and I worked to together to implement a solution based on Kurtis Seebaldt’s original idea. We created SystemTimer, which is a gem with a C extension to Ruby that uses OS level signals to implement the timeout rather than Ruby’s green threads. The homicidal killer metaphor still applies, but instead of launching a green thread SystemTimer asks the OS to deliver a signal after a certain amount of time to indicate that it should go medieval on the working thread. Since the OS will deliver the signal regardless of whether there is a blocking system call, this technique works to overcome the timeout issues we encountered. Using SystemTimer is easy—just check out the info in Philippe’s article.
One can hope you’ll never run into the situation of Ruby’s timeout not working for you. If you do hit this problem, however, I hope that SystemTimer can relieve your pain. We extracted from our application and released to Rubyforge (with the client’s blessing) so that you wouldn’t have to recreate the solution we found. Install it, use it, and let us know what you think!
Hello from RailsConf 2008 + 30 days of tech
June 1st, 2008
I’m a little behind the ball on this, but hopefully not too late to make a difference. If you ended up here because you heard my name at a RailsConf presentation, fear not! You’re at the right place. Don’t let the sparse technical content here fool you, it’s simply a reflection of what’s been important for me to write up until now. Life is a crazy wonderful thing, and if you’re open to it it will take you to some amazing places. You have embrace it, roll with it, and grow from it. To that end, I’m making a commitment to myself to post on something technical, however small, every day straight for 30 days. I don’t know how it’s going to go, but there’s only way one way to find out. So if you’re interested, follow me on this month long journey and we’ll see what life brings.
Peace, Love, & Happy Hacking
David Vollbracht