Pivotal Labs

Nick Kallen's blog



The Law of Demeter is a Piffle

edit Posted by Nick Kallen on Wednesday May 07, 2008 at 09:15PM

One of The Blabs' most controversial articles was Lovely Demeter, Meter Maid, in which Pivotal and Thoughtworks battle over which Agile consultancy has the better understanding of the Law of Demeter, and which has better hair and music taste (seriously).

I have never found this "law" very persuasive.

  • The bizarre, culturally loaded analogy about a paperboy and a wallet says nothing insightful about encapsulation boundaries as they arise in real software systems.
  • The blogosphere's endless scholastic hermeneutics of the law's 4 allowances for message sending is a masturbatory philosophical enterprise with nothing relevant to real-world software.
  • The Mockist's insistence on easy mockability is of dubious merit--build better mocking frameworks!
  • And the few practical, real merits that arise in from following the Law of Demeter are better arrived at using other techniques, such as "Tell, Don't Ask".

Here Are Two Examples, one where I violate the Law of Demeter, and another where I don't.

I wrote this code recently, in flagrant violation of the Law:

cookies[:store_id] = @login.store.id

Suppose @login is not an ActiveRecord object, it does not automatically have a #store_id method. Should I create a delegator for this?

class Login
  def store_id
    store.id
  end
end

This is pretty silly. The store_id is not an attribute of the login; rather it's an attribute of the store, and the store is an attribute of the login. The delegator is needless code cruft to replace a dot with an underscore, it smells of the endless boilerplate Java code of my youth. Demeter be damned.

On the other hand, here is a refactoring I did, incidentally complying with the law of Demeter:

Here is the original, Demeter-violating code:

def find_attribute_given_name(name)
  attributes.detect { |a| a.name_or_alias == name }
end

The call to == here is the violation of Demeter. I later replaced this with:

attributes.detect { |a| a.named?(name) }

The latter complies with the "law". And it's much better code. But was I lead to the improvement to this by Demeter? No, I was lead to it by a better understanding of the encapsulation boundaries of the object (#name_or_alias became private) and by a desire to have my code be more terse and clear. a.named?(name) is the most terse explanation of the intended computation that I can think of.

Demeter be damned.

Screw.Unit 0.3

edit Posted by Nick Kallen on Sunday May 04, 2008 at 05:22AM

Screw.Unit 0.3 is now available. I'm skipping 0.2 since there have been two milestones worth of additions to the new version of Screw.Unit. New features:

  • test suite functionality
  • afters
  • global befores and afters
  • enhanced error messages
  • new matchers

Here's how to do a global before:

Screw.Unit(function() {
  before(function() {
    $("#screw_unit_content").html("");
    ActiveAjaxRequests.length = 0;
    PainPoint.instances = [];
    delete window._token;
  });
});

Put this, for instance, in your spec_helper.js file.

Here is how to manage a suite:

Have a suite.html file that requires the Screw.Unit source, your spec helper, and your various test files.

<html>
  <head>
    <script src="../lib/jquery-1.2.3.js"></script>
    <script src="../lib/jquery.fn.js"></script>
    <script src="../lib/jquery.print.js"></script>
    <script src="../lib/screw.builder.js"></script>
    <script src="../lib/screw.matchers.js"></script>
    <script src="../lib/screw.events.js"></script>
    <script src="../lib/screw.behaviors.js"></script>
    <script src="spec_helper.js"></script> <!-- SPEC HELPER -->
    <script src="behaviors_spec.js"></script><!-- A SPEC -->
    <script src="matchers_spec.js"></script> <!-- ANOTHER SPEC -->
    <link rel="stylesheet" href="../lib/screw.css">
    </head>
    <body></body>
  </html>

Have a test file (for example, matchers_spec.js):

Screw.Unit(function() {
  var global_before_invoked = false;
  before(function() { global_before_invoked = true });

  describe('Behaviors', function() {
    describe('#run', function() {
      describe("a simple [describe]", function() {
        it("invokes the global [before] before an [it]", function() {
          expect(global_before_invoked).to(equal, true);
        });
  ...
});

Extra Powerful Matchers

// hash equality
expect({a: 'b', c: 'd'}).to(equal, {a: 'b', c: 'd'});

// recursive array equality
expect([{a: 'b'}, {c: 'd'}]).to(equal, [{a: 'b'}, {c: 'd'}]);

// regular expressions and string inclusion
expect("The wheels of the bus").to(match, /bus/);
expect("The wheels of the bus").to(match, "wheels");

// array emptiness:
expect([]).to(be_empty);
expect([1]).to_not(be_empty);

Thanks To

  • Brian Takita for the ideas and much of the implementation.

Block/fu

edit Posted by Nick Kallen on Wednesday April 30, 2008 at 06:47AM

This is the second article on idiomatic Rubyisms that I like. Today's snippet is also from ActiveRecord.

The following method takes :conditions arrays of the form ['foo_id = ?', foo.id] and turns them into safely quoted SQL strings:

    def replace_bind_variables(statement, values)
      ...
      bound = values.dup
      statement.gsub('?') { quote_bound_value(bound.shift) }
    end

The calling gsub with a block and shifting off of the bound values inside the block is so cute that I want to give it a hug. You know, I cut my teeth doing functional programming and I usually have this aversion to such a side-effect-heavy style. But treating gsub as an iterator -- and using shift as a kind of index into the iteration -- is so elegant you have to love it. It makes you remember that sometimes things are beautiful because they are imperative, not despite.

Of course, you could write this purely:

statement.gsub('?', '%s') % values.map { |v| quote_bound_value(v) }

(I'm showing off here a bit with the % (percent) operator on String.) So this latter code is pure and it's clear. It may even be more terse than the imperative version since it lacks the duping of the values array. But I don't know about you but I don't want to give this functional code a hug. The imperative version is like a baby panda bear:

Panda

Don't you want to hug that? Whereas the Functional Version is like kind of like a Japanese carp.

If there's any lesson from this it's: know which standard library methods take a block.

Here is some code I hacked up recently somewhat in the spirit of the gsub-with-block approach above:

  [relation1[attribute], relation2[attribute]].select { |a| a =~ attribute }.min do |a1, a2|
    attribute % a1 <=> attribute % a2
  end

Don't ask what this code does, it's not what you think (this is operator overloading taken to its psychedelic conclusion). But note the use of min taking a block. This is the same as providing a custom ordering relation to sort, a pretty common idiom in many languages. But here I'm not interested in sorting attributes based on their intrinsic hashrocketness; rather, i need to sort them based on a comparison to some other object. min takes a block gsub takes a block sort takes a block... you'd be surprised at what takes a block. Look it up.

Now, I know some of you are going to say, "I did look it up, and that's not true." That's 'cause you looked it up in a book. Next time, look it up in your gut. -- Stephen Colbert

Ruby Pearls vol. 1 - The Splat

edit Posted by Nick Kallen on Wednesday April 23, 2008 at 05:03AM

Over the next week or so I'll be sharing Ruby idioms and flourishes that I quite like. Today I'd I'll show a few tiny uses of splat! that make me tremble with delight.

Splat! - For Beginners

Splat! is the star (*) operator, typically used in Ruby for defining methods that take an unlimited number of arguments:

def sprintf(string, *args)
end

It can also be used to convert an array to the multiple-argument form when invoking a function:

some_ints = [1,2,3]
sprintf("%i %i %i", *some_ints)

Splat! - For Wizards

Array to Hash Conversion

The best use of splat! for invoking a infinite-arity functions I've ever seen is the recipe for converting an array to a hash. Suppose you have an array of pairs:

array = [[key_1, value_1], [key_2, value_2], ... [key_n, value_n]]

You would like to produce from it the hash: {key1 => value1 ... } You could inject down the array, everybody loves inject, but there is a better way:

Hash[*array.flatten]

Amazing right? This relies on the the fact that the Hash class implements the [] (brackets) operator and behaves thusly:

Hash[key1, value1, ...] = { key1 => value1, ... }

Heads or tails?

Splat! can be used for more than just method definition and invocation. My personal favorite use is destructuring assignment. I read this in Active Record's source code recently:

  def sanitize_sql_array(ary)
    statement, *values = ary
    ...
  end

This is invoked when you do something like User.find(:all, :conditions => ['first_name = ? and last_name = ?', 'nick', 'kallen']). Splat! is used here is to get the head and tail of the conditions array. Of course, you could use always use shift, but the functional style used here is quite beautiful. Consider another example:

first, second, *rest = ary

One final trivium (#to_splat aka #to_ary)

You can actually customize the behavior of the splat operator. In Ruby 1.8, implement #to_ary and in 1.9 it's #to_splat. For example

class Foo
  def to_ary
    [1,2,3]
  end
end

a, *b = Foo.new
a # => 1
b # => [2,3]

This also works for method invocation:

some_method(*Foo.new) == some_method(1,2,3)

When I first learned this at RubyConf I thought this was mind-blowing. I have since never used it.

My Talk at RailsConf

edit Posted by Nick Kallen on Tuesday April 22, 2008 at 12:52AM

So I'm giving a talk at RailsConf, the last day, the last time slot before the keynote -- Sunday @ 1:50

My talk is in the "advanced" track, and is intended for language nerds and Ruby programmers who already have some metaprogramming experience. The topic is "ACTIVERECORD ASSOCIATIONS AND THE PROXY PATTERN". I will look at

  • several implementation techniques for the proxy pattern (aka Blank Slate),
  • and will look very closely at the implementation details and advanced features of ActiveRecord's association proxies, Named Scope's repository proxies, and several other cool uses of this pattern.

If you're looking for an intense, detailed, close look at very advanced Ruby coding techniques then this talk is for you. The full outline is here

Now I understand what they mean by tabular data (or: building a relational database using jQuery and <TABLE> tags)

edit Posted by Nick Kallen on Tuesday April 08, 2008 at 07:26AM

Today I was thinking aloud about Tree Regular Expressions and how they might make a nice query language for document databases like CouchDB. Someone pointed out that CSS3 selectors might make a great concrete syntax for this. One thing lead to another and I thought, why not build a relational database in HTML? So I did. I even got inner joins working.

Let's start with a few tables:

<table class="users">
  <tr>
    <td class="id">1</td>
    <td class="first_name">amy</td>
    <td class="last_name">bobamy</td>
  </tr> 
  ...
</table>
<table class="photos">
  <tr>
    <td class="id">1</td>
    <td class="user_id">1</td>
    <td class="url">http://www.example.com/foo.png</td>
  </tr> 
</table>

Now we can express some queries:

$('.users')
  .where('.id:eq(1)')
  .select('*')

This is equivalent to SELECT * FROM users WHERE id = 1

$('.users')
  .where('.id:eq(1)')
  .select('.id, .name')

This is equivalent to SELECT id, name FROM users WHERE id = 1. Here is something slightly more complicated:

$('.users')
  .where('.name:contains(a)')
    .and('.name:contains(c)')
  .select('*')

But here is the crowning glory, the inner join:

$('.users')
  .join('.photos')
  .where('.photos.user_id:eq(.users.id)')
    .and('.users.id:eq(1)')
  .select('.photos.url')

This is equivalent to:

SELECT photos.url FROM users, photos
WHERE photos.user_id = users.id
  AND users.id = 1

Download the fun at Github.

Screw.Unit, a new JS testing framework, version 0.1

edit Posted by Nick Kallen on Monday April 07, 2008 at 05:20AM

Screw.Unit is a Behavior-Driven Testing Framework for Javascript written by Nathan Sobo and Nick Kallen. It features nested describes. Its goals are to provide:

  • a DSL for elegant, readable, organized specs;
  • an interactive runner which can execute focused specs and describes;
  • and brief, extensible source-code.

What it is

Test Runner

The testing language is inspired by JSpec (and Rspec, obviously). Consider,

describe("Matchers", function() {
  it("invokes the provided matcher on a call to expect", function() {
    expect(true).to(equal, true);
    expect(true).to_not(equal, false);
  });
});

A key feature of Screw.Unit are nested describes and the cascading before behavior that entails:

describe("a nested describe", function() {
  var invocations = [];

  before(function() {
    invocations.push("before");
  });

  describe("a doubly nested describe", function() {
    before(function() {
      invocations.push('inner before');
    });

    it("runs befores in all ancestors prior to an it", function() {
      expect(invocations).to(equal, ["before", "inner before"]);
    });
  });
});

The Screw.Unit runner is pretty fancy, supporting focused describes and focused its:

Focused Runner

You can download the source from Github. Please see the included spec (screwunit_spec.js) to get up and running.

Implementation Details

Screw.Unit is implemented using some fancy metaprogramming learned from the formidable Yehuda Katz. This allows the describe and it functions to not pollute the global namespace. Essentially, we take the source code of your test and wrap it in a with block which provides a new scope:

var contents = fn.toString().match(/^[^{]*{((.*\n*)*)}/m)[1];
var fn = new Function("matchers", "specifications",
  "with (specifications) { with (matchers) { " + contents + " } }"
);

fn.call(this, Screw.Matchers, Screw.Specifications);

Furthermore, Screw.Unit is implemented using the Concrete Javascript style, which is made possible by the Effen plugin and jQuery. Concrete Javascript is an alternative to MVC. In Concrete Javascript, DOM objects serve as the model and view simultaneously. The DOM is constructed using semantic (and visual) markup, and behaviors are attached directly to DOM elements. For example,

$('.describe').fn({
  parent: function() {
    return $(this).parent('.describes').parent('.describe');
  },
  run: function() {
    $(this).children('.its').children('.it').fn('run');
    $(this).children('.describes').children('.describe').fn('run');
  },
});

Here two methods (#parent and #run) are attached directly to DOM elements that have class describe. To invoke one of these methods, simply:

$('.describe').fn('run');

Bind behaviors by passing a hash (see the previous example). Using CSS3 selectors and cascading to attach behaviors provides interesting kind of multiple inheritance and polymorphism:

$('.describe, .it').fn({...}); // applies to both describe and its
$('.describe .describe').fn({...}); // applies to nested describes only

A typical Concrete Javascript Application is divided into 4 aspects:

  • a DOM data model,
  • CSS bound to DOM elements,
  • asynchronous events bound to DOM elements (click, mouseover), etc.,
  • synchronous behaviors bound to DOM elements (run and parent in the above example).

The Concrete style is particularly well-suited to Screw.Unit; to add the ability to run a focused spec, we simply bind a click event to an it or a describe, which runs itself:

$('.describe, .it')
  .click(function() {
    $(this).fn('run');
  })

Anyway, more details about Effen / Concrete Javascript in a later post.

Extensibility

Screw.Unit is designed from the ground-up to be extensible. For example, to add custom logging, simply subscribe to certain events:

$('.it')
  .bind('enqueued', function() {...})
  .bind('running', function() {...})
  .bind('passed', function() {...})
  .bind('failed', function(e, reason) {...})

Thanks to

  • Nathan Sobo
  • Yehuda Katz

My Feed

edit Posted by Nick Kallen on Thursday April 03, 2008 at 06:03PM

For the last several months I've been producing a Shared Items feed in Google Reader that some of my friends enjoy. I subscribe to dozens of blogs, sift through a couple hundred items per day, and curate what I think is the highest quality content.

Feel free to subscribe to my feed:

http://www.google.com/reader/shared/02863459657356251703

alt What my feed looks like

Ninja Patching jQuery

edit Posted by Nick Kallen on Tuesday April 01, 2008 at 11:23PM

Jonathan and I love jQuery's extended psuedo-selectors:

  • :input - Matches all input, textarea, select and button elements.
  • :text - Matches all input elements of type text.
  • :password - Matches all input elements of type password.
  • :hidden - Matches all elements that are hidden, or input elements of type * "hidden".
  • :visible - Matches all elements that are visible.
  • and so on

These aren't actually part of the CSS spec, but they're incredibly useful and can be chained:

$(':input:visible') // => finds all visible inputs

We wanted to customize the behaviors of :text and :visible:

  • We wanted :text to return both <input type="text"> AND <textarea>
  • We wanted :visible to return elements that aren't directly display:none or visibility:hidden, nor are their parents display:none or visibility:hidden

So, we decided to customize this behavior:

jQuery.extend(jQuery.expr[":"], {
  text    : "(a.tagName=='INPUT' && a.type=='text') || (a.tagName=='TEXTAREA')",
  visible : '"hidden"!=a.type && jQuery.css(a,"display")!="none" && jQuery.css(a,"visibility")!="hidden" && (jQuery(a).parent(":hidden").size() == 0)',
  hidden  : 'document != a && ("hidden"==a.type || jQuery.css(a,"display")=="none" || jQuery.css(a,"visibility")=="hidden" || (jQuery(a).parent(":hidden").size() > 0))'
});

So how would you like to ninja-patch jQuery's custom pseudo-selectors?

Monkey

edit Posted by Nick Kallen on Sunday March 16, 2008 at 03:42AM

The next programming language I invent shall be named monkey. And instead of objects it will have patches.

POP, patch oriented programming.

In fact, all of the primitives will be built by reopening primitives. For example, to make the primitive 2, you start with 1, then patch 1 to act like 2.

Out of this, the whole of arithmetic is built. and so on for the most complex of programs.

Other articles: