Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Tools
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker
Adam Milligan

has_one-ish :through

Adam Milligan
Saturday, December 27, 2008

Rails has had the has_one :through association for a while now, and you probably use it on occasion. But, has it ever given you the heebie-jeebies a little bit? Maybe something happens now and then that doesn’t seem quite right? Well, the reason for this is that HasOneThroughAssociation, the class that ActiveRecord uses (shockingly) to implement has_one :through associations, is a subclass of HasManyThroughAssociation.

Whhaaaaaaaaaat?

Yes, oddly enough, a has_one :through association is a collection that is special-cased to always return just one element. Seems kind of dirty, doesn’t it?

I have two, related, problems with this inheritance relationship. First, it violates Liskov substitutability. One cannot in any way argue that a has_one :through association IS A has_many :through association; substituting one for the other would not be likely to maintain a program’s correctness. Second, the inheritance relationship exists to share implementation, not interface. Among others, the Gang of Four have described, persuasively, why this is a terrible idea.

More practically, I’ve now run into two serious bugs caused by this relationship. The first one caused newly created has_one :through associations to return an empty array rather than nil. I fixed that here, with the help of wunderkind David Stevenson. The second I ran into in the last few days while working on this patch, which I’ve written about here. It turns out that trying to get #method_missing to behave sensibly for all non-collection associations is difficult when one of those associations inherits a pile of collection-specific functionality.

So, in order to make my #method_missing patch work I had to rewrite HasOneThroughAssociation with a more appropriate superclass (I used HasOneAssociation). You can find that patch here. Hopefully this change will make its way into the Rails codebase and will make lives easier for generations to come.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Adam Milligan

#method_missing makes me eat my words

Adam Milligan
Saturday, December 27, 2008

A while back I wrote about private methods in ActiveRecord objects, and how Rails 2.2 makes them behave as they should. ActiveRecord associations will no longer respond to private methods defined on their targets; however, my colleague Joseph pointed out that they also no longer respond to methods defined via #method_missing on their targets. Which sucks horse poop through a straw, to some extent.

In my original post I wrote this, fully aware that I was writing lies, but mostly in a rush to get on to my point at the time:

Sometimes I’m forced to use #send:

method_name = extract_method_name_from_the_aether
some_object.send(method_name)

In order to make this code correct with regard to access control I have to add cruft:

method_name = extract_method_name_from_the_aether
some_object.send(method_name) if some_object.respond_to?(method_name)

The astute reader will note that the second code block doesn’t actually approximate the behavior of calling a private method via function call syntax. It should look more like this:

method_name = extract_method_name_from_the_aether
raise NoMethodError if some_object.private_methods.include?(method_name)
some_object.send(method_name)

Two things to notice here: first, the original code didn’t throw an exception if it failed to call the method; second, and much more importantly, the set of private methods is not the complement of the set of methods an object will respond to. So, using !#respond_to? as the condition for preventing the method call is too restrictive. The fact that this code will prevent calling a non-private method defined via #method_missing clearly shows this.

Now, I know the Rails core team chose to use #respond_to? in this particular case for a good reason (which my original patch did not take into consideration): performance. Some simple investigation quickly shows that #include? is an order of magnitude slower than #respond_to? Method calls happen quite a lot, so slow is bad.

I’ve submitted another patch that should correct the #method_missing behavior without dragging everything to a halt. Building on my previous examples, the code looks something like this:

method_name = extract_method_name_from_the_aether
raise NoMethodError if !some_object.respond_to?(method_name) && some_object.private_methods.include?(method_name)
some_object.send(method_name)

Note that the conditional expression is now redundant; the first condition cannot be false if the second condition is true. However, an object will likely respond to the majority of method calls sent to it. The first conditions will (quickly) evaluate to false in these cases, short-circuiting the conditional. In the minority of cases where the first condition evaluates to true, the second condition will (slowly, but correctly) determine if the method call violates access control.

Unfortunately, sensible as it may seem, this change actually breaks has_one :through associations, because of collection-specific functionality they inherit from has_many :through associations. (Oh yes, has_one :through associations are collections, based on their place in the ActiveRecord inheritance hierarchy. Or, they were; read more about that here).

And, finally, I think it’s important to note that none of these machinations in Rails would be necessary if #send (and #send!) actually worked as it should. Heads up, Matz.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Edward Hieatt

Back in the land of the living (or: How RubyMine makes me happy)

Edward Hieatt
Wednesday, December 17, 2008

How my outlook on coding in Rails has changed over the past few months!

When I made the switch from Java to Rails a few years back, I, like many of my fellow Pivots making that same well-chronicled transition, delighted in the ease with which we could suddenly knock out a web app. How we cheered when our object-relational mapping took zero lines of code! How we applauded when we declared our model object validations in near-English! How we roared with laughter when convention viciously slapped the face of configuration! And how we shook our heads in dismay when we realized that our new development environment appeared to be from the mid-, if not early, nineties.

For, while we had arrived in a brave new world of minimalist declarative meta-programming, rapid prototyping, and an new-found sense of productivity that made even the most nimble forms of Java development look like wading through a morass of slimy boilerplate code and endless XML, we soon realized that the IDE situation was less than awesome. Our productivity was overall much improved, but we had taken a huge step backwards when it came to the act of writing – and especially changing – code and tests. Overnight, we went from living it up in a paradise of automated refactorings, seamlessly inbuilt test runners and powerful debuggers to roughing it with a text editor that, to our spoilt eyes, appeared to offer barely more than code highlighting and support for homemade macros.

Not only didn’t our favorite Java IDE, IntelliJ, not function well with Ruby, but nor did Eclipse, and nor did NetBeans. Early on, each had some nominal support for Ruby, it’s true, but it was mostly just code highlighting and some basic navigation. If we wanted to run a test, we had to (horror of horrors) leave our IDE, go to a shell and run a command (mapping a key to an “external tool” was cold comfort, it seemed to me). If we wanted to rename a variable, we had to do it manually. And if we wanted to debug something, well, the only option was to use a tool that appeared so prehistoric that we simply didn’t do it.

In fact, things were so bad that if we were honest with ourselves, TextMate sometimes looked like a better option that the IDE we knew and loved. We pleaded with Pivots who didn’t come from the world of Java to use IntelliJ, if only (for them) for its awesome global search, and if only (for us) to make ourselves feel comfortable in the new world of Rails. But IntelliJ had been rendered so impotent by its Ruby Kryptonite that it felt at times as if we were simply dragging around a comfort pillow that had lost its stuffing. All the progress that had been made in the world of Java IDEs for so many years seemed to have been lost. Woe was certainly us.

But then came some signs of life. NetBeans and Eclipse (in its various forms) were making progress in Ruby-land: they had test runner integration and debuggers that worked. Big steps forward indeed. While I suspected that I would probably miss IntelliJ, I nevertheless gallantly tried to commit to one of them: if they were going to offer me something even close to the power I used to have in my Java IDE, I was willing to put up with a lot. But despite my best attempts to be patient, I was disappointed time and time again. Eclipse still felt clunky compared to IntelliJ. NetBeans still suffered from a problematic global search and less-than-perfect VCS integration. They are gallant attempts, and they deserve credit. They’re both great products and they both serve communities that no doubt find them invaluable. But in that very unquantifiable, personal, emotional way, they weren’t what I really wanted. I wanted that IntelliJ feel.

So where was JetBrains on this? There was the Ruby plugin for IntelliJ, which was making some great strides forward, but that always felt like a bolt-on solution at best. What was more, it often didn’t work with new IntelliJ updates.

Imagine my surprise and delight, then, when Christmas came several months early this year. Suddenly, in late 2008, we are quietly presented with RubyMine. IntelliJ for Ruby? Surely not! I dared not hope for too much when with some trepidation I downloaded an early pre-EAP candidate a few months ago. But, joy of joys, it turned out that it was, or rather, is gradually becoming, (almost) all I was hoping for. Built-in test runner, debugger, pretty good refactorings – all things that other IDEs provide, but in that special JetBrains way that is so much more intuitive. Great success!

Now, I realize that all this probably sounds like a gush of praise that is not yet due, and perhaps that’s true. It’s certainly true that there’s a long way to go: RubyMine is lacking in many ways. But the signs are there that things are moving hastily in the right direction. Recently, each build that has come out has been noticeably better to me than the last (additional useful features, stability, performance). But more importantly, I feel like JetBrains is on the right trajectory with RubyMine. We now have a path towards a great IDE for Rails. I think we’re back in the land of the living, and I’m hopeful that between Rails and RubyMine our productivity will soon jump higher than we could have imagined just a few years ago.

OK, start the “All you need is Emacs”, “VIM is the best thing ever”, and “TextMate rocks, what’s this IDE nonsense?” comments below :)

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Adam Milligan

ActiveRecord learns to respect your privates

Adam Milligan
Tuesday, December 2, 2008

This is somewhat old news, but I don’t think it has received the attention it deserves. As of Rails 2.2, ActiveRecord associations and attributes will now behave properly with regard to access control. You can view the Rails tickets, with patches, here and here.

Take, for example, this schema:

mysql> desc accounts;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| id             | int(11)      | NO   | PRI | NULL    | auto_increment |
| balance        | int(11)      | NO   |     | 0       |                |
+----------------+--------------+------+-----+---------+----------------+

used by this model:

class Account < ActiveRecord::Base
  def deposit(amount)
    do_state_and_federally_mandated_things
    balance += amount
  end

  def withdraw(amount)
    if sufficient_funds?(amount)
      do_state_and_federally_mandated_things
      balance -= amount
    end
  end

private :balance=

private

  def do_state_and_federally_mandated_things
    ...
  end
end

You most likely don’t want someone coming along and modifying the balance attribute directly, either intentionally or inadvertently. However, prior to Rails 2.2, ActiveRecord ignores the privacy declaration for #balance=, so you must execute horrid machinations in order to protect it:

class Account < ActiveRecord::Base
  def balance=(amount)
    raise "I'm private!"
  end

  def deposit(amount)
    do_state_and_federally_mandated_things
    write_attribute(:balance, balance + amount)
  end

  ...

As of Rails 2.2, ActiveRecord will respect private accessors for database column attributes.

Along the same vein, if we add the following:

class User < ActiveRecord::Base
  has_one :account
end

Now we can call methods on the proxy returned by calling User#account, just as if we were calling methods on an account instance; any methods:

johnny_taxpayer = User.first
johnny_taxpayer.account.withdraw(700_000_000_000)
johnny_taxpayer.account.do_state_and_federally_mandated_things

Who knows what scary things #do_state_and_federally_mandated_things does? This will, frighteningly, run just fine prior to Rails 2.2. But, no more.

Now, a number of people have considered this change and asked “why bother?” Ruby allows access to private methods via #send, so they’re not really private, right?

This argument leads down the dark path. Like it or not, cheat around it as you may, access control is an important aspect of object oriented programming. If nothing else, the private keyword is my way of saying “hic sunt dracones,” or “hands off!” It’s also a way of saying “this method may or may not exist in the future.” As a class designer I have every right to refactor that private method entirely away, thus breaking any code that calls it; including, significantly, test code.

More fundamentally, object interactions should be via interfaces. If code makes calls to an object’s private methods, that code has now tied itself to the object’s implementation. Coupling ensues, duck-typing breaks down, anarchy reigns.

So, this begs the question, why does #send ignore access control?. Why should two forms of sending a message to an object differ in their access control semantics? Sometimes I’m forced to use #send:

method_name = extract_method_name_from_the_aether
some_object.send(method_name)

In order to make this code correct with regard to access control I have to add cruft:

method_name = extract_method_name_from_the_aether
some_object.send(method_name) if some_object.respond_to?(method_name)

Now, this is not to say that I don’t think Ruby should provide the ability to call private methods, or generally dig around in an object’s internals. This comes in handy in some instances (although I find many of these instances are short-term solutions that should get refactored away). But, in an ideal world I think the sender should explicitly specify when a message should ignore access control:

potentially_private = extract_method_name_from_the_aether
some_object.send_without_restriction(potentially_private)

This makes the syntax somewhat more ugly, but ugly syntax suits an ugly operation.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Adam Milligan

Volatility: it's not just for sublimation any more

Adam Milligan
Sunday, November 16, 2008

Multithreaded programming was a hot topic at RubyConf this year, and a common theme in many talks was the use of functional languages to prevent contention between threads. This totally makes sense to me, to the limited extent that I can wrap my head around truly functional programming, and I’m sure it’s an excellent approach. However, imagine a case in which we can’t just drop in a new language, so we need to write some multithreaded code in Ruby. I’m sure you won’t have to think too long or hard.

Now, one point several speakers at RubyConf made that I would like to reiterate is this: multithreaded programming is difficult. Gosh darn difficult. People who write software tend to thrive on determinism and linearity. After all, computers always do what we tell them to, right? They don’t make mistakes or change their minds; not like those silly, silly humans. But now big, bad concurrent programming comes along and suddenly computers can come up with different answers depending on, oh, the alignment of the planets. Chaos.

So, functional programming languages aside for the moment, what tools do we have to rein in the inevitable entropy that will, more than likely, eventually bring the planets into alignment against us?

Several years ago Andrei Alexandrescu wrote this excellent article on how to use the C++ type system (stick with me, it’s all Ruby after this paragraph) to automatically prevent race conditions at compile time. I recommend you read it; it’s quite short. Now, however you feel about static typing, you must admit that the approach he describes is a beautiful use of the expressiveness of the C++ type system. The question is, can we do something analogous in Ruby?

First off, lets start with some thread-unsafe code, similar to what Jim Weirich used in his talk on threads at RubyConf:

account = Account.new
threads = []

1000.times do |i|
  threads << Thread.new(account) do |account|
    account.credit(1)
  end
end

threads.each { |thread| thread.join }
puts account.balance

This code results in an account balance somewhere between 1 and 1,000. The exact value depends, of course, on the planets.

Now, to make this thread-safe. I came up with a few attempts using #alias_method and #undef_method, but didn’t find anything satisfying. After that, I figured I’d try a simple proxy to approximate the effect. Here’s a first cut:

class VolatileProxy
  attr_reader :obj

  def initialize(obj)
    @obj = obj
  end

  def method_missing(method, *args)
    raise "Unsynchronized message '#{method}' sent to volatile object"
  end
end

def volatile(obj)
  VolatileProxy.new(obj)
end

def locked_scope(volatile, mutex)
  mutex.synchronize do
    yield(volatile.obj)
  end
end

Now, calls to methods on objects you declare as volatile (shared across threads) will fail messily unless you use them within a locked_scope. To make this work the example code now becomes:

mutex = Mutex.new
account = volatile Account.new
threads = []

1000.times do |i|
  threads << Thread.new do
    locked_scope(account, mutex) { |safe_account| safe_account.credit(1) }
  end
end

threads.each { |thread| thread.join }
puts account.balance

This example has some issues, namely:

  • The final call to #balance will actually fail, since it’s not in a locked_scope; it would be nice to be able to declare individual functions as volatile without too verbose a syntax.
  • It’s tempting to name the locked account object the same name as the unlocked account object, but doing so will cause them to overwrite one another (fixed in Ruby 1.9, of course, but until then…)
  • The unlocked object is easily available. Given the opportunity to circumvent the lock, someone will do something horrible.

I really like the idea of using blocks to scope behavior like this. This particular example doesn’t feel particularly clean to me yet, but hopefully it will give some people something to think about. If you have a better approach, please don’t be afraid to shout it out.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Adam Milligan

Functional witness protection

Adam Milligan
Tuesday, November 11, 2008

I wrote a bit about function objects here. However, if you don’t buy that the persistent state of function objects provides something that anonymous functions cannot, how about this: readability. In some cases.

Anonymous functions are boss and cool, and extremely common in idiomatic Ruby. However, in some cases they can get a little… esoteric. Consider:

people.sort do |lhs, rhs|
  lhs, rhs = rhs, lhs if ascending?
  result = lhs.name <=> rhs.name
  if result == 0
    result = lhs.date_of_birth <=> rhs.date_of_birth
  end

 # etc...
end

Sometimes, anonymity isn’t the answer. Consider:

class ByNameAscending
  def self.to_proc
    Proc.new { |lhs, rhs| rhs.name <=> lhs.name }
  end
end

This allows you to write this:

people.sort(&ByNameAscending)

Or, to push the example to the extreme:

class SortOrder
  def initialize(direction = :descending)
    @direction = direction
  end

  def by(attribute)
    attributes << attribute
    self
  end
  alias_method :and, :by

  def to_proc
    Proc.new do |lhs, rhs|
      lhs, rhs = rhs, lhs if ascending?

      return lhs <=> rhs if attributes.empty?
      attributes.each do |attribute|
        result = lhs.send(attribute) <=> rhs.send(attribute)
        return result if result != 0
      end

      0
    end
  end

private
  def attributes
    @attributes ||= []
  end

  def ascending?
    @direction == :ascending
  end
end

def ascending; SortOrder.new(:ascending); end

Which gives us:

people.sort(&ascending.by(:name).and(:date_of_birth))

A DSL for generating sort order function objects. It could be useful.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Adam Milligan

Give up the func

Adam Milligan
Monday, November 10, 2008

I’ve been a C++ developer ever since I discovered the language in the early 90′s and I realized that my beloved Pascal had nothing on objects. I’ve spent plenty of time working with other languages, of course, and over the past year or so I’ve written almost exclusively Ruby. But, one thing I’ve missed about C++ is the ease with which you can make objects act like functions.

In case your C++ is a little rusty, here’s an example:

class Fibonacci {
public:
  Fibonacci(): n1_(1), n2_(1) {}

  int operator()() {
    int result = n1_;
    n1_ = n2_;
    n2_ = result + n2_;

    return result;
  }

private:
  int n1_, n2_;
};

What you’re looking at there is an overload of the function call operator. No, I’m not kidding; that will compile and run. Instances of the Fibonacci class are called function objects, or functors.

Now, you’re wondering to yourself why anyone would care. The answer is, this function can now carry state around with it:

Fibonacci fibonacci;
fibonacci();  // 1
fibonacci();  // 1
fibonacci();  // 2
Fibonacci()();  // 1

vector<int> v(5);
generate(v.begin(), v.end(), Fibonnaci());  // [1, 1, 2, 3, 5]
generate(v.begin(), v.end(), fibonnaci);  // [3, 5, 8, 13, 21]

This may not seem particularly compelling for generating Fibonnaci numbers, but consider generators that may carry more complex state, or references to state owned by other objects. Consumers can also set initial state, such as a seed value for a random number generator, via the ctor.

Also, consider the generate method above. It expects a third parameter that supports function call semantics with arity of zero. And nothing else. That parameter could be a function pointer (should you desire statelessness and impenetrable syntax), a functor of any type, or anything else that supports operator (). That’s duck-typing, my friends. In a statically-typed language. Dogs and cats sleeping together, and all that.

Again, you cry, why would anyone care? Well, blocks in Ruby carry around the state of the context in which they were created, but sometimes you want more. For instance, if you pass your Proc object around your code may be clearer with the state explicitly encapsulated. The initial state may simply not make sense as local variables when you create the Proc. You may want to save some secondary value that a consumer can query the functor for (how many Fibonacci numbers has this generator generated). Or, perhaps you want consumers to be able to mutate the state in some way.

In any case, this functor approach wacked me over the head recently while I was looking at some code that used the Rails Symbol#to_proc. We all know that Rails adds voodoo to symbols so that

User.find(:all).collect(&:name)

is equivalent to

User.find(:all).collect { |u| u.name }

And, we all know that this works because the & operator, when applied to an object in a parameter list, will implicitly call #to_proc on that object and then convert the result to a block. This is vanilla Ruby functionality, Rails just adds #to_proc to the Symbol class.

So, duh. Check it out:

class Fibonacci
  def initialize
    @n1 = @n2 = 1
  end

  def to_proc
    @proc ||= Proc.new do
      result = @n1
      @n1, @n2 = @n2, @n1 + @n2
      result
    end
  end
end

fibonacci = Fibonacci.new
fibonacci.call  # 1
fibonacci.call  # 1
fibonacci.call  # 2
Fibonacci.new.call  # 1

(1..5).collect(&Fibonacci.new)  # [1, 1, 2, 3, 5]
(1..5).collect(&fibonacci)  # [3, 5, 8, 13, 21]

VoilĂ , a functor. I’d love to hear from anyone who has used this technique to do something really cool.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

RR 0.6.0 Released

Pivotal Labs
Monday, October 13, 2008

I’m pleased to announce the 0.6.0 version of RR. The changes include:

  • Declaring Double subject objects without having to pass it in via the mock!, stub!, dont_allow!, instance_of!, and proxy! methods
  • Revised Double chaining API
  • satisfy matcher
  • hash_including matcher

Declaring Double Subjects (The bang methods)

In previous versions of RR, you always needed to pass in the subject of the double. For example:

subject = Object.new
mock(subject).does_something {:and_returns_me}
subject.does_something # :and_returns_me

Now you can have RR automatically create the subject object for you by using the ! method:

subject = mock!.does_something {:and_returns_me}.subject
subject.does_something # :and_returns_me

Now the bang methods by themselves don’t really add a whole lot, but when used in the context of Double chaining, they become a powerful addition.

Double Chaining

Nick Kallen presented the use case for Double chaining and contributed a patch for the 0.5.0 release of RR. It has proved useful and is now more fully incorporated into RR. Now you can pass in your subject or use the subject provided by RR by using the ! method. Here are some examples of Double Chaining:

mock(subject).first(1) {mock(Object.new).second(2) {mock(Object.new).third(3) {4}}}
subject.first(1).second(2).third(3) # 4

mock(subject).first(1) {mock!.second(2) {mock!.third(3) {4}}}
subject.first(1).second(2).third(3) # 4

mock(subject).first(1).mock!.second(2).mock!.third(3) {4}
subject.first(1).second(2).third(3) # 4

Of course you have access to the proxy facilities:

mock.proxy(User).find('1').mock.proxy!.children.mock.proxy!.find_all_by_group_id(10)
User.find('1').children.find_all_by_group_id(10) # Makes verifications pass and returns the actual children

You can also do branched Double chaining:

mock(subject).first do
  mock! do |expect|
    expect.branch1.mock!.branch11 {11} # or expect.branch1 {mock!.branch11 {11}}
    expect.branch2.mock!.branch22 {22} # or expect.branch2 {mock!.branch22 {22}}
  end
end
o = subject.first
o.branch1.branch11 # 11
o.branch2.branch22 # 22

Satisfy Matcher

Matthew O’Conner submitted a patch that added the satisfy matcher. This adds the ability to add arbitrary argument expectation matchers.

mock(object).foobar(satisfy {|arg| arg.length == 2})
object.foobar("xy")

Hash Including Matcher

Matthew O’Conner also submitted a patch that added the hash_including matcher. This adds a convenient way to assert that the passed-in hash includes certain key/value pairs.

mock(object).foobar(hash_including(:red => "#FF0000", :blue => "#0000FF"))
object.foobar({:red => "#FF0000", :blue => "#0000FF", :green => "#00FF00"})

Mailing list

RR has a mailing lists at:

  • double-ruby-users@rubyforge.org
  • double-ruby-devel@rubyforge.org

Also, RR’s rubyforge page is at http://rubyforge.org/projects/double-ruby and of course the github page is at http://github.com/btakita/rr.

Yes, and there is more to come

There are many interesting ideas floating around. Joseph Wilk has been playing around with adding Spies into RR. I’m also thinking about adding Double validation scoping into RR. Also, I’m impressed by Mocha’s warning of unused stubs. Josh Susser also proposed having a mode where a warning would occur if a mocked method is not implemented on the subject being mocked.

If you have any feature requests, please send an email to the mailing list or add it to the rubyforge tracker.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Sunday Sunday (3 would be cliché)

Pivotal Labs
Thursday, September 25, 2008

This Sunday I am co-presenting at toorcon. The talk that I am a part of is titled Owning telephone entry systems (aka why you shouldn’t sleep so well), and will be presented by Josh Brashars and myself. If you’re in the greater San Diego area and have time to kill at a security conference, stop by.

I’m releasing a ruby web app as a part of the talk. It’s build in sinatra, which has been really fun to play with so far — shout out to nakajima for the quick ramp-up to the frank of ruby’s rat-pack at nycrb! The code is on github, and I plan to write about my impressions of sinatra here in the future. No promises, though.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Introducing RR

Pivotal Labs
Monday, December 31, 2007

I’m pleased to introduce a new Test Double (or mock) framework named RR, which is short for Double Ruby.

Why a Double framework and not a Mock framework?

A mock is a type of test double. Since RR supports mocks, stubs, and proxies, it makes sense to refer to RR as a double framework. The proxy is a new usage pattern that I will introduce later in this article, and in more detail in future articles.

Unfortunately, the terminology over doubles has been contradictory depending on the framework. RR’s terminology tries to be as faithful as possible to Gerald Meszaros’ definition of test doubles. You can read more about test doubles in XUnit Test Patterns and Martin Fowler’s article, Mocks aren’t Stubs. Regretfully, this does mean that RR will have slightly different terminology than other double frameworks.

How does RR compare to other Mock frameworks?

Most double frameworks focus mainly on mocks (hence the categorization “mock framework”). RR’s focus is on enabling more double test patterns in a terse and readable syntax.

RR also does not have dedicated mock objects. It primarily uses the technique called ‘double injection’. Names that other frameworks use are ‘stub injection’, ‘mock object injection’, ‘partial mocking’, or ‘stubbing’. The term I’ll use for this is a double injection, since one or many doubles are being injected into an object’s method.

I’ll use trivial Rails examples to highlight the syntactical differences between RR, Mocha, Rspec’s mocks, and Flexmock. They may or may not be appropriate situations for mocks. The right situations for mocks is an entirely different discussion.

If there is better way to do any of the examples, please post a comment and I will gladly replace it.

Mocks

Here are the ways to mock the User.find method. The expectation is the User class object will receive a call to #find with the argument ’99′ once and will return the object represented by the variable user.

RR
mock(User).find('99') { user }
Mocha
User.expects(:find).with('99').returns(user)
spec/mocks
User.should_receive(:find).with('99').and_return(user)
Flexmock
flexstub(User).should_receive(:find).with('99').and_return(user).once

Stubs

Here are the ways to stub the User.find method. When the User class object receives a call to find with the argument ’99′ it will return user1. When User receives find with any other arg, it returns user2.

RR
stub(User).find('99') { user1 }
stub(User).find { user2 }
Mocha
User.stubs(:find).with(anything).returns(2)
User.stubs(:find).with('99').returns(1)
spec/mocks
users = {
  '99' => user1,
  'default' => user2
}
User.stub!(:find).and_return do |id|
  users[id] || users['default']
end
Flexmock
users = {
  '99' => user1,
  'default' => user2
}
flexstub(User).should_receive(:find).and_return do |id|
  users[id] || users['default']
end

Proxy

A proxy used with a mock or stub causes the real method to be called. Expectations can be placed on the invocation and the return value can be intercepted. The main rationales are test clarity and you can ensure that the methods are being called correctly, even after you refactor your code. I will delve more into proxies and their usage patterns in my next article.

Mock Proxy

The following examples set an expectation that User.find(’99′) will be called once. The actual user is returned.

RR
mock.proxy(User).find('99')
Mocha

You cannot implement this in Mocha. You can do an approximation in this situation however. This technique is not always the solution you need, though.

user = User.find('99')
User.expects(:find).with('99').returns(user)
spec/mocks
find_method = User.method(:find)
User.should_receive(:find).with('99').and_return(&find_method)
Flexmock
find_method = User.method(:find)
User.should_receive(:find).with('99').and_return(&find_method)

Stub Proxy

The following examples intercept the return value of User.find(’99′) and stub out valid? to return false.

RR
stub.proxy(User).find('99') do |user|
  stub(user).valid? {false}
  user
end
Mocha

Again, this is an approximation, since you cannot use proxies in Mocha.

user = User.find('99')
user.stubs(:valid?).returns(false)
User.stubs(:find).with('99').returns(user)
spec/mocks
find_method = User.method(:find)
User.stub!(:find).with('99').and_return do |id|
  user = find_method.call(id)
  user.stub!(:valid?).and_return(false)
  user
end
Flexmock
find_method = User.method(:find)
flexstub(User).should_receive(:find).with('99').and_return do |id|
  user = find_method.call(id)
  flexstub(user).should_receive(:valid?).and_return(false)
  user
end

instance_of

instance_of is method sugar than allows you to mock or stub instances of a particular class. The following examples mock instances of User to expect valid? with no arguments to be called once and return false.

RR
mock.instance_of(User).valid? {false}
Mocha
User.any_instance.expects(:valid?).returns(false)
spec/mocks
new_method = User.method(:new)
User.stub!(:new).and_return do |*args|
  user = new_method.call(*args)
  user.should_receive(:valid?).and_return(false)
  user
end
Flexmock
new_method = User.method(:new)
flexstub(User).should_receive(:new).and_return do |*args|
  user = new_method.call(*args)
  flexmock(user).should_receive(:valid?).and_return(false)
  user
end

More to come

This concludes the introduction to RR. RR enables some techniques, like proxying, that will make your tests clearer and less brittle. In the next article I will describe into patterns and techniques that will make mocks a more feasible tool for more situations.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (783)
  • rails (117)
  • testing (90)
  • ruby (86)
  • ruby on rails (71)
  • jobs (62)
  • javascript (59)
  • techtalk (44)
  • ironblogger (42)
  • rspec (39)
  • bloggerdome (34)
  • productivity (34)
  • activerecord (30)
  • rubymine (30)
  • git (29)
  • gogaruco (29)
  • nyc (27)
  • design (24)
  • mobile (23)
  • pivotal tracker (22)
  • process (21)
  • cucumber (21)
  • jasmine (19)
  • ios (18)
  • tracker ecosystem (17)
  • webos (17)
  • objective-c (17)
  • fun (16)
  • android (16)
  • palm (16)
  • ci (16)
  • "soft" ware (16)
  • bdd (15)
  • tdd (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • css (14)
  • gem (13)
  • mouse-free development (12)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • api (12)
  • keyboard (11)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
Subscribe to ruby Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 7
  9. 8
  10. 9
  11. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Tools
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >