Monday, December 27, 2010

Patrick Farley on Ruby Internals

Elegance in Action
Enlightening talk on how Ruby handles class hierarchies:
http://mwrc2008.confreaks.com/11farley.html
Patrick reveals an important simplicity: method dispatch happens the same way, all the time.
"Elegance is the simplicity found on the far side of complexity" [1]
That is: you find a mathematical beauty from slogging your way through the various details and extracting from that an essential common concept.

Back to Farley... just two data structures and then this simplifying singular algorithm for method dispatch.  Simplistically:

  • A Ruby object has two primary data members: its values for its instance variables and a pointer to its type (what class it is)
  • Ruby class is has two distinguishing data members: a list of methods and a pointer to its super class.

here's the algorithm for method dispatch:

  1. for the object being send the "message"/"method call", dereference its Class
  2. look for the method in that Class' list of methods.  If found, you're done; otherwise continue.
  3. dereference this Class' super class and repeat step 2 (unless you're already at the "Object" class, in that case, you've got the "method_missing" event.

Given this algorithm, you can understand how Ruby implements:
  • per-instance methods ("plain ol'" singleton class)
  • class methods (a metaclass)
  • include class (a singleton class created for each time the module is included)

Per-Instance Methods

These are methods added not to a class, but to an object:
1  class Foo
2   def defined_in_the_class
3     puts "Foo you!"
4   end
5  end
6
7  bar = Foo.new
8  baz = Foo.new
9  
10 def bar.only_works_on_bar
11   puts "I'm a bar!"
12 end
13
14 bar.only_works_on_bar
15 baz.only_works_on_bar
which outputs:
I'm a bar!
NoMethodError: undefined method `only_works_on_bar' for #
from (irb):15
from :0

On line 10, under the covers, Ruby is actually creating a secret class, known as a singleton class.  I'll follow Farley's example and use the prime notation: Foo'.  Foo' is the actual direct class of the object "bar".  Foo' 's super class is Foo.

That secret class creation occurs only on the first time a method is defined on an object.  It's the "purest" form of a "singleton class" -- it's a class which will only ever have one instance (here, Foo' has exactly on instance... that referenced by "bar").

Class Methods

It turns out, that each time you define a class, Ruby actually creates the object that is the class AND a "metaclass" (which is the singleton class of that object).
class Foo
  def self.im_a_class_method
    puts "this impl is stored in Foo's metaclass"
  end
end
Here, we are defining a class, Foo.  An object (of type "Class") is created and given the name of "Foo".  That instance of Class is immediately given a singleton class whereon class methods will be stored.  Remember, a class is an object (an instance of Class) and therefore, this is just per-instance behavior of instances of Class.  It's literally the exact same mechanism providing both class methods and per-instance method behavior.


[1] - http://www.amazon.com/dp/0743290178

Monday, December 6, 2010

Zotero -- Collaborate Web-based Researching

I'm on the hunt for a good bookmarking tool I can use across my computers and my iPhone.

Along the way found an interesting "research" tool: Zotero

  • http://www.zotero.org/

Basically, it's a personal "Library" with social media tools.  The idea is that you can capture and organize online and library resources.  But then you can also use the site to find others who are potentially researching the same topic you are.

While I don't have a use for it, right this moment, seems like a cool tool and a fine example of how social media can be used for positive/constructive purposes.

Thursday, December 2, 2010

Automated Testing Patterns and Smells

Gerard Meszaros gave a good talk at Goople on how to properly design unit tests:

http://www.youtube.com/watch?v=Pq6LHFM4JvE

His tome (and at 900+ pages, that's a fitting term) covers the unit testing topic from the perspective of identifying smells to help inch in the direction of well-structured tests and patterns that codify the structure that yields quality tests.

Good quality tests
  1. bring confidence that the software under test (SUT) works as expected -- "verification"
  2. are easy to read and understand -- "maintainability by way of discoverability"
  3. are relatively inexpensive to maintain (and write new ones).
Why Poorly Design Tests are Worse Than No Tests
Gerard Meszaros gives a good case for why you should care: namely that just writing tests isn't good enough because you can quickly increase the carry cost of the software if you don't design your tests.  In that case, it would be better not to have written the tests in the first place.

Contributions
Meszaros identifies three categories of testing smells:
  1. code smells
  2. behavior smells
  3. project smells
(of which he spoke of the first two in his talk)

In his book, xUnit Test Patterns: Refactoring Test Code, Meszaros identifies a number of categories of patterns:
Chapter 18 Test Strategy Patterns 
Chapter 19 xUnit Basics Patterns 
Chapter 20 Fixture Setup Patterns 
Chapter 21 Result Verification Patterns 
Chapter 22 Fixture Teardown Patterns 
Chapter 23 Test Double Patterns 
Chapter 24 Test Organization Patterns 
Chapter 25 Database Patterns 
Chapter 26 Design-for-Testability Patterns 
Chapter 27 Value Patterns




I'm purchasing this book and expecting to get the following benefits:

  • develop a more academic understanding of the design of tests;  having patterns in mind while coding are excellent guides -- if you don't know the core patterns, you're swinging blind, relatively speaking.
  • improve the quality of my tests by developing a sense for how they can go wrong and why.  This means getting a grasp of the dynamic complexity of making a "mistake" in test design and knowing the cost that incurs later.  This is the essence of informed design decisions.
    • also this is a handy skill for tackling legacy code.