Design-By-Contract in JavaScript, part 2

Two years ago, I wrote an article describing a design-by-contract library for JavaScript. This morning, I realized I wasn’t using it anywhere in my new projects. This really bothers me – a tool that not even the inventor will use?

I did a little thinking, and realized one of the big problems was in object construction, where I literally couldn’t use it. The old DBC-JS file had the approach of requiring users to call a separate function to execute the contract: var root_3 = applyContract(getSquareRoot, this, 3); instead of this.getSquareRoot(3).

Ease of use beats functionality hands-down. Firefox taught us that for user interfaces, and this demonstrates the same for actual code. So obviously I had a design flaw in my design code.

Enter one of the little used features of JavaScript: you can define functions inside functions. The inner functions are treated as local variables. Moreover, any local variables in the outer functions are available to the inner functions.

To spare feedreaders from unwanted technobabble, I’ll continue the rest of this on a secondary page.

Observe the following function:

Note the getContractFunction actually returns a function, not an object or an ordinary value. If I have code like this:

Then the only call a user of sqrtObject has to make is sqrtObject.sqrt(9). No applyContract() mess!

Suppose, though, you want your contract function to be a constructor. For that, the inner function of getContractFunction() is even simpler:

Contracts are thus simplified enormously. Here’s some sample code to demonstrate this new design-by-contract library:

ecmaDebugTest.js


Here’s the updated ecmaDebug.js file, with the new contract code. It also includes my custom NS_ASSERTION firing function for debugging purposes when Venkman just isn’t enough. Other features: toString and toSource have been redirected to the contract’s body (so you can see what the function’s really supposed to do). Also there is a toContractSource() and toContractString() which deliver the whole contract object in source and string form, respectively.

ecmaDebug2.js



Feedback welcome!

6 thoughts on “Design-By-Contract in JavaScript, part 2”

  1. Wow, you discovered closures. Congratulations. It’s really mind-blowing what closures can do. Every time I think I understand just how amazing they are I learn about some other unbelievable thing that I never would have thought was possible.
    I think your DBC stuff could be really great, but it needs more work. It’s still a bit clunky. And what’s the deal with “objectThatDoesAction.doAction()”? Don’t get taken in by the Kingdom of Nouns.
    (From Alex: Actually, I knew about closures several years ago. I probably knew about it when I wrote the JavaScript Developer’s Dictionary’s Function chapter in 2001. I just didn’t know what the term was called.
    I’ve thought about using closures to define private members, but it snowballs out of control very quickly.)

Comments are closed.