The Pragmatic Bookshelf

PragPubThe First Iteration

IN THIS ISSUE

* Advanced Arduino Hacking * Create your Own Arduino IDE * Testing Arduino Code * Test Abstraction * When Did That Happen?

The Arduino Issue In which we bring serious software development tools to the popular single-board platform. Issue #22 April 2011 PragPub • April 2011

Contents

FEATURES

Advanced Arduino Hacking ...... 4 by Maik Schmidt You want to get into this popular open-source electronics prototyping platform, but you don’t want to have to work with development tools designed for artists and hobbyists. Maik shows you how to develop software for Arduino in a professional way.

Create your Own Arduino IDE ...... 22 by Maik Schmidt If you’re going to do serious Arduino development, you may want to work in an environment more like your day job. Here Maik shows how to set up your own IDE.

Testing Arduino Code ...... 24 by Ian Dees Ian brings the testing power of the Ruby-based Cucumber testing library to the Arduino.

Test Abstraction ...... 33 by Jeff Langr, Tim Ottinger Use the techniques in this article to sniff out problems and improve tests by increasing their level of abstraction.

When Did That Happen? ...... 42 by Dan Wohlbruck Claude Shannon was born in this month in 1916. Two decades later, he made history.

— i — DEPARTMENTS

Up Front ...... 1 by Michael Swaine Just because it’s a hobby that doesn’t mean you don’t need power tools.

Choice Bits ...... 2 A few selected sips from the Twitter stream.

The Quiz ...... 45 by Michael Swaine Just your basic Arduino Sudoku.

Calendar ...... 47 After a slow-ish winter, things are really heating up this spring.

Shady Illuminations ...... 58 by John Shade Some elements of Sun Microsystems were never going to survive the move to Oracle. John runs down the Doomed from the Get-Go list.

Except where otherwise indicated, entire contents copyright © 2011 The Pragmatic Programmers.

Feel free to distribute this magazine (in whole, and for free) to anyone you want. However, you may not sell this magazine or its content, nor extract and use more than a paragraph of content in some other publication without our permission.

Published monthly in PDF, mobi, and epub formats by The Pragmatic Programmers, LLC, Dallas, TX, and Raleigh, NC. E-Mail [email protected], phone +1-800-699-7764. The editor is Michael Swaine ([email protected]). Visit us at http://pragprog.com for the lowdown on our books, screencasts, training, forums, and more.

ISSN: 1948-3562

— ii — Up Front Bringing Serious Software Welcome to our first-ever Arduino issue! Development to the Arduino Arduino, as the whole geek-speaking world knows by now, is an extremely by Michael Swaine accessible open-source single-board microcontroller designed for pursuing electronics projects. Also as the whole geek-speaking world knows by now, Arduino is very popular. Over 100,000 boards have been sold so far, and the fascination shows no signs of abating. We’re a hard-core software developers’ magazine, so that’s the approach we’re taking to Arduino in this issue. We figure you want to get into this popular open-source electronics prototyping platform, but you don’t want to have to work with development tools designed for artists and hobbyists. So Arduino master Maik Schmidt shows you how to develop software for Arduino in a professional way. Ian Dees gets into the act, too, showing how to bring serious software testing to the Arduino. Just because it’s a hobby that doesn’t mean you don’t need power tools. Of course we also have lots of other good stuff in this packed issue. Jeff Langr and Tim Ottinger offer up a thoughtful article on Test Abstraction, Dan Wohlbruck offers another in his series on computer history, John Shade has some thoughts on Sun, Oracle, and the Doomed List, and there is a quiz (Arduino-themed, of course).

Arduino Resources We recommend that you include in your Arduino toolkit Maik’s book, Arduino: A Quick-Start Guide [U1]. But there are other books to check out, including

these two new ones from O’Reilly: Arduino Cookbook [U2] by Michael Margolis

and Make: Arduino Bots and Gadgets [U3] by Tero Karvinen and Kimmo Karvinen. Also, here are three sites Maik tells us are must-visits for the Arduino hacker: makershed.com [U4], adafruit.com [U5], and hackaday.com [U6].

External resources referenced in this article:

[U1] http://pragprog.com/refer/pragpub22/titles/msard/arduino

[U2] http://oreilly.com/catalog/9780596802486/

[U3] http://oreilly.com/catalog/0636920010371/

[U4] http://makershed.com

[U5] http://adafruit.com

[U6] http://hackaday.com/

PragPub April 2011 1 Choice Bits Top 11 books, tweets from the coding life, and better beer through Arduino What’s Hot hacking... Top-Ten lists are passé—ours goes to 11. These are the top titles that folks are interested in currently, along with their rank from last month. This is based If you can’t do it with an Arduino, is it really worth solely on direct sales from our online store. doing? 1 NEW iOS Recipes

2 1 Agile Web Development with Rails

3 3 The RSpec Book

4 NEW Programming Concurrency on the JVM

5 5 Crafting Rails Applications

6 7 Programming Ruby 1.9

7 4 Rails Test Prescriptions

8 2 Hello, Android

9 9 Seven Languages in Seven Weeks

10 6 HTML5 and CSS3

11 NEW Pragmatic Thinking and Learning

My Arduino Why would you want to buy and program an open-source, single-board microcontroller? Why, to improve your home-brewed beer, of course! • Wooh! got our #arduino powered 1950s telephone up and running! #knowledgelives — @bluec • Making a temperature logger for my fermentation with an #arduino Gonna be interesting :) #homebrew — @stoffers • Etch a Sketch clock: http://bit.ly/b5Gdfw #awesome #maker #arduino — @erinldoyle • Arduino Tic-Tac-Toe http://bit.ly/hcHs48 #arduino — @tipie • A networked candy grabber http://www.pimedius.com/Candygrabber #arduino — @dboardman • Spent a very interesting afternoon writing laser harp control software in #arduino. — @moray_macdonald • Made a bunch of optimizations on the #oracle database. Now everything is running smoothly on an #arduino. I'm very proud of myself! — @cscmeu • How to Make a Brain-controlled Device http://bit.ly/dKXL3H #arduino — @romainsauvez • HIDUINO: Your #Arduino is Now A #MIDI Interface http://bit.ly/eAlK36 — @jocequelo • Monkey Automatons! http://bit.ly/egyXH7 #arduino — @tipie

PragPub April 2011 2 This Coding Life • I'm missing out. Apparently, I need to stop coding so much and spend more time on twitter arguing about how best to write code. — @benrady • I also feel that "fast-paced work environment" means "disorganized with lots of overtime." http://bit.ly/gC4JSA — @bphogan • Have to say this again: Regex section of Stackoverflow is the outstanding late Saturday night infotainment http://bit.ly/i4esC4 — @staffannoteberg • I may be the last living human who remembers using submit and supersub in CP/M. — @tottinge • @coreyhaines As context-driven testers, we've named at least three contexts in which context-driven is a bad idea. Craft demands that. — @michaelbolton • You know what keeps me grounded? The aluminum case on my MacBook Pro. #shocking — @benrady • SpacebarOnTheMacQuitWorkingTakingItToTheGeninusBar — @venkat_s Need to Know • Dogs are the new fashion exercise accessory. http://j.mp/goUwfH /via @khoi — @tswicegood • Antique clown shoes: The nouvelle vague of hipsterism twitpic.com/4bb2u7 — @noradio • Acid test: RT @Fritinancy: RT @Mxrk: Adding lime juice to any recipe is low-cal way to find out if you have any paper cuts — @makower • ProTip: calling self when you mean to call super can lead to bad, bad things happening. — @jeff_lamarche • Today was better than yesterday. Tomorrow will be better than today. And so on. #recursion #tailcalloptimization — @chadfowler • note to self: laptop as alarm clock works best when plugged into wall #savebytriplelyredundantalarms — @adamgoucher • Must be just about leave-secret-iPhone-in-a-bar time of year. (via @drewmccormack) — @dimsumthinking • nothing says "viable and sustainable business model" like building an app on top of a service owned by someone else. — @bphogan • Cegłowski's first law of Internet business: "Never get in the way of people trying to give you money" http://pinboard.in/blog/173/ — @tottinge • Why does my iPhone insist on correcting thing to thong? Amusing, but not helpful. — @duncan This month we were tuned to the tweeting channel of David Boardman, Michael Bolton, James Duncan Davidson, Erin Doyle, Chad Fowler, Adam Goucher, Corey Haines, Brian Hogan, knowledgelives, Jeff Lamarche, Moray Macdonald, Joel Makower, Marcel Molina, Staffan Nöteberg, Christophe Nowicki, Tim Ottinger, Tius Piepin, Jocelyne Quélo, Ben Rady, Romain Sauvez, Kristoffer Sivertsen, Daniel Steinberg, Venkat Subramaniam, and Travis Swicegood. Feel free to tune us in [U1]. Those who would follow tweets must suffer their tweets to be followed.

External resources referenced in this article:

[U1] http://www.twitter.com/pragpub

PragPub April 2011 3 Advanced Arduino Hacking Bringing Serious Developer Tools and The Arduino was made for beginners. The microcontroller board has a lot of Techniques to Arduino, the Popular built-in mechanisms that prevent beginners from destroying it accidentally, Single-Board Platform and its development environment is as simple as possible. On the web and in your favorite book store you can find countless tutorials and books for beginners. by Maik Schmidt Simplicity is the basis of the Arduino’s popularity.

You want to get into this popular open-source But simplicity is a double-edged sword. As the Arduino became more popular, electronics prototyping platform, but you don’t want advanced developers and even experts started to have a look at it and quickly to have to work with development tools designed got disappointed by the development environment’s limited capabilities and for artists and hobbyists. Maik shows you how to develop software for Arduino in a professional way. the lack of advanced documentation. In this article I’ll try to fill some of those gaps. You’ll learn how to develop software for the Arduino in a professional way. For example, you’ll see how to manage your Arduino projects with a good old Makefile that you can easily integrate into your favorite IDE. In addition, you’ll learn that the Arduino platform supports nearly all features of the current C++ standard and that it’s advantageous to use these features for programming embedded systems. But first we’ll take a close look at the Arduino IDE’s internals. Then once we’ve seen how it turns our sketches into executable code, we’ll create a Makefile to bypass it completely.

What’s Wrong With The Arduino IDE? One of the reasons of the Arduino’s success is its beginner-friendly integrated development environment (IDE). For people who have never written any software, the Arduino IDE is a perfect starting point. It offers only features that you absolutely need: compile a program, transfer it to the Arduino board, and monitor the serial port. Also the IDE has basic support for grouping a set of files into a project, it supports syntax coloring, and it helps you to quickly find example projects and documentation. All this is helpful for beginners and useful for small projects, but as soon as your projects become more sophisticated you’ll need a more elaborate programming environment. You’ll probably want to use your favorite text editor or IDE and you may need a more flexible build process. For example, if you’re developing a video game for one of the great Arduino video game shields, you’ll need tools that turn bitmap graphics into C/C++ source code. These tools should be part of your automatic build process, and it’s difficult to add them to the original IDE. So let’s see how the Arduino IDE turns your sketches into binary code for the Arduino board.

PragPub April 2011 4 Behind the Scenes People sometimes seem to be a bit irritated when it comes to the language the Arduino gets programmed in. That’s mainly because the typical sample sketches look as if they were written in a language that has been exclusively designed for programming the Arduino. But that’s not the case—it is plain old C++ (which implies that it supports C, too). To turn C++ code into machine code the Arduino can execute, we need a suitable compiler. Every Arduino uses an AVR microcontroller designed by a company named Atmel. (Atmel says that the name AVR does not stand for anything.) These microcontrollers are very popular, and many hardware projects use them. One of the reasons for their popularity is their excellent tool chain, based on the GNU C++ compiler tools and optimized for generating code for AVR microcontrollers. That means you feed C/C++ code to the AVR compiler and it does not translate it into machine code for your computer but for an AVR microcontroller. This is called cross-compiling and is the usual way to program embedded devices.

For nearly all GNU development tools—such as gcc, ld, or as—there’s an AVR pendant: avr-gcc, avr-ld, and so on. You can find them in the hardware/tools/bin directory of the Arduino IDE. The IDE is mainly a graphical wrapper that helps you to avoid using the command-line tools directly. Whenever you compile or upload a program using the IDE, it delegates all work to the AVR tools. As a serious software developer, you should enable the IDE’s verbose output, so you can see all command-line tool invocations. Load an arbitrary sketch and hold down the Shift key when you click the Verify/Compile in the IDE’s toolbar. The output in the message panel should look similar to the picture.

PragPub April 2011 5 The command invocations look a bit weird at first, because of the names of the many temporary files that are created. You should still be able to identify all compile and link steps that are necessary to build even a simple sketch like the blinking LED example. That’s the most important thing that the Arduino team did: they hid all these nasty details well behind the IDE, so even people with no software development experience are able to program the Arduino. So to compile and upload Arduino programs yourself you have to perform the same steps as the IDE; that is, you have to invoke the AVR tools in the right order and for the right files. In principle you could do this manually, but it’s much more efficient to use a Makefile for this task.

Do It Yourself Now that we know how the Arduino IDE works internally we will bypass it and use make for compiling, uploading, and monitoring our programs. Make

[U1] is a project management tool that has been around for decades and helps you to build executables from source files. It knows a lot of rules for turning C/C++ files into object files, for example, and it has some clever algorithms for calculating dependencies between your project’s files, so it only compiles source files if needed.

PragPub April 2011 6 In contrast, the Arduino IDE always recompiles your sketch and all the system libraries it needs. This usually happens very fast on a modern computer, but it is not necessary and in some cases it might be even annoying. Also it’s hard to automate tasks with the IDE. For example, you might have completed a successful project and now you have to transfer the same software to a bunch of Arduinos. In this case you want to compile your program only once and then upload it to as many devices as you like. In a typical development cycle for an Arduino program you compile the program and upload it to an Arduino board. Then you usually start a serial monitor to see what’s happening. So our perfect Makefile should support the following targets: • all: This is the default target in nearly all Makefiles on this planet and it builds the whole project. • clean: Sometimes it’s good to start from scratch and this target deletes all build artifacts. • upload: Upload the software to an Arduino board and compile it if necessary. • monitor: This target opens a serial monitor and connects it to the Arduino. • upload_monitor: This is a convenience task that uploads a program and opens a serial monitor. Writing Makefiles isn’t fun, but fortunately Alan Burlison did all the hard work for us already [U2]. He created a master Makefile that you can include into your own Makefile, so you only have to adjust some settings. I had to add some minor changes to the master Makefile, and you can download my version (together with all the other code I use in this article) from github [U3].

Let’s see how to actually use make to compile a simple Arduino program.

Hello, world! One of the simplest Arduino programs possible is the following:

void setup() { Serial.begin(9600); } void loop() { Serial.println("Hello, world!"); delay(1000); }

It initializes the serial port and then it outputs the text “Hello, world!” endlessly in a loop. Here’s our project’s Makefile:

PragPub April 2011 7 # Your Arduino environment. ARD_REV = 22 ARD_HOME = /Applications/Arduino.app/Contents/Resources/Java AVR_HOME = $(ARD_HOME)/hardware/tools/avr ARD_BIN = $(AVR_HOME)/bin AVRDUDE = $(ARD_BIN)/avrdude AVRDUDE_CONF = $(AVR_HOME)/etc/avrdude.conf # Your favorite serial monitor. MON_CMD = screen MON_SPEED = 9600 # Board settings. BOARD = diecimila PORT = /dev/tty.usbserial-A60061a3 PROGRAMMER = stk500v1 # Where to find header files and libraries. INC_DIRS = ./inc LIB_DIRS = $(addprefix $(ARD_HOME)/libraries/, $(LIBS)) LIBS = include ../Makefile.master

As you can see you only have to define a few variables: ARD_REV specifies the revision of the Arduino IDE you have installed. Although you no longer have to use the IDE to compile your programs, you still need an installation of the IDE to have all tools and libraries available. ARD_HOME has to point to the IDE’s installation directory.

If your program uses the serial port, set MON_CMD to your favorite serial monitor. Also you should set MON_SPEED to the baud rate you’re using in your program. Unfortunately, serial monitors often differ in their invocation syntax, so you might have to change the master Makefile to get your preferred serial monitor running. Here’s the relevant portion of the master Makefile:

upload : all - pkill -f '$(MON_CMD).*$(PORT)' - sleep 1 - stty -f $(PORT) hupcl - $(AVRDUDE) -V -C$(AVRDUDE_CONF) -p$(MCU) -c$(PROGRAMMER) \ -P$(PORT) -b$(UPLOAD_SPEED) -D -Uflash:w:$(IMAGE).hex:i monitor : $(MON_CMD) $(PORT) $(MON_SPEED)

Adjust the monitor target to your needs and notice that the upload target removes all running serial monitor processes from the process list using pkill. Depending on your UNIX flavor you also might have to change the pkill and stty calls. For example, Mac OS X usually does not have a pkill command, but

you can install it [U4]. Also stty’s command switch '-f' is named '-F' on Linux systems.

Back to our master Makefile’s configuration. With the BOARD variable you define which type of Arduino board you’re using. You can find a list of all supported boards in hardware/boards.txt in the IDE’s installation directory. PORT contains the name of the serial port you have connected your Arduino to. Finally you can tell the compiler where to look for header files and libraries using INC_DIRS and LIB_DIRS. With LIBS you can define a set of libraries that should be linked to your project. If you need the libraries for LCD and EEPROM, for example, set LIBS to “LiquidCrystal EEPROM”. You can find many useful libraries in the libraries folder of the IDE’s installation directory.

PragPub April 2011 8 Don’t forget to include the master Makefile at the end and then run your Makefile for the first time:

maik> make ... avr-size build/HelloWorld.hex text data bss dec hex filename 0 2106 0 2106 83a build/HelloWorld.hex

If everything goes fine you will see a lot of output that is very similar to the IDE’s verbose output. In fact it is nearly the same. A major difference is that you will see the output of the avr-size command at the end. This tool tells you how much memory your program will use on the Arduino and it also tells you which parts of the memory it occupies. This can be a helpful debugging aid if you ever use too much memory. And believe me: sooner or later you will! You might have noticed that we did not specify a target when we invoked make. If you do not specify a target make will run the all target by default. In our case this target builds the whole project. It creates a directory named build in your project’s directory. There you can find all artifacts that make created during the build process. Most files are system files and libraries needed by all Ardunio programs and they do not differ from project to project. Only files starting with “HelloWorld” were built specifically for our project.

All files ending with eep, elf, and lst are binary files that you probably know from other build processes. Only HelloWorld.hex might be new to you and you might wonder where the final executable file like a.out is? The answer is simple: HelloWorld.hex is the final executable. It contains all the data that we will upload to the Arduino.

Now run the upload target and you should see something like this (I’ve shortened some path names for clarity):

maik> make upload pkill -f 'screen.*/dev/tty.usbserial-A60061a3' sleep 1 stty -f /dev/tty.usbserial-A60061a3 hupcl avrdude -V -Cavrdude.conf -patmega168 -cstk500v1 -b19200 \ -P/dev/tty.usbserial-A6 -D -Uflash:w:build/HelloWorld.hex:i avrdude: AVR device initialized and ready to accept instructions Reading | ############################################### | 100% 0.02s avrdude: Device signature = 0x1e9406 avrdude: reading input file "build/HelloWorld.hex" avrdude: writing flash (2106 bytes): Writing | ############################################### | 100% 1.60s avrdude: 2106 bytes of flash written avrdude: safemode: Fuses OK avrdude done. Thank you.

Here you can see the avrdude command in action. This tool is responsible for loading code into the Arduino, and you can use it for programming many other devices, too. Study the output carefully to see where make uses our former variable definitions such as PORT.

Finally we should test if our program actually does what it’s supposed to do. Invoke make monitor and your serial monitor should open and print lots of “Hello, world!” messages.

PragPub April 2011 9 That’s it! You’ve compiled and uploaded your first Arduino program without starting the Arduino IDE. Also you’ve monitored your program’s output from the command line and did not use the IDE’s serial monitor. You’re well prepared for the next steps! So let’s build a more sophisticated project: a park distance control system. We will use some advanced C++ features such as namespaces and template programming, and we’ll have a look at dynamic memory management on the Arduino.

A Park Distance Control System Many new cars come with a park distance control system (PDC) that helps you to enter or leave tight parking spaces. Whenever you are going to collide with an obstacle such as another car the PDC will give you an acoustic (and sometimes also visual) warning. Usually, the PDC starts to beep if it detects an object near your car and it increases the frequency of the tones the closer you get. If you’re getting too close it emits a non-stop warning tone. If we’re going to build our own PDC we need a device for generating acoustic signals. A piezo buzzer [U5] is a perfect fit for our purposes. It’s cheap and easy to use, because it only has two pins. Connect one to the Arduino’s ground and the other one to the Arduino’s digital pin #13 (see illustration). It doesn’t matter which of the buzzer’s pins you connect to ground.

PragPub April 2011 10 We also need a sensor for measuring the distance to the nearest object, and we have several options. Commercial PDCs use ultrasonic sensors, because they offer high accuracy and a large range. For our PDC I’ve chosen the SHARP GP2Y0A21YK0F [U6] infrared proximity sensor, because it’s much cheaper than most ultrasonic sensors. The sensor emits infrared light and measures the time it takes for the reflected light to get back to the sensor. It is easy to use, but has a very limited range (about 10 to 80 cm). You could not use it for a real car’s PDC, but for a small robot or an RC car it’s sufficient. The infrared proximity sensor is an analog device that outputs a voltage corresponding to the detection distance. Connect its signal pin to one of the Arduino’s analog pins such as A0, connect the ground pin to the Arduino’s ground and its Vcc pin to the Arduino’s 5V pin (see illustration). Wiring the circuit of our PDC was easy. Let’s write some code now to bring our hardware to life.

PragPub April 2011 11 Using the Piezo Buzzer We start with the code for the piezo buzzer, and without further ado I present the Speaker class:

#include #include "WProgram.h" namespace arduino { namespace actuators { class Speaker { public: static const uint16_t DEF_FREQUENCY = 1000; static const uint32_t DEF_DURATION = 200; Speaker(const uint8_t speaker_pin) : _speaker_pin(speaker_pin) {} void beep( const uint16_t frequency = DEF_FREQUENCY, const uint32_t duration = DEF_DURATION) const { tone(_speaker_pin, frequency, duration); } private: uint8_t _speaker_pin; }; } }

If you’re not very familiar with C++ this code might look a bit shocking at first, but we’ll dissect it piece by piece. First of all, we include two header files. stdint.h defines portable integer types, for example uint16_t for a 16 bit unsigned integer. These types are advantageous for several reasons, but most importantly they make your code more predictable, because the length of data types in C/C++ is not strictly defined. In addition they save you some typing, which is always a good thing.

The WProgram.h header file comes with the Arduino IDE and defines all its basic constants and functions such as OUTPUT or digitalWrite. We have to include it, because we will use the tone function later on.

After we’ve included all the header files we need, we declare a nested namespace using the namespace keyword. Namespaces help you to prevent name clashes when using code from different sources. You have to separate nested namespace by a double colon (::), so everything we define from here belongs to the arduino::actuators namespace.

Then we define the Speaker class and start with two constants named DEF_FREQUENCY and DEF_DURATION. They contain the default frequency (in Hertz) and the default duration (in milliseconds) of our warning tone. Note that we’re using the types from stdint.h for the first time.

You should also note that we’re using the const keyword for defining the constants. Many people still use the preprocessor’s #define directive for defining constants and I strongly recommend that you get out of this habit! The compiler will never see the name of a constant defined using #define, so this can lead to strange error messages and long debugging sessions. Also, depending on your constant’s type, the compiler will often produce more effective code when using proper constant definitions using const.

PragPub April 2011 12 Have you noticed that in modern C++ it’s possible to define static constants (aka class constants) like DEF_DURATION directly in a class declaration? This is a very handsome feature and also helps to keep namespaces clean. The constructor of our Speaker class expects a single argument (the number of the digital pin it’s connected to) and it initializes a private class member named _speaker_pin. Private member names do not have to start with an underscore in C++, but I think it makes code more readable under certain circumstances.

You might wonder how we initialize _speaker_pin without using an assignment. We’ve used a member initialization list which in C++ is the preferred way for initializing class members. In most cases member initialization is more efficient than assignment statements and in some cases, for example for const members or for references, you even have to use it. All in all, it is never a disadvantage and it’s often more efficient.

Next we define a method named beep that takes two arguments, a frequency and a duration. Both arguments have default values, so if you do not pass a duration, for example, it will automatically be set to DEF_DURATION. The method body is simple, because it delegates all the hard work to the Arduino’s tone function.

There’s one thing worth mentioning, though: we declare the beep method as const. This tells the compiler that calling this method does not change the class’s state. It helps the compiler to optimize the machine code and it also helps to detect errors when passing around constant objects. Use const wherever possible!

The definition of the Speaker class is complete and you can use it as follows:

#include "speaker.h" using namespace arduino::actuators; Speaker speaker(13); speaker.beep(1000, 500);

This code fragment uses a piezo buzzer connected to pin 13 and outputs a tone having a frequency of 1000 Hz for 500 milliseconds. Note that we import the arduino::actuators namespace with the using namespace directive. Without it you’d have to use the fully qualified name arduino::actuators::Speaker.

Even in our small Speaker class we can benefit from many useful C++ features. We have used namespaces, class constants, const function declarations, and member initialization lists. We’ll use even more features when we start to control the infrared proximity sensor.

Using the Infrared Proximity Sensor

Our infrared proximity sensor [U7] is an analog device, so it outputs a voltage corresponding to the current detection distance. Its data sheet contains some graphs explaining how a certain voltage can be mapped to a distance. We can simplify the distance calculation, because the distance is approximately equal to 27 V * cm. You might be tempted to read the sensor’s signal from analog pin A0 using analogRead and turn it into a distance immediately. Unfortunately, the real

PragPub April 2011 13 world is a bit more complicated, because sensor signals are often subject to jitter and distortion. So, it’s a much better idea to continuously append sensor data to a small buffer and calculate their average value. If the buffer is full and a new sensor value arrives, the oldest value will be removed from the buffer. We call such a data structure a ring buffer. After I’ve written countless ring buffer implementations using fixed-length arrays of various types, I decided to find a reusable solution. Here’s my dynamic RingBuffer class for all C++ integer types:

namespace arduino { namespace util { template class RingBuffer { private: T* _samples; uint16_t _sample_pos; uint16_t _buffer_size; public: static const uint16_t DEF_SIZE = 16; RingBuffer(const uint16_t buffer_size = DEF_SIZE) { _sample_pos = 0; _buffer_size = buffer_size != 0 ? buffer_size : DEF_SIZE; _samples = static_cast( malloc(sizeof(T) * _buffer_size) ); } RingBuffer(const RingBuffer& rhs) { *this = rhs; } RingBuffer& operator=(const RingBuffer& rhs) { if (this != &rhs) { _sample_pos = rhs._sample_pos; _buffer_size = rhs._buffer_size; _samples = static_cast( malloc(sizeof(T) * _buffer_size) ); for (uint16_t i = 0; i < _buffer_size; i++) _samples[i] = rhs._samples[i]; } return *this; } ~RingBuffer() { free((void*)_samples); } void addValue(const T value) { _samples[_sample_pos] = value; _sample_pos = (_sample_pos + 1) % _buffer_size; } T getAverageValue() const { float sum = 0.0; for (uint16_t i = 0; i < _buffer_size; i++) sum += _samples[i]; return round(sum / _buffer_size); } uint16_t getBufferSize() const { return _buffer_size; } }; } }

PragPub April 2011 14 This class uses a lot of the features we’ve seen already in our Speaker class. Still we have something new: template classes. You can do a lot of interesting things using template classes, but you’ll mainly use them for generating classes for different types. In our case it helps us to make the RingBuffer work for all C++ integer types such as int or long.

Defining template classes is easy. Simply put a template declaration in front of the class declaration. Now you can use “T” as a placeholder for every C++ type in your class (you can choose whatever name you like instead of “T”, but it’s a widespread convention).

We use the placeholder for the first time to declare the samples member. Here we declare a pointer to the actual memory buffer we are going to use. In a non-templated class this declaration would have been something like uint16_t* _samples;, but using templates we can be more generic. Then we define two more member variables. _sample_pos stores our current position in the buffer, so we know when we have to remove older data samples. _buffer_size contains the size of our sample buffer.

The public interface of our class starts with a class constant named DEF_SIZE that specifies a default size for the ring buffer. The constructor is a delicate piece of code. It expects the buffer size as an argument and initializes all private members. In this case we cannot use member initialization lists, because we cannot use pure assignment statements to initialize the member variables. First of all, we set _sample_pos to 0. Then we initialize _buffer_size and we make sure that the buffer size is greater than 0. If it’s not we use the default size. You might think that it’d be more appropriate to raise an exception in such a case and I fully agree with you. Unfortunately, we’ve found one of the major restrictions when programming the Arduino: it does not support exceptions, because their runtime overhead would be too big. So we had to find a compromise and using the default size is a reasonable approach in this case. If you need more control, you have to add a separate initialize method that returns some kind of error code. In the next line we initialize the samples buffer and we find another restriction. Usually, you’d use the new operator in C++ to allocate objects dynamically and you’d use delete to give back the occupied memory. Both operators aren’t supported on the Arduino, so we had to use good old malloc. For our purpose it does not make a difference, because we will only allocate memory for integer types. It makes a big difference when you allocate memory for “real” objects, because the new operator automatically calls each object’s constructor while malloc doesn’t. The same is true for giving back the memory. delete automatically invokes all destructors and free does not.

Note that we use C++’s shiny new static_cast operator to turn the void pointer returned by malloc into a pointer to our generic T objects. Attentive readers have certainly noticed that we did not check if malloc returned NULL. We should have done this, and in the next version of this class I’ll definitely add an initialize method!

The next three methods you’ll find in nearly every C++ class that encapsulates pointers to dynamic memory. We define a copy constructor, an assignment

PragPub April 2011 15 operator, and a destructor. These methods make sure that you can safely copy objects and pass them to methods without messing up the dynamic memory.

Finally, we implement the ring buffer’s business logic. addValue takes a data value having a generic type and appends it to the ring buffer. It uses the modulus operator to make sure that we do not exceed the data buffer’s bounds and to automatically throw out old values if necessary. getAverageValue calculates the average value of the current sample buffer and returns it as a generic type. Now that we have a generic ring buffer implementation, let’s use it to implement an InfraredSensor class:

#include #include "ring_buffer.h" using namespace arduino::util; namespace arduino { namespace sensors { class InfraredSensor { private: uint8_t _pin; RingBuffer _buffer; public: static const float SUPPLY_VOLTAGE = 4.7; static const float VOLTS_PER_CM = 27.0; InfraredSensor(const uint8_t pin); void update(void); float getDistance(void) const; }; } }

This class has only two data members. In _pin we store the number of the analog pin we have connected the sensor to and _buffer is the ring buffer we’re going to use to de-jitter the sensor’s signal. Here we have to instantiate a concrete implementation of our template class for the first time. When the compiler encounters the declaration RingBuffer it replaces all occurrences of the generic type “T” with uint16_t and compiles the file afterwards. If in your next project you’re working with a sensor that outputs smaller values, it might be sufficient to use RingBuffer, for example.

The rest of the class declaration is fairly easy. We define a constructor and two methods for updating the sensor and for getting the distance to the nearest object. Their implementation is straightforward:

PragPub April 2011 16 #include #include #include "infrared_sensor.h" namespace arduino { namespace sensors { InfraredSensor::InfraredSensor(const uint8_t pin) : _pin(pin) { for (uint16_t i = 0; i < _buffer.getBufferSize(); i++) update(); } void InfraredSensor::update(void) { _buffer.addValue(analogRead(_pin)); } float InfraredSensor::getDistance(void) const { const float voltage = _buffer.getAverageValue() * SUPPLY_VOLTAGE / 1024.0; return VOLTS_PER_CM / voltage; } } }

The constructor uses a member initialization list to initialize the _pin variable and then it initializes the ring buffer, so we have some data available right from the start. update reads the sensor’s current output using Arduino’s analogRead function and adds it to the ring buffer. Then we use a simple formula to calculate the distance to the nearest object in getDistance.

Isn’t this code beautiful? It’s mostly because we’ve separated concerns and because we could keep all methods very small. Also RingBuffer is completely independent of all other classes and even of all Arduino stuff. This way you can easily test it and you can even use it in projects that aren’t related to the Arduino. Minimizing dependencies is always a good idea and using classes helps a lot. The same is true for generic programming, because it helps us to decouple algorithms (for example, calculating an average value) from concrete data types.

Building a PDC Application The only thing missing is the PDC’s business logic, but that’s really a piece of cake now. We have already implemented all major classes and in the illustration you can see a class diagram of our final product. Only the ParkDistanceControl class is missing and here is its interface:

PragPub April 2011 17 #include "infrared_sensor.h" #include "speaker.h" using namespace arduino::sensors; using namespace arduino::actuators; namespace arduino { class ParkDistanceControl { private: InfraredSensor _ir_sensor; Speaker _speaker; float _mounting_gap; public: static const float MIN_DISTANCE = 8.0; static const float MAX_DISTANCE = 80.0; ParkDistanceControl( const InfraredSensor& ir_sensor, const Speaker& speaker, const float mounting_gap = 0.0) : _ir_sensor(ir_sensor), _speaker(speaker), _mounting_gap(mounting_gap) {} void check(void); }; }

As shown in the class diagram this class uses an InfraredSensor object and an instance of the Speaker class. In addition it stores a mounting gap. This is necessary, because when calculating the distance to the nearest object you have to take into account that the sensor usually isn’t mounted directly to the car’s surface.

The class’s constructor only initializes all data members, so we could implement it in the class definition. With the check method you can check the PDC’s current state, and its implementation looks like this:

PragPub April 2011 18 #include #include "pdc.h" namespace arduino { void ParkDistanceControl::check(void) { _ir_sensor.update(); const float distance = _ir_sensor.getDistance() - _mounting_gap; if (distance <= MIN_DISTANCE) { Serial.println("Too close!"); _speaker.beep(); } else if (distance >= MAX_DISTANCE) { Serial.println("OK."); } else { Serial.print(distance); Serial.println(" cm"); } } }

No big surprises here: we update the infrared sensor and then we calculate the distance to the nearest object. Then we check if the distance is less than the minimum distance we allow. If yes, we print an appropriate message to the serial port for debugging purposes and we make our speaker beep. If the distance is greater than the sensor’s range, we print “OK” to the serial port, and in the remaining case we print the current distance. Finally, we create a minimalistic Arduino sketch for our project:

#include #include "pdc.h" const uint16_t BAUD_RATE = 57600; const uint8_t IR_SENSOR_PIN = A0; const uint8_t SPEAKER_PIN = 13; const float MOUNTING_GAP = 3.0; arduino::ParkDistanceControl pdc( InfraredSensor(IR_SENSOR_PIN), Speaker(SPEAKER_PIN), MOUNTING_GAP ); void setup(void) { Serial.begin(BAUD_RATE); } void loop(void) { pdc.check(); delay(50); }

We initialize a global ParkDistanceControl object and pass it an InfraredSensor instance, a Speaker object, and a mounting gap. The setup function only initializes the serial port, and in loop we check the PDC’s state every 50 milliseconds. We’re done! You can use the following Makefile to build, upload, and monitor the PDC:

PragPub April 2011 19 ARD_REV = 22 ARD_HOME = /Applications/Arduino.app/Contents/Resources/Java AVR_HOME = $(ARD_HOME)/hardware/tools/avr ARD_BIN = $(AVR_HOME)/bin AVRDUDE = $(ARD_BIN)/avrdude AVRDUDE_CONF = $(AVR_HOME)/etc/avrdude.conf PROGRAMMER = stk500v1 MON_CMD = screen MON_SPEED = 57600 PORT = /dev/tty.usbmodemfa141 BOARD = uno LIB_DIRS = $(addprefix $(ARD_HOME)/libraries/, $(LIBS)) include ../Makefile.master

The Makefile automatically compiles all files ending with pde, c, and cpp (it currently ignores files ending with cc). While the serial monitor is running play with your hands in front of the sensor and see how the output changes.

What About Performance? You might wonder if it’s appropriate to build complete class hierarchies for this kind of simple projects. From my experience it is, because reusing classes such as RingBuffer helps to reduce programming and debugging time tremendously. Also, a clean interface design makes it much easier to replace hardware components. On top of that, proper C++ code does not cost as much as you might think, because modern compilers optimize their output massively. Most of the features you’ve seen in this article have no performance or memory overhead at all and many even help to reduce your program’s size.

The article’s code repository [U8] contains a classless PDC implementation in a single file. It is as simple as possible and does the same as our object-oriented version. It needs 5,690 bytes while the object-oriented version needs 6,646 bytes. That’s a small overhead, especially taking into account that it’s usually much easier to refactor and optimize the object-oriented version. Interestingly, the code size is 6,756 bytes when I use the IDE to build the project. Obviously, the IDE uses different settings for the compiler and the linker, which leads to a final important issue: portability. If you’re planning to release your project to the public you should keep in mind that people will expect that your project works with the Arduino IDE. To achieve this you only have to follow a few conventions: your project’s main folder has to have the same name as your pde file (in our case it’s park_distance_control. All files have to be in the same directory, so you cannot put header files into a separate include folder, for example. Don’t use a cpp file that has the same name as your pde file. In our case you should not have a file named park_distance_control.cpp, for example. If you follow these rules, your project should run fine with the IDE and your Makefile. All in all I think it’s well worthwhile to treat every Arduino project as a serious software development project. Just because the code base might be small, that doesn’t mean it has to be sloppy.

PragPub April 2011 20 Of course, there are still plenty of interesting and advanced techniques left. We did not talk about inheritance or unit testing, for example. Maybe we will deal with some of these issues in a future article!

About the Author

Maik Schmidt is the author of Arduino: A Quick-Start Guide [U9]. He has worked as a software developer for more than fifteen years, creating solutions for large enterprises. He frequently writes book reviews and articles and is also the author of Enterprise Recipes with Ruby and Rails [U10] and Enterprise Integration with Ruby [U11].

Send the author your feedback [U12] or discuss the article in the magazine forum [U13].

External resources referenced in this article:

[U1] http://www.gnu.org/software/make/

[U2] http://bleaklow.com/2010/06/04/a_makefile_for_arduino_sketches.html

[U3] https://github.com/maik/pragpub/tree/master/hacking_arduino/part1

[U4] http://proctools.sourceforge.net/

[U5] http://www.adafruit.com/index.php?main_page=product_info&cPath=35&products_id=160

[U6] http://sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y0a21yk_e.pdf

[U7] http://www.australianrobotics.com.au/?q=node/30

[U8] https://github.com/maik/pragpub/blob/master/hacking_arduino/part2/pdc/pdc.pde

[U9] http://pragprog.com/refer/pragpub22/titles/msard/arduino

[U10] http://pragprog.com/refer/pragpub22/titles/msenr/enterprise-recipes-with-ruby-and-rails

[U11] http://pragprog.com/refer/pragpub22/titles/fr_eir/enterprise-integration-with-ruby

[U12] mailto:[email protected]?subject=Arduino

[U13] http://forums.pragprog.com/forums/134

PragPub April 2011 21 Create your Own Arduino IDE Work the Way You Want to Work Crafting your own IDE is eminently doable but there are some hidden gotchas to avoid. Here is one a case study on how you might go about it, along with by Maik Schmidt some general advice for those aiming to set up a serious work environment for Arduino development. If you’re going to do serious Arduino development, you may want to work in an environment more like your day job. Here Maik shows how to set up your Case Study: Using Vim for Arduino Development own IDE. A popular editor among software developers is Vim [U1], and for Vim users a Makefile is nearly all that’s needed to start professional Arduino development. Vim comes with a built-in make command that invokes the Makefile in the current directory and parses its output. Vim creates a list of all warnings and errors in the compiler output and after make returns it automatically jumps to the position of the first problem. This is called QuickFix mode and you can learn more about it by reading Vim’s documentation (:h quickfix) or Matthieu Weber’s excellent article [U2].

Unfortunately, compiling the Arduino libraries produces a lot of warnings in QuickFix mode. Fortunately, you can safely ignore them. To make these warnings go away, you can add a pattern to Vim’s errorformat variable. The best way to do this is with an autocommand that is invoked automatically whenever you open a new Arduino file. So add the following to your ~/.vimrc file (you have to adjust the path to the IDE’s installation directory accordingly):

autocmd Filetype arduino set errorformat^=\%-G%.%#/path/to/Arduino/IDE/%.%#

This will ignore all warnings and errors that are produced when compiling one of the Arduino’s system libraries. But how does Vim know that a certain file is an Arduino file? Arduino files often have the extension pde, but they can be h or cpp files as well. So the best way to tell Vim that a file belongs to an Arduino project is to put this information into the file itself using a mode line. Mode lines are special comments containing Vim directives. They must be the first or last lines of a file. You enable the modelines feature by adding the command set modelines to your ~/.vimrc file (be careful: some people think that the mode lines feature is a potential security risk!). Then add the following comment to the end of all your project’s files:

// vim:ft=arduino

Now Vim will treat all your files as Arduino files and the only thing missing is proper syntax coloring. Fortunately, Johannes Hoff has created a Vim syntax file already [U3]. You only have to copy it to your ~/.vim/syntax directory.

PragPub April 2011 22 Of course, you can add as many helpful commands as you like, but at this point you have turned Vim into a full-blown Arduino IDE.

More IDE Alternatives Every advanced text editor supports Makefiles, so with the techniques you’ve learned in this article you can easily turn GNU Emacs [U4], for example, into a perfect Arduino IDE.

For some editors, like Textmate [U5], you can even get ready-made plugins. These plugins usually emulate the original IDE’s features; that is, they add a special Arduino menu where you can choose your board’s type and your serial port. This certainly sounds useful, but unfortunately most plugins do not work very well in practice. Their biggest problem is that they are often tied to certain versions of the Arduino environment. So if you need a feature of the most recent version, for example, you’re stuck. The same is true for new hardware releases. If the plugin is not updated for a new Arduino board, you cannot use it. Maintenance problems get even worse with “real” IDEs such as Apple’s Xcode. Creating templates for such products often is a major undertaking, so you can only find a few attempts on the Internet and at the moment none of them works with the most recent versions of Arduino and Xcode. All in all I strongly suggest that you use the most minimalistic approach; that is, use a Makefile and integrate it into your favorite text editor. This way you have at least a chance to respond to changes in the Arduino environment.

About the Author

Maik Schmidt is the author of Arduino: A Quick-Start Guide [U6]. He has worked as a software developer for more than fifteen years, creating solutions for large enterprises. He frequently writes book reviews and articles and is also the author of Enterprise Recipes with Ruby and Rails [U7] and Enterprise Integration with Ruby [U8].

Send the author your feedback [U9] or discuss the article in the magazine forum [U10].

External resources referenced in this article:

[U1] http://www.vim.org

[U2] http://users.jyu.fi/~mweber/blog/Informatique/arduino_vim.html

[U3] http://www.vim.org/scripts/script.php?script_id=2654

[U4] http://www.gnu.org/software/emacs/

[U5] http://macromates.com/

[U6] http://pragprog.com/refer/pragpub22/titles/msard/arduino

[U7] http://pragprog.com/refer/pragpub22/titles/msenr/enterprise-recipes-with-ruby-and-rails

[U8] http://pragprog.com/refer/pragpub22/titles/fr_eir/enterprise-integration-with-ruby

[U9] mailto:[email protected]?subject=Arduino

[U10] http://forums.pragprog.com/forums/134

PragPub April 2011 23 Testing Arduino Code An Everyday JRuby Adventure This article is the latest in my series on everyday JRuby. But it’s also an exploration in bringing serious software development tools to the Arduino. by Ian Dees People are using JRuby for amazing things worldwide. They’re also using it at

Ian brings the testing power of the Ruby-based smaller scales to make their day-to-day work a little easier. This series is a Cucumber testing library to the Arduino. journey through everyday situations where JRuby comes in handy.

In the previous installment [U1], we implemented the Six Degrees of Kevin Bacon game using a graph database. We then packaged it up for easy deployment to machines that don’t have Ruby installed. Today, we’ll use the Ruby-based Cucumber testing library to do a quick smoke test of an Arduino-based project. The technique will work in several different Ruby implementations; using JRuby here will give us an excuse to talk about calling into a Java library from Ruby.

The Hardware The hardware we’ll be testing is the Mood Hat, a little demo I threw together last summer as an excuse to play with microcontrollers. It features the Lilypad

[U2], a washable Arduino-based circuit board that can be sewn to clothing.

The Mood Hat is a simple toy. It’s a baseball cap with five LEDs representing five different moods from furious to ecstatic. At any given time, one LED is lit. You press one of two buttons to advance to the next happier or angrier state. You can use nearly any cheap consumer LEDs and pushbuttons for this; I bought a handful of tiny ones from Sparkfun that are designed to go with the Lilypad.

PragPub April 2011 24 Construction is simple. First, we’ll wire up the five LEDs to pins 6 through 10 on the Lilypad. For each pin, connect a 1K resistor to the pin, then connect the positive terminal of an LED to the other side of the resistor. Wire the negative terminal of the LED to the ground pin (marked as - on the board).

Now, we’ll hook up the pushbuttons to pins 2 and 3. Connect each button between its corresponding input pin and ground. When the wearer presses a button, the voltage read at the pin will drop to near zero. But you’ll need something to keep the voltage high when the button isn’t being pressed. Connect a small resistor, something on the order of 2.2K, between each output pin and the supply pin (marked as + on the board).

That’s it for the hardware—on to the tests!

The Tests

We’re going to write a series of tests using the Cucumber test framework [U3]. Each test will drive the hardware by sending commands to it over the board’s built-in serial interface.

The Protocol We’ll define a simple set of single-character commands we can send from our test script to the Mood Hat over the serial port:

? Ask for the current mood, from 0 (furious) to 4 (ecstatic). + or - Increase or decrease happiness by one notch. 0 ... 4 Set the current mood. Those are all the commands we need to drive the hardware during testing. We’ll need to implement them in both the tests and in the firmware. Let’s start with the tests.

The Feature Here’s what one piece of a Cucumber test might look like:

PragPub April 2011 25 Given I am happy When I increase my happiness Then I should be ecstatic

This wording is going to get really old if we have to repeat it for every combination of starting state and button push. Let’s take advantage of Cucumber’s ability to define several steps in a single ASCII art table. Here’s the full Cucumber test, which should go in features/mood_hat.feature in your project directory:

Feature: Mood hat In order to get my feelings across As a passionate person I want to display my mood on my hat Scenario Outline: Changing mood Given I am When I my happiness Then I should be Examples: | feeling_now | change | feeling_next | | furious | increase | unhappy | | furious | decrease | furious | | unhappy | increase | neutral | | unhappy | decrease | furious | | neutral | increase | happy | | neutral | decrease | unhappy | | happy | increase | ecstatic | | happy | decrease | neutral | | ecstatic | increase | ecstatic | | ecstatic | decrease | happy |

Go ahead and install Cucumber, then run what you’ve got so far:

$ jruby -S gem install cucumber rspec-expectations $ jruby -S cucumber features

You should see a copy of the test, plus a list of missing step definitions:

... 10 scenarios (10 undefined) 30 steps (30 undefined) 0m1.360s You can implement step definitions for undefined steps with these snippets: Given /^I am furious$/ do pending # express the regexp above with the code you wish you had end When /^I increase my happiness$/ do pending # express the regexp above with the code you wish you had end Then /^I should be unhappy$/ do pending # express the regexp above with the code you wish you had end ...

For each line in the feature description, Cucumber expects to find a chunk of code implementing that particular test step. Since we haven’t defined any steps yet, Cucumber has supplied a template for us. Let’s create some step definitions based on the template.

PragPub April 2011 26 Step Definitions Cut and paste the first three empty step definitions into a new file called features/step_definitions/mood_hat_steps.rb. Adjust them to contain the following code:

Given /^I am (.+)$/ do |mood| @port.putc int_for(mood).to_s end When /^I ([^ ]+) my happiness$/ do |change| char = (change == 'increase') ? '+' : '-' @port.putc char end Then /^I should be (.+)$/ do |mood| @port.putc '?' @port.getc.to_i.should == int_for(mood) end

Since each test step matches one of these three regular expressions, these definitions are all we need. The @port variable is an instance of the SerialPort class (more on that in a moment). We need to create this variable before the first test runs; features/support/env.rb is the place to put this kind of initialization code:

$: << File.dirname(__FILE__) + '/../../lib' require 'serialport' port = SerialPort.new ENV['MOOD_HAT'], 9600, 8, 1, SerialPort::NONE port.read_timeout = 1000 port.putc('?') until (port.getc =~ /\d/ rescue nil) at_exit { port.close }

That code opens the serial port and keeps trying to contact the Mood Hat until it receives a reply. How to we make the connection visible to our test code? Cucumber provides the World method for this purpose. The following code (also in env.rb) will define a MoodWorld class to make the port available to Cucumber:

class MoodWorld def initialize(port) @port = port end # ... more methods here ... end World { MoodWorld.new(port) }

The MoodWorld class is also a good place for helper methods, like the int_for method that converts the names of emotions into numbers we can send over the port:

Emotions = %w(furious unhappy neutral happy ecstatic) def int_for(emotion) Emotions.index emotion end

Now, on to the SerialPort class.

Supporting Code In regular Ruby, we’d install a gem called serialport to provide the SerialPort class. That gem has C code in it, though. While some C-based gems are compatible with JRuby, serialport isn’t one of them.

PragPub April 2011 27 The good news is that we only need a tiny subset of serialport’s functionality. We can easily write a JRuby-specific file that provides this subset. If you’re following along with regular Ruby, you can just do a gem install serialport and skip to the next section.

Java in Your Serial To access the serial port from the JVM, we’re going to use the JavaComm API. Although this is an official Java API, it doesn’t actually ship with the JVM. Fortunately, there’s an open source implementation called RXTX [U4].

To use RXTX in this project, download the latest prerelease version from the download page. Extract the zip file. You’ll need two files from this archive: a platform-specific library (e.g., rxtxSerial.dll on Windows) and the cross-platform file RXTXComm.jar. Put the platform-specific file in your project directory. Create a lib subdirectory and put the jar file into it.

Serial With Class Now we need to define the SerialPort class. Create a new file called lib/serialport.rb, and place the following code at the top of it:

require 'java' require 'RXTXcomm.jar' java_import('gnu.io.CommPortIdentifier') java_import('gnu.io.SerialPort') { 'JSerialPort' }

This brings the RXTX classes we’re using into the Ruby namespace, so we can use them just like any Ruby class. We don’t want a name collision between the SerialPort Java class defined in RXTX and the one we’ll be writing in Ruby. By providing the name JSerialPort in the block passed to java_import, we prevent a clash. Now, sketch the outline of the new class:

class SerialPort attr_accessor :read_timeout NONE = JSerialPort::PARITY_NONE # ... methods go here ... end

First, we’ve defined the read_timeout= method, one of the three SerialPort methods our test script uses. Next, we’ve added a constant that needs to be visible from outside the class. Now, let’s add a couple of methods to open and close the serial port:

def initialize name, baud, data, stop, parity port_id = CommPortIdentifier.get_port_identifier name data = JSerialPort.const_get "DATABITS_#{data}" stop = JSerialPort.const_get "STOPBITS_#{stop}" @port = port_id.open 'JRuby', 500 @port.set_serial_port_params baud, data, stop, parity @in = @port.input_stream @out = @port.output_stream end def close @port.close end

PragPub April 2011 28 There’s not much going on here. We just do a little translation from the Ruby API to the Java one, then set up the serial port. Now, add the putc method, which sends a single character:

def putc(char) @out.write char[0, 1].to_java_bytes end

This method is simple; we just take the first character of the string passed to us, convert it to a Java byte array, and tell the underlying output stream to send it. getc is the other half of the equation:

def getc if @read_timeout deadline = Time.now + @read_timeout / 1000.0 sleep 0.1 until @in.available > 0 || Time.now > deadline end @in.to_io.read(@in.available)[-1, 1] || '' end

If this port has a read timeout defined, we want to wait for that amount of time until data becomes available. Otherwise, we proceed straight to the read (which will block indefinitely). To do the actual read, we could allocate a fixed-size Java byte array, pass it to the underlying input stream, then copy it into a Ruby string. That’d be a lot of boilerplate, though. Instead, we use a method provided by JRuby called to_io. This presents the Java stream as a Ruby IO object, which just uses plain Ruby strings. We read all the bytes available, then return the last one. That’s all the serial support we need to get this test code running. We can finally turn our attention to the firmware.

The Firmware You can write the Mood Hat’s firmware using the official Arduino IDE, or you can use the techniques Maik Schmidt describes in this issue of PragPub. Before you start, you’ll need to install the open source Bounce library [U5] for reading button states accurately. First, create a few definitions you’ll use elsewhere in the code:

#include #define NUM_MOODS 5 #define NEUTRAL ((NUM_MOODS - 1) / 2) #define UP '+' #define DOWN '-' #define QUERY '?' #define NONE -1 int ledPins[NUM_MOODS] = {6, 7, 8, 9, 10}; int heartbeatPin = 13; int upPin = 2; int downPin = 3; Bounce upButton (upPin, 100); Bounce downButton(downPin, 100); int mood = NEUTRAL;

When the firmware loads, we need to open up serial communications and designate our input and output pins. This code goes into a setup function, which will get called automatically after the hardware is done powering up:

PragPub April 2011 29 void setup() { for (int i = 0; i < NUM_MOODS; ++i) { pinMode(ledPins[i], OUTPUT); } pinMode(upPin, INPUT); pinMode(downPin, INPUT); Serial.begin(9600); setMood(NEUTRAL); }

Typical Arduino practice is to write a short, fast loop function. The development kit will generate code that calls our loop repeatedly.

This project doesn’t need to do much work on each pass. We’ll just check the physical buttons and serial port for incoming commands, then change the mood accordingly:

void loop() { upButton.update(); downButton.update(); int button = (upButton.fallingEdge() ? UP : (downButton.fallingEdge() ? DOWN : NONE)); int serial = (Serial.available() > 0 ? Serial.read() : NONE); int event = (button != NONE ? button : serial); switch (event) { case UP: setMood(mood + 1); break; case DOWN: setMood(mood - 1); break; case QUERY: Serial.print('0' + mood, BYTE); break; default: setMood(event - '0'); break; } digitalWrite(heartbeatPin, HIGH); delay(50); digitalWrite(heartbeatPin, LOW); delay(50); }

Let’s walk through this step by step. First, we check both of our input pins for a signal falling to near zero—such a condition would indicate a button press. We also check the serial port for incoming commands. If we see both buttons and serial characters, buttons take precedence. Next, we change the current state based on what the incoming request was. Finally, we flash the on-board LED to give an indication that the firmware is still running.

The implementation of setMood just needs to do a little range checking and activate the appropriate LED:

PragPub April 2011 30 void setMood(int newMood) { if (newMood < 0 || newMood >= NUM_MOODS) { return; } digitalWrite(ledPins[mood], LOW); mood = newMood; digitalWrite(ledPins[mood], HIGH); }

With this code loaded on the device, try rerunning your tests. You’ll need to set the MOOD_HAT environment variable to your Lilypad’s serial port, which might be COM3 on Windows or /dev/tty-usbserial-... on a Mac:

$ export MOOD_HAT=/dev/tty-usbserial-... $ jruby -S cucumber features

Now, bask in the green glow of a stream of passing tests on your monitor.

Wrapping Up What is it that we’ve done here? Well, I wrote this test suite for fun, just to see what kind of hoops one would have to go through to test an embedded device from Ruby. So, mission accomplished. But despite my best intentions to keep this test suite purely theoretical, it ended up having practical value. Before all the LEDs were wired up, I wrote a temporary user interface that made just one LED brighter or dimmer to indicate the mood. Later, I could freely change the user interface and retest the underlying logic. The tests were also a good place to explore different edge cases for the interface. For example: should the moods wrap around at the extremes, so that furious is one step happier than ecstatic? Definitely not, and this became clear as the different examples took shape. Finally, there’s the more obvious benefit of using Cucumber to drive the design: the project now has a basic smoke test that can quickly be run against the firmware. As you write your own variant Mood Hat that’s way better than mine, you’ll be able to refactor fearlessly. When you do, please drop by the PragPub forums [U6] and show us what you’ve built.

The source code for this project is available here [U7]. You can see a video of

the tests in action here [U8]. Happy hacking!

Special thanks to Maik Schmidt for reviewing this article.

About the Author By day, Ian Dees slings code, tests, and puns at a Portland-area test equipment manufacturer. By night, he dons a cape and keeps watch as Sidekick Man, protecting the city from closet monsters. Ian is the author of Scripted GUI Testing With Ruby [U9] and co-author of the upcoming Using JRuby [U10].

Send the author your feedback [U11] or discuss the article in the magazine forum [U12].

External resources referenced in this article:

[U1] http://pragprog.com/magazines/2011-01/everyday-jruby

[U2] http://www.arduino.cc/en/Main/ArduinoBoardLilyPad

[U3] http://cukes.info

[U4] http://rxtx.qbang.org

PragPub April 2011 31 [U5] http://www.arduino.cc/playground/Code/Bounce

[U6] http://forums.pragprog.com/forums/134

[U7] https://github.com/undees/pragpub

[U8] http://www.youtube.com/watch?v=YLABikl74J4

[U9] http://pragprog.com/refer/pragpub22/titles/idgtr

[U10] http://pragprog.com/refer/pragpub22/titles/jruby/using-jruby

[U11] mailto:[email protected]?subject=jruby

[U12] http://forums.pragprog.com/forums/134

PragPub April 2011 32 Test Abstraction Eight Techniques to Improve Your Tests In this article we illustrate several useful techniques you can use to improve your tests by increasing their level of abstraction. by Jeff Langr, Tim Ottinger Expressive Tests Use the techniques outlined in this article to sniff out problems and improve tests by increasing their When doing TDD, the tests you create are the entry point into your system. level of abstraction. Tests are where the coding starts. They are also how you drive changes into the system, whether those changes represent new features or defects that you must fix. When you’ve taken the care to craft your tests to act as “specifications by example,” you can learn about system behaviors and class capabilities from reading the tests. For those who haven’t ingrained the discipline of TDD, the natural inclination is to find reasons not to write tests—to those developers, TDD is just more work. We hear many excuses: • “This code was in a larger method that was already tested. All I did was move it to a new class, and there’s no way I could have broken it.” • “The whole feature is covered by an acceptance test.” • “The method is so simple I can look at it and know it’s not broken.” • “I don’t have time.” • “Our coverage is good enough.” “... So why do I need to write additional tests?” Why? First and foremost, because other developers will need to understand the code at some point down the road. They may need to change the behavior of the class, or they may want to reap the benefits of reuse and consume the class from other client code. Without tests, they’ll have to spend extra time digging through the code to fully understand its behavior. Describing your code with readable tests is an act of courtesy. It is also the mark of a professional who has moved out of the novice TDD phase—someone who is striving to craft better tests instead of seeking to avoid writing them.

Test Abstraction

In our PragPub article on abstraction [U1], we lightly touched on the topic of test abstraction—the idea that a test needs to clearly specify its intent. You may recall that we used Uncle Bob’s definition of abstraction: “Amplification of the essential, elimination of the irrelevant.” Let’s talk about some concepts and techniques for making your tests suitably abstract.

PragPub April 2011 33 Bill Wake’s Arrange-Act-Assert (AAA) pattern [U2] for test organization tells you to visually organize your tests—by grouping lines of code—around their core three steps: setup (“arrange”), execution (“act”), and verification (“assert”). For a test reader to easily understand the intent of a test, these three test steps must be distinct from each other.

Kent Beck’s rules for simple design (we have an Agile in a Flash card [U3] for that too) are the next things to consider. The second and third steps of the simple design rules are: 1. … 2. No code is duplicated 3. Code clearly expresses intent The rules are in priority order. Getting rid of duplication trumps code expressiveness. However, this ordering has been debated often, with some developers suggesting a reversal, and other developers suggesting that these two rules are roughly on equal footing.

With respect to tests, if you strive to eliminate duplication without considering expressiveness, you’re going to bury important concepts in setup methods. Sure, it’s usually easy to navigate to a setup method and then return to the test method, but that navigation represents extra “travel” on the part of the test reader. Eventually, unnecessary travel adds up to significant wasted time and wears a test reader down. It is especially unwelcome if the reader is only visiting the test because his or her most recent code change caused it to fail. Following is a test that exhibits some test smells, culled from a well-known open source effort. Let’s see what we can do to improve it.

The test testMessageKey isn’t terribly long but it’s not quickly digestible either. If it failed, how long would it take for you to understand why?

PragPub April 2011 34 public void testMessageKey() { HashMap params = new HashMap(); params.put("foo", "200"); // HashMap extraContext = new HashMap(); extraContext.put(ActionContext.PARAMETERS, params); // try { ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, extraContext); ValueStack stack = ActionContext.getContext().getValueStack(); ActionContext.setContext(new ActionContext(stack.getContext())); ActionContext.getContext().setLocale(Locale.US); proxy.execute(); assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors()); // Map> errors = ((ValidationAware) proxy.getAction()).getFieldErrors(); List fooErrors = errors.get("foo"); assertEquals(1, fooErrors.size()); // String errorMessage = fooErrors.get(0); assertNotNull(errorMessage); assertEquals("Foo Range Message", errorMessage); } catch (Exception e) { e.printStackTrace(); fail(); } }

So, what can we do to improve this?

Unnecessary Test Code If you’re running your test suite in an environment that suppresses stack traces on test failure, it may seem advantageous to have included the printStackTrace statement. But from the standpoint of cohesion, it’s not necessary and represents irrelevant clutter in your tests. A single JUnit test method should capture a single case, start to finish. Design the bulk of your tests as “happy path” cases that demonstrate useful functionality, blissfully ignoring any possible errors. When the system under test (SUT) throws an exception, JUnit catches it and reports a test failure. So you can remove extracurricular constructs, such as the try/catch block in testMessageKey.

Don’t waste too much time designing tests that provide volumes of information when they fail. Once you’ve gotten them to pass initially, they will almost always pass. If tests fail in a non-obvious way, it’s a simple matter to bolster them with helpful failure messages and then re-run them. Instead, make the message as brief and clear as possible.

Another piece of clutter is the assertNotNull statement near the end of the test. Such assertions are absolutely unnecessary when followed by a subsequent test that uses the same reference. In testMessageKey, the assertNotNull statement is immediately followed by assertEquals("Foo Range Message", errorMessage). If the reference is null, the subsequent assertion will make it perfectly clear. Run the test while it is failing and check the error message for yourself.

PragPub April 2011 35 Here’s the new code, with the try/catch block and unnecessary assertNotNull statement removed:

public void testMessageKey() { HashMap params = new HashMap(); params.put("foo", "200"); // HashMap extraContext = new HashMap(); extraContext.put(ActionContext.PARAMETERS, params); // ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, extraContext); ValueStack stack = ActionContext.getContext().getValueStack(); ActionContext.setContext(new ActionContext(stack.getContext())); ActionContext.getContext().setLocale(Locale.US); proxy.execute(); assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors()); // Map> errors = ((ValidationAware) proxy.getAction()).getFieldErrors(); List fooErrors = errors.get("foo"); assertEquals(1, fooErrors.size()); // String errorMessage = fooErrors.get(0); assertEquals("Foo Range Message", errorMessage); }

Missing Abstractions We want to quickly understand the core concepts of each test we read. Anywhere we find two or more lines used to express a single concept, there might be bloat that we can eliminate.

In testMessageKey, we see a common construct: verifying that a collection has only a single element, and then verifying the value of that single element:

List fooErrors = errors.get("foo"); assertEquals(1, fooErrors.size()); // String errorMessage = fooErrors.get(0); assertEquals("Foo Range Message", errorMessage);

A bit of refactoring and name-brainstorming can lead to a single-line abstraction (which might read even better in Hamcrest form):

assertSoleElementEquals("Foo Range Message", errors.get("foo"));

Our test is starting to trim down. We’re also starting to build a library of reusable functions which will help us reduce the amount of code application-wide.

PragPub April 2011 36 public void testMessageKey() { HashMap params = new HashMap(); params.put("foo", "200"); // HashMap extraContext = new HashMap(); extraContext.put(ActionContext.PARAMETERS, params); // ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, extraContext); ValueStack stack = ActionContext.getContext().getValueStack(); ActionContext.setContext(new ActionContext(stack.getContext())); ActionContext.getContext().setLocale(Locale.US); proxy.execute(); assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors()); // Map> errors = ((ValidationAware) proxy.getAction()).getFieldErrors(); assertSoleElementEquals("Foo Range Message", errors.get("foo")); }

Irrelevant Information In a well-abstracted test, every fact in the test is relevant to understanding the test. Take care not to include arbitrary values in a way that suggests relevance. In the statement:

params.put("foo", "200");

… the word “foo” is a standard metasyntactic variable indicating unimportance, but what’s the meaning of the value 200? Is it an HTTP status code? You have to spend time reading the rest of the test to see if 200 correlates with anything else. If you suspect it doesn’t, you can always change the value and see if the test still passes. You might be able to get away with passing the empty string or null:

params.put("foo", "");

If null or empty values don’t work, you can use a meaningful constant name:

params.put("foo", ARBITRARY_NUMERIC_VALUE);

or even pass a value that imparts the arbitrary meaning:

params.put("foo", "bar");

The unfortunate intertwining of “essential” and “irrelevant” code in a test requires the reader to do even more work to figure out what’s important. In our case, it turns out that 200 is indeed relevant. More on that later—for now we choose to leave the magic number in the code and revisit it when the tests are easier to follow.

Bloated Construction Our test dedicates its first four lines of code to a single relevant concept: constructing an “extra context” containing our single key/value pair of foo/200.

HashMap params = new HashMap(); params.put("foo", "200"); // HashMap extraContext = new HashMap(); extraContext.put(ActionContext.PARAMETERS, params);

PragPub April 2011 37 Elsewhere in the open source application containing testMessageKey, we found a handful of four-line chunks that were exactly the same—duplication!

Understanding testMessageKey does not require one to know that extra context is created by stuffing one map into another. You can introduce a single-line call to a new factory method and hide this detail without losing any useful information:

HashMap extraContext = createExtraContextWithParameters("foo", "200");

Our test is now a few lines shorter still:

public void testMessageKey() { HashMap extraContext = createExtraContextWithParameters("foo", "200"); // ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, extraContext); ValueStack stack = ActionContext.getContext().getValueStack(); ActionContext.setContext(new ActionContext(stack.getContext())); ActionContext.getContext().setLocale(Locale.US); proxy.execute(); assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors()); // Map> errors = ((ValidationAware) proxy.getAction()).getFieldErrors(); assertSoleElementEquals("Foo Range Message", errors.get("foo")); }

Sometimes new test helper methods are useful not only for testing but for production code as well! The “move method” refactoring can be used to relocate methods from test to production code, and some search-and-replace can help find all the places where the production code is simplified by the new method. Duplication is a major drain on developer productivity for any application. Eliminating the bloat of duplication improves your future development speed in these ways: • The improved abstraction level reduces comprehension time and thus also the time to maintain the tests and application. • Future changes to the steps required to construct the “extra context” can be made in one place, not dozens or more. • You can write new tests more rapidly, introducing a single line instead of having to find-copy-paste-and-alter another chunk of four lines.

Irrelevant Details in Test Specifying the Locale for the ActionContext appears to have nothing to do with the rest of the test. We can bury it in a construction method (createActionProxy in the example here), killing another bird with this same stone—it also removes some of the clutter required for ActionProxy construction.

PragPub April 2011 38 public void testMessageKey() { HashMap extraContext = createExtraContextWithParameters("foo", "200"); // ActionProxy proxy = createActionProxy( MockConfigurationProvider.VALIDATION_ACTION_NAME, extraContext); proxy.execute(); assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors()); // Map> errors = ((ValidationAware) proxy.getAction()).getFieldErrors(); assertSoleElementEquals("Foo Range Message", errors.get("foo")); }

As you can see, well-named extracted methods are a major key to cleaning up your tests. And once again, there’s some chance that you can find and eliminate similar code chunks in other tests nearby, or even in the SUT itself.

Multiple Assertions You can make the case for multiple assertions in one test method if a single behavior has multiple post-conditions that must hold true. However, additional assertions make it harder to comprehend the test at a glance, and decrease the amount of useful information that the test names can impart on their own. Multiple assertions can also be a code smell, suggesting violation of cohesion in the SUT. You can consider separating each of these post-conditions into a separate test. There is a minor downside: readers must now poke around to find all conditions that hold true for a particular behavior, and hope that the developer has named and organized these consistently. But you get better fault isolation (single reason to fail), as well as an opportunity to improve test names, if you split the tests:

public void testActionValidationReportsFieldErrors() { HashMap extraContext = createExtraContextWithParameters("foo", "200"); // ActionProxy proxy = createActionProxy( MockConfigurationProvider.VALIDATION_ACTION_NAME, extraContext); proxy.execute(); assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors()); } // public void testActionValidationAllowsMessageRetrievalByKey() { HashMap extraContext = createExtraContextWithParameters("foo", "200"); // ActionProxy proxy = createActionProxy( MockConfigurationProvider.VALIDATION_ACTION_NAME, extraContext); proxy.execute(); // // we could also eliminate this line of ugliness, replacing it // with a call to a local method named getFieldErrors. See the // next code section for the result. Map> errors = ((ValidationAware) proxy.getAction()).getFieldErrors(); assertSoleElementEquals("Foo Range Message", errors.get("foo")); }

PragPub April 2011 39 Test names are exceedingly important abstractions: they amplify the essential behaviors captured by a test case, and eliminate the contextual irrelevancy of how those behaviors are executed and verified.

Misleading Organization The resulting two tests are clear candidates for the idiomatic organization of AAA:

public void testActionValidationReportsFieldErrors() { HashMap extraContext = createExtraContextWithParameters("foo", "200"); ActionProxy proxy = createActionProxy( MockConfigurationProvider.VALIDATION_ACTION_NAME, extraContext); // proxy.execute(); // assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors()); } // public void testActionValidationAllowsMessageRetrievalByKey() { HashMap extraContext = createExtraContextWithParameters("foo", "200"); ActionProxy proxy = createActionProxy( MockConfigurationProvider.VALIDATION_ACTION_NAME, extraContext); // proxy.execute(); // // see previous code excerpt for how we got this single-line assertion assertSoleElementEquals("Foo Range Message", getFieldErrors().get("foo")); }

Since both tests contain common setup, you can consider creating a separate fixture around action validation. An isolated fixture would allow you to move the common setup into a common initialization method (setUp or @Before).

And there’s still room for a few additional tweaks. How do you know when you’re done with a test? One great way is to call over a neutral party and ask them to paraphrase the test. If they’re unable to clearly do so, you have work to do!

Implicit Meaning Now that these tests are split apart and easy to read, it’s pretty obvious that we’re missing something: It’s not at all clear why the key/value pair foo/200 generates a validation error! Unraveling this mystery requires you to read between the lines (aka blow time by digging around through other code or running a series of experiments).

The constant MockConfigurationProvider.VALIDATION_ACTION_NAME makes it obvious that a test double is in play somewhere, no doubt the arbitrator of whether or not validation passes. Unfortunately, the developer buried relevant test context in this test double. To fix the flaw, make the test double construction more explicit. Here’s a stab at a clearer test:

PragPub April 2011 40 static String INVALID_FOO_VALUE = "200"; // public void testActionValidationReportsFieldErrors() { ActionProxy proxy = createActionProxy( createExtraContextWithParameters("foo", "200")); proxy.injectValidator( createStubValidatorThatThrowsOnValue("200")); // proxy.execute(); // assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors()); } // private Validator createStubValidatorThatThrowsOnValue(String value) { Validator validator = mock(Validator.class); when(validator.validate(value).thenThrow(new ValidationException()); return validator; }

Your tests should be short and sweet, but it is more important to be clear than to be brief. Don’t let your passion for shortening tests push you to bury relevant meaning!

Conclusion Tests are documentation, or at least can be written as descriptive documents. Use the techniques outlined in this article to sniff out problems and improve tests by increasing their level of abstraction. Your coworkers will thank you, and the deciphering/debugging time you save may be your own.

About Jeff Jeff Langr has been happily building software for three decades. In addition to co-authoring Agile in a Flash [U4] with Tim, he’s written another couple books, Agile Java and Essential Java Style, contributed to Uncle Bob’s Clean Code, and written over 90 articles on software development. Jeff runs the consulting and training company Langr Software Solutions from Colorado Springs.

About Tim

Tim Ottinger is the other author of Agile in a Flash [U5], another contributor to Clean Code, a 30-year (plus) software developer, agile coach, trainer, consultant, incessant blogger, and incorrigible punster. He writes code. He likes it.

Send the authors your feedback [U6] or discuss the article in the magazine forum [U7].

External resources referenced in this article:

[U1] http://www.pragprog.com/magazines/2011-02/abstraction

[U2] http://agileinaflash.blogspot.com/2009/03/arrange-act-assert.html

[U3] http://agileinaflash.blogspot.com/2009/02/simple-design.html

[U4] http://www.pragprog.com/refer/pragpub22/titles/olag/Agile-in-a-flash

[U5] http://www.pragprog.com/refer/pragpub22/titles/olag/Agile-in-a-flash

[U6] mailto:[email protected]?subject=Agile-cards

[U7] http://forums.pragprog.com/forums/134

PragPub April 2011 41 When Did That Happen? The Most Famous Master’s Thesis in Despite the fact that he was responsible of one of the twentieth century’s History breakthrough achievements in digital networking, Claude Shannon is almost alone among tech heroes in being without a biographer. We do know this: he by Dan Wohlbruck was born on April 30, 1916, in Petoskey, Michigan—making his story apt for the April issue of PragPub. And we know the story of how he came to write Dan continues his series on events in computer the most famous Master’s thesis in history…. history with a look at the world-changing insight of Claude Shannon. From the corporate archives of the Bell Labs where he worked, we know that Shannon graduated from the University of Michigan in 1936 with a bachelor’s degree in mathematics and electrical engineering. He went on to MIT later that year to study under Vannevar Bush and to work with MIT’s Differential Analyzer.

The Differential Analyzer Vannevar Bush himself deserves several pages in any computer history, having founded Raytheon, anticipated the Web with his prescient Memex concept, directed scientific efforts during World War II for the White House, including the Manhattan Project, and built an early analog computer. That computer, the Differential Analyzer, is what concerns us here. Bush was at the time an associate professor at MIT and was working on the transient problem with electrical power networks. He became interested in analog computational devices because evaluating transients required significant calculations. As a result, by 1931 he and his students at MIT had completed the development of his Differential Analyzer. The Analyzer, a mechanical analog computing device that could solve ordinary differential equations up to the sixth order, was so large that it occupied a full room. Before attempting the solution of a particular differential equation, the machine’s circuits had to be redesigned and rewired. Despite its difficulties, the Analyzer was a tool that was much in demand by students and professors at MIT. About this time, Claude Shannon arrived at MIT and, like college students of every generation, he needed money. He noticed a job posting on a bulletin board on campus announcing that someone was needed to work with visiting scientists and wire the Differential Analyzer. Shannon applied for and was given the job. While helping a visiting researcher wire the Analyzer, Shannon had an idea. He honed the idea into a master’s thesis titled “A Symbolic Analysis of Relay and Switching Circuits.” That thesis has been called the most important and the most famous master’s thesis ever written. What follows describes Shannon’s idea and how it led to today’s digital networks.

PragPub April 2011 42 Shannon helped scientists set up their problems by rearranging the Analyzer so that the machine’s movements would be synchronized with the mathematical equations. While helping a visiting researcher wire the Analyzer, Shannon had an idea. Dr. Charles Vest, an MIT researcher, recalled Shannon telling him how one night it just dawned on Shannon that the circuits he was building were like the Boolean logic he had studied while he was at Michigan. Shannon thought that switches could be combined in circuits in such a manner as to carry out symbolic logic operations. He honed the idea, this marrying of electric circuits with symbolic logic, into a Master’s thesis titled “A Symbolic Analysis of Relay and Switching Circuits.” At the urging of Dr. Bush, it was published in 1938 and honored with the Alfred Noble American Institute of American Engineers Award in 1940. That thesis has been called the most important and the most famous Master’s thesis ever written. So what was so special about this thesis?

Shannon’s Thesis Shannon introduces his thesis thus: “The method of attack on these problems may be described briefly as follows: any circuit is represented by a set of equations, the terms of the equations corresponding to the various relays and switches in the circuit. A calculus is developed for manipulating these equations by simple mathematical processes, most of which are similar to ordinary algebraic algorithms. This calculus is shown to be exactly analogous to the calculus of propositions used in the symbolic study of logic.” At the time, to bother with equations just to create a circuit design would have been seen as innovative to the point of eccentricity. Before Shannon’s treatise, circuit design was an art, not a science. Shannon’s part-time job of synchronizing the electrical and mechanical parts of the Analyzer taught him that there wasn’t much design in the process, just a lot of trial and error. First, he would wire a circuit, energize it, and discover that it didn’t work as intended. Then he would follow the wires, testing each relay, to find where he had gone wrong. One imagines that one night after a particularly tedious circuit repair, Shannon was driven to find a way to make circuit design a science. Shannon begins his argument with the following postulate: “[A]t any given time the circuit between any two terminals must be either open (infinite impedance) or closed (zero impedance). Let us associate a symbol Xab or simply X, with the terminals a and b. This variable, a function of time, will be called the hinderance [sic] of the two-terminal circuit a-b. The symbol 0 (zero) will be used to represent the hinderance of a closed circuit, and the symbol 1 (unity) to represent the hinderance of an open circuit. Thus when the circuit a-b is open Xab equals 1 and when closed Xab equals 0.” Shannon went on to define the plus sign to mean the series connection of two terminal circuits whose hinderances are added together. He also defined the product of two hinderances to mean the hinderance of the circuit formed by connecting the two circuits in parallel. After these two definitions, Shannon

PragPub April 2011 43 said, “This choice of symbols makes the manipulation of hinderances very similar to ordinary numerical algebra.” With his definitions, postulates, and theorems, Shannon proceeded to use Boolean algebra to design real electrical circuits. In short, he moved the design process from art to science. At the conclusion of his thesis, Shannon gave examples of several circuits he had designed with his algebra. One of the examples was a circuit that added two numbers. Shannon called the example an electric adder to the base two and he explained that although any numbering system could be used, the circuit would be greatly simplified when each digit was either a 0 or a 1. And with just 0s and 1s, the digital circuit was born.

Legacy Not surprisingly, Shannon was awarded a Master’s degree for his work, which he followed with a PhD. He continued to build on his deep insight into the logic of computing for the rest of his career. He worked with the Army in World War II, and in 1946, he prepared a classified report titled, “Communication Theory of Secrecy Systems.” His greatest work came in 1948 when, with little fanfare, he published his seminal paper on information theory. But that’s another story altogether. Dr. Claude Elwood Shannon, the American mathematician and computer scientist whose theories laid the groundwork for the electronic communications networks that now lace the earth, died in February 2001 at his home in Medford, Mass. He was 84. But it all started in April 1916—and that’s when it happened.

About the Author Dan Wohlbruck has over 30 years of experience with computers, with over 25 years of business and project management experience in the life and health insurance industry. He has written articles for a variety of trade magazines and websites. He is currently hard at work on a book on the history of data processing.

Send the author your feedback [U1] or discuss the article in the magazine forum [U2].

External resources referenced in this article:

[U1] mailto:[email protected]?subject=Shannon

[U2] http://forums.pragprog.com/forums/134

PragPub April 2011 44 The Quiz My Arduino Sudoku This month we present another Sudoku puzzle that uses letters instead of digits. In keeping with the theme of this issue, the nine letters are MYARDUINO. by Michael Swaine Simply fill in the empty cells with these nine unique letters in such a way that each row, column, and small square contains each of the nine letters exactly once.

A - - - - R Y - O

O - - - N D - - -

M U ------

- D N - - Y - - -

- - A - - - U - -

- - - O - - A I -

------Y I

- - - R D - - - A

N - O A - - - - R

Solution right here next issue.

Solution to Last Month’s Quiz To refresh your memory, here is last month’s puzzle: A certain club has just over four dozen members. It’s not what you’d call a social club. Most of the members are friends with only a few others. For example, Richard, Lincoln, Christine, Jack M., and Nikki are particularly lonely, as each has only two friends. And Paul is almost as lonely as the utterly friendless Sean and Neil, since he has just one friend, John L. Friendship, I should mention, is a reciprocal relation. If I’m your friend, you’re my friend. Substitute any other reciprocal relation if it makes the problem clearer to you. I won’t mind. We're friends, after all.

PragPub April 2011 45 Nobody else in the club has as many friends as Jay or Bill, who have eight each. Perhaps we should not be surprised that these two relatively gregarious members are friends with each other. And with Steve, who has seven friends. You could say that Bob has six friends and Martin has five, but only if you count Vincent, and Vincent isn’t a member. Forget I mentioned Vincent. Vincent is right out. It’s a cliquish club, this one. Some members are off in their own chilly little corner. If it weren’t for Andrew, all six of Peter, Paul, Lincoln , John L., Deval, and Dan would only have each other for friends. He’s their only link to all the rest. Well, all except Sean and Neil. There are also what you might call strings of friends. Jerry and Jack M. are remotely connected, because Jerry is friends with Young Brian, who is friends with Gary, who is friends with John H., who is friends with Sam, who is friends with Jay, who is friends with Pat, who is friends with Mitch, who is friends with John K., who is friends with Tom, who is friends with Chris, who is friends with Jack M.—still with me? A similar string connects Jan with Richard, running from Jan to Susana to Mary to James Richard to Mike to Bobby to Haley to Robert to Nathan and ultimately to Nathan’s friend Richard. Friendships in the club are fairly permanent, but thin. No four people are all friends with one another, but there are many mutually-friendly threesomes, like Beverly, Nikki, and Nathan. Some of these friendship triangles do overlap. The three-friend triangle of Butch, Old Brian, and Matt, for example, overlaps with the Old Brian-Matt-Dennis triangle, which shares Old Brian and Matt and which also overlaps with the Dennis-Jack D.-Mark triangle, which overlaps with the Mark-Scott-Terry triangle, which in turn overlaps with the Terry-Dave-Dennis triangle, which overlaps with… Well, this is getting a little complicated, with these friendship triangles that one can be a member of many of, if you follow me. I mean, Earl is a member of five such triangles and Doctor John is a member of three, although Rick is a member of only one. But I think you have enough information now. So if I tell you that Christine has exactly two friends, can you name them? That was the puzzle. The solution is to recognize that the club is the set of Governors of the 50 United States, and the friendship relationship means that their States are physically adjacent. With that, we can work out that Christine must be Christine Gregoire, the Governor of Washington. The States that border Washington are Oregon and Idaho, so her friends must be Butch Otter and John Kitzhaber. But we’re not done yet. The choices of names we’re given include one Butch, so that’s clear enough, but there’s a John K that could be Oregon Governor Kitzhaber or Ohio Governor John Kasich, so we have to dig a little deeper. Google tells us that John Kitzhaber is an M.D., so he’s Doctor John. A map of the relationships can be found in Figure 17 on page 15 of The Art of Computer Programming, Volume 4A by Donald Knuth.

PragPub April 2011 46 Calendar Author sightings, partner events, and other notable MIT is 150 years old this year, and they’re throwing a party! Well, a symposium happenings. [U1], really. If you happen to be in Cambridge April 11–12, you have an opportunity to see some computer pioneers, like Patrick Wiston, Ron Rivest, Butler Lampson, Rodney Brooks, and Tim Berners-Lee.

Author Appearances

Apr 5–7 Tutorial: “Coaching as a Two-Way Relationship,” and talk: “It’s the People; It’s Always the People” Johanna Rothman, author of Manage Your Project Portfolio [U2]: Increase Your Capacity and Finish More Projects, Manage It! [U3]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U4]: Secrets of Great Management QAI, QUEST 2011 [U5], Boston, MA

Apr 6 HTML5 Brian Hogan, the author of Web Design for Developers [U6] and HTML5 and CSS3 [U7] Orbitz headquarters, Chicago, IL

Apr 6–8 Keynote plus talks on JVM languages Venkat Subramaniam, the author of Practices of an Agile Developer [U8], Programming Groovy [U9], and Programming Scala [U10] 33degree [U11], Krakow, Poland

Apr 6–8 Speaking Chad Fowler, author of The Passionate Programmer [U12] Scottish Ruby Conference [U13], Edinburgh, Scotland

Apr 7 Charity tutorial Chad Fowler, author of The Passionate Programmer [U14] Scottish Ruby Conference [U15], Edinburgh, Scotland

Apr 9 “Introduction to Advanced Ruby” Brian Hogan, the author of Web Design for Developers [U16] and HTML5 and CSS3 [U17] Twin Cities Code Camp 10 [U18], Minneapolis, MN

Apr 9–10 “Advanced Media Manipulation with AV Foundation” Chris Adamson, author of iPhone SDK Development [U19] Voices That Matter: iPhone Developers Conference [U20], Seattle, WA

Apr 9–10 “Project and Community Management with Github” Andy Lester, author of Land the Tech Job You Love [U21] CodeConf [U22], San Francisco, CA

Apr 10 “Turning Passion Into Words—Tips, Tricks, and Tools for Aspiring Authors” Brian Hogan, the author of Web Design for Developers [U23] and HTML5 and CSS3 [U24] ?

Apr 10 “Getting Started with Elixir: Simple object orientation and charming on top of Erlang” José Valim, author of Crafting Rails Applications [U25] railscampPolska [U26], Wista, Poland

PragPub April 2011 47 Apr 10–14 “SQL Injection Myths and Fallacies,” “Models for Hierarchical Data with SQL and PHP,” “Scalable Architecture and Design for MySQL,” and “SQL Antipatterns: The Next Generation” Bill Karwin, author of SQL Antipatterns [U27]: Avoiding the Pitfalls of Database Programming COLLABORATE 11 [U28], Orlando , FL

Apr 11–13 Keynote (Tuesday 12) on “Deliberate Discovery and Programming Patterns” Dan North, co-author of The RSpec Book [U29] JAX London [U30], London, England

Apr 12 “Agile Testing and Test Management: Where Do They Fit?” Johanna Rothman, author of Manage Your Project Portfolio [U31]: Increase Your Capacity and Finish More Projects, Manage It! [U32]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U33]: Secrets of Great Management Software Quality User Group of New England [U34], Burlington, MA

Apr 13 “Java is from Mars, Ruby is from Venus” Paolo Perrotta, the author of Metaprogramming Ruby [U35] DevTank [U36], London, England

Apr 13 “Oniguruma—new regex engine in Ruby” Staffan Nøteberg, author of Pomodoro Technique Illustrated [U37] SHRUG [U38], Stockholm, Sweden

Apr 15 Keynote: “Thriving in a Competitive Marketplace” Johanna Rothman, author of Manage Your Project Portfolio [U39]: Increase Your Capacity and Finish More Projects, Manage It! [U40]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U41]: Secrets of Great Management GLSEC Conference [U42], Grand Rapids, MI

Apr 15–16 “Rediscovering Apprenticeship in the 21st Century” and “Grails: Bringing Radical Productivity to the JVM” Dave Klein, author of Grails: A Quick-Start Guide [U43] Southern California Software Symposium [U44], Los Angeles, CA

Apr 16 Keynote: “Thriving in a Competitive Marketplace” Johanna Rothman, author of Manage Your Project Portfolio [U45]: Increase Your Capacity and Finish More Projects, Manage It! [U46]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U47]: Secrets of Great Management GLSEC [U48], Grand Rapids, MI

Apr 16 “Overcoming Resistance to New Ideas/Breaking through the Brick Wall” Rachel Davies, co-author of Agile Coaching [U49] ACCU conference [U50], Oxford, UK

May 16 “Getting Started with Elixir: Simple object orientation and charming on top of Erlang” José Valim, author of Crafting Rails Applications [U51] BohConf [U52], Baltimore, MD

May 16–19 “SOLID Design Principles behind the Rails 3 Refactoring” José Valim, author of Crafting Rails Applications [U53] RailsConf 2011 [U54], Baltimore, MD

Apr 17 Talk on JVM Languages Venkat Subramaniam, the author of Practices of an Agile Developer [U55], Programming Groovy [U56], and Programming Scala [U57] Chennai Java User Group [U58], Chennai, India

Apr 18–21 “iPhone/iPad Programming” with Mike Clark Daniel Steinberg, co-author of iPad Programming [U59]: A Quick-Start Guide for iPhone Developers and author of Cocoa Programming [U60]: A Quick-Start Guide for Developers Pragmatic Studios [U61], Denver, CO

Apr 19–22 Keynote plus talks on Java, RichWeb and .NET related topics Venkat Subramaniam, the author of Practices of an Agile Developer [U62], Programming Groovy [U63], and Programming Scala [U64] Great Indian Developer Summit [U65], Bangalore, India

PragPub April 2011 48 Apr 20 “Overcoming Some Pitfalls of Transitioning to Agile” Johanna Rothman, author of Manage Your Project Portfolio [U66]: Increase Your Capacity and Finish More Projects, Manage It! [U67]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U68]: Secrets of Great Management ASP.net Boston User Group [U69], Waltham, MA

Apr 21 Panelist for “Is Agile Development for You?” Johanna Rothman, author of Manage Your Project Portfolio [U70]: Increase Your Capacity and Finish More Projects, Manage It! [U71]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U72]: Secrets of Great Management Boston Product Management Association [U73], Waltham, MA

Apr 21 “Using BDD in JavaScript from Ruby” Noel Rappin, author of Rails Test Prescriptions [U74] Red Dirt RubyConf [U75], Oklahoma City, OK

Apr 22–23 Speaking Chad Fowler, author of The Passionate Programmer [U76] RedDot RubyConf [U77], Singapore

Apr 22–23 Speaking Dave Thomas, Pragmatic Programmer RedDot Ruby Conference [U78], Singapore

Apr 25 Online and in-person class Sarah Allen, author of the forthcoming Test First Rails Blazing Cloud [U79], San Francisco, CA

Apr 26 MongoDB Administration Brendan McAdams, author of the forthcoming MongoDB: A Quick Start Guide Mongo Philly [U80], Philadelphia, PA

Apr 27 “REST with MarkLogic: Getting the Balance Right” Ron Hitchens, the author of Getting Started with XQuery [U81] MarkLogic User Conference [U82], San Francisco, CA

Apr 27 “Mary Poppins Meets the Matrix: Seven Programming Languages at the Cinema” Bruce Tate, the author of From Java to Ruby [U83] and Seven Languages in Seven Weeks [U84] Emerging Technologies for the Enterprise [U85], Philadelphia, PA

Apr 27–28 “Say Yes—or Say No? What to Do When Faced with the Impossible” Johanna Rothman, author of Manage Your Project Portfolio [U86]: Increase Your Capacity and Finish More Projects, Manage It! [U87]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U88]: Secrets of Great Management Emerging Tech Conference [U89], Philadelphia, PA

Apr 30 Talks on JVM languages, concurrency, and testing Venkat Subramaniam, the author of Practices of an Agile Developer [U90], Programming Groovy [U91], and Programming Scala [U92] No Fluff Just Stuff [U93], Reston, VA

May 5 2-day training course on MongoDB (mainly focused for DBAs and Ops staff) Brendan McAdams, author of the forthcoming MongoDB: A Quick Start Guide The Skills Matter eXchange [U94], London, England

May 5 “Agile Program Management: Is Large Agile an Oxymoron?” Johanna Rothman, author of Manage Your Project Portfolio [U95]: Increase Your Capacity and Finish More Projects, Manage It! [U96]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U97]: Secrets of Great Management Agile New England [U98], Waltham, MA

May 10–13 “Still No Silver Bullets” Esther Derby, coauthor of Behind Closed Doors [U99] and Agile Retrospectives [U100] XP2011 [U101], Madrid, Spain

May 10–13 Keynote Brian Marick, author of Programming Cocoa with Ruby [U102] and Everyday Scripting with Ruby [U103] XP2011 [U104], Madrid, Spain

PragPub April 2011 49 May 12 Park Bench Discuss: “Grumpy Old Agile Coaches” Rachel Davies, co-author of Agile Coaching [U105] XP2011 [U106], Madrid, Spain

May 13 hands-on coding workshop, “Extreme Startup,” with Robert Chatley Matt Wynne XP2011 [U107], Madrid, Spain

May 13 “Regex—the Future Programmer’s Best Friend” Staffan Nøteberg, author of Pomodoro Technique Illustrated [U108] GeeCON 2011 [U109], Krakow, Poland

May 13–15 “Hello! Groovy” Dave Klein, author of Grails: A Quick-Start Guide [U110] Gateway Software Symposium [U111], St. Louis, MO

May 15–20 Problem Solving Leadership Workshop with Jerry Weinberg and Esther Derby Johanna Rothman, author of Manage Your Project Portfolio [U112]: Increase Your Capacity and Finish More Projects, Manage It! [U113]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U114]: Secrets of Great Management Full. Email Johanna for slots in August.

May 16 “Building Bulletproof Views” John M. Athayde and Bruce Williams, who are writing The Rails View for the Pragmatic Bookshelf RailsConf Baltimore [U115], Baltimore, MD

May 16–19 “Test Your Legacy Code” Noel Rappin, author of Rails Test Prescriptions [U116] RailsConf [U117], Baltimore, MD

May 16–19 TBD Chad Fowler, author of The Passionate Programmer [U118] RailsConf [U119], Baltimore, MD

May 17 “The Holy Grail (of Databases)” Eric Redmond, author of the forthcoming Seven Databases in Seven Weeks RailsConf 2011 [U120], Baltimore, MD

May 18 “Regex—the Future Programmer’s Best Friend” Staffan Nøteberg, author of Pomodoro Technique Illustrated [U121] DevSum 2011 [U122], Stockholm, Sweden

May 28–29 TBD Chad Fowler, author of The Passionate Programmer [U123] RubyConf India [U124], Bangalore, India

May 28–29 “The Revenge of method_missing()” Paolo Perrotta, the author of Metaprogramming Ruby [U125] European Ruby Conference [U126], Berlin, Germany

May 28–29 “Writing your own Programming Language to Understand Ruby Better” José Valim, author of Crafting Rails Applications [U127] Euroko 2011 [U128], Berlin, Germany

Jun 5–6 Agile Architecture workshop with Rebecca Wirfs-Brock Johanna Rothman, author of Manage Your Project Portfolio [U129]: Increase Your Capacity and Finish More Projects, Manage It! [U130]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U131]: Secrets of Great Management Better Software Conference/Agile Development West [U132], Las Vegas, NV

Jun 6–10 Speaking Pragmatic Programmer Andy Hunt Better Software Conference/Agile Development West [U133], Las Vegas, NV

Jun 7 Agile Program Management for Agile and Non-Agile Projects Johanna Rothman, author of Manage Your Project Portfolio [U134]: Increase Your Capacity and Finish More Projects, Manage It! [U135]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U136]: Secrets of Great Management Better Software Conference/Agile Development West [U137], Las Vegas, NV

PragPub April 2011 50 Jun 7 TBD Brendan McAdams, author of the forthcoming MongoDB: A Quick Start Guide Mongo NYC [U138], Ney York, New York

Jun 7–8 “TDD in Clojure” Brian Marick, author of Programming Cocoa with Ruby [U139] and Everyday Scripting with Ruby [U140] agical [U141], Stockholm Sweden

Jun 8–9 “Faltering Projects: Getting Them Back on Track” Johanna Rothman, author of Manage Your Project Portfolio [U142]: Increase Your Capacity and Finish More Projects, Manage It! [U143]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U144]: Secrets of Great Management Better Software Conference/Agile Development West [U145], Las Vegas, NV

Jun 10–12 “Grails Deep Dive” and “Rediscovering Apprenticeship in the 21st Century” Dave Klein, author of Grails: A Quick-Start Guide [U146] Central Ohio Software Symposium [U147], Columbus, OH

Jun 13 Workshop: “Improving Trust in Teams” Rachel Davies, co-author of Agile Coaching [U148] SPA Conference [U149], London, England

Jun 16–18 Keynote Pragmatic Programmer Dave Thomas Ruby Kaigi [U150], Tokyo, Japan

Jun 19–23 “Making Geographically Distributed Agile Work,” “Agile Program Management,” and “Agile for Executives: A Half-Day Briefing” Johanna Rothman, author of Manage Your Project Portfolio [U151]: Increase Your Capacity and Finish More Projects, Manage It! [U152]: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors [U153]: Secrets of Great Management Ignite Outsourcing [U154], Tel Aviv, Israel

Jun 26–30 “SQL Injection Myths and Fallacies” Bill Karwin, author of SQL Antipatterns [U155]: Avoiding the Pitfalls of Database Programming KSCOPE 11 [U156], Long Beach CA

O’Reilly Events

Apr 11–14 MySQL Conference & Expo: “The O’Reilly MySQL Conference & Expo is committed to spreading the latest and best knowledge on MySQL and related technologies to the global community of DBAs, developers, and managers. You’ll find answers to your questions about MySQL in an independent and inclusive environment. You’ll also find practical guidance to help you add value and manage costs to your project or organization.” MySQL Conference & Expo [U157], Santa Clara, CA

Apr 19–21 O’Reilly Where 2.0 Conference: “Where 2.0 brings together the people, projects, and issues building the new technological foundations and creating value in the location ecosystem. Join with developers, technologists, CTOs, researchers, geographers, academics, business developers, and entrepreneurs to debate what’s critical now, and what’s pushing the boundaries of the location frontier.” Where 2.0 [U158], Santa Clara, CA

May 16–19 RailsConf: “Co-produced by Ruby Central and O'Reilly Media, RailsConf is the official and largest gathering of the Ruby on Rails community. RailsConf incorporates keynotes, sessions, and tutorials to arm participants with the knowledge and skills they need to capitalize on the wealth of services and opportunities the Rails framework has to offer.” RailsConf [U159], Baltimore, MD

May 21–22 Maker Faire 2011: “A two-day, family-friendly event that celebrates arts, crafts, engineering, and science projects and the Do-It-Yourself (DIY) mindset. It's for creative, resourceful people who like to tinker and love to make things. We call them Makers.” Maker Faire 2011 [U160], San Mateo, CA

PragPub April 2011 51 June 14–16 Velocity: “Web performance and operations, once the secret sauce of elite Web companies, are now essential ingredients in every company’s online strategy. The business value of ‘fast and reliable’ has been established, and stakeholders are demanding more and better results now. Get the skills and tools you need to master this ever-shifting, increasingly complex domain at Velocity.” O’Reilly Velocity Conference [U161], Santa Clara, CA

USENIX Events What’s coming from our USENIX friends.

Apr 10–13 European Conference on Computer Systems: “The EuroSys conference series brings together professionals from academia and industry. It has a strong focus on systems research and development: operating systems, data base systems, real-time systems and middleware for networked, distributed, parallel, or embedded computing systems. EuroSys has become a premier forum for discussing various issues of systems software research and development, including implications related to hardware and applications.” EuroSys11 [U162], Salzburg, Austria

May 8–10 HotOS XIII: “Three days of active interaction among innovative practitioners and researchers in computing systems, broadly construed. Continuing the HotOS tradition, participants will present and discuss new ideas about computer systems research and how technological advances and new applications are shaping our computational infrastructure.” HotOS XIII [U163], Napa, CA

May 26–27 3rd USENIX Workshop on Hot Topics in Parallelism: “HotPar '11 will bring together researchers and practitioners doing innovative work in the area of parallel computing. HotPar recognizes the broad impact of multicore computing and seeks relevant contributions in all fields, including application design, languages and compilers, systems, and architecture.” HotPar '11 [U164], Berkeley, CA

Jun 14 3rd USENIX Workshop on Hot Topics in Cloud Computing: Part of 2011 USENIX Federated Conferences Week. “Back for 2011, USENIX is combining established conferences and new workshops into a week of research, trends, and community interaction.” HotCloud '11 [U165], Portland, OR

June 14 3rd USENIX Workshop on Hot Topics in Storage and File Systems: Part of 2011 USENIX Federated Conferences Week. “Back for 2011, USENIX is combining established conferences and new workshops into a week of research, trends, and community interaction.” HotStorage '11 [U166], Portland, OR

June 14 3rd Workshop on I/O Virtualization: Part of 2011 USENIX Federated Conferences Week. “Back for 2011, USENIX is combining established conferences and new workshops into a week of research, trends, and community interaction.” WIOV '11 [U167], Portland, OR

June 15–17 2011 USENIX Annual Technical Conference: Part of 2011 USENIX Federated Conferences Week. “Back for 2011, USENIX is combining established conferences and new workshops into a week of research, trends, and community interaction.” USENIX ATC '11 [U168], Portland, OR

Jun 15–16 2nd USENIX Conference on Web Application Development: Part of 2011 USENIX Federated Conferences Week. “Back for 2011, USENIX is combining established conferences and new workshops into a week of research, trends, and community interaction.” WebApps '11 [U169], Portland, OR

Jun 20–21 3rd USENIX Workshop on the Theory and Practice of Provenance: “The workshop may cover any topic related to theoretical or practical aspects of provenance, including but not limited to: provenance in databases, work flows, programming languages, security, software engineering, or systems; provenance on the Web; or real-world applications of or requirements for provenance.” TaPP '11 [U170], Heraklion, Crete, Greece

PragPub April 2011 52 Jun 28–Jul 1 The 9th Annual International Conference on Mobile Systems, Applications, and Services: “MobiSys 2011 seeks to present innovative and significant research on the design, implementation, usage, and evaluation of mobile computing and wireless systems, applications, and services. It is jointly sponsored by ACM SIGMOBILE and the USENIX association in cooperation with ACM SIGOPS.” MobiSys 2011 [U171], Washington, DC

Other Happenings

Apr 4 Larry Page takes over as Google CEO.

Apr 5 SATAN’s father, Dan Farmer, is 49.

Apr 5 Inventor Dean Kamen is 60.

Apr 6 MacOS co-creator Andy Hertzfeld is 58.

Apr 9 ENIAC co-inventor J. Presper Eckert was born on this date in 1919.

Apr 9 SQLite architect D. Richard Hipp is 50.

Apr 14 Ruby designer Yukihiro Matsumoto (Matz) is 46.

Apr 18 PUGS project initiator Audrey Tang is 30.

Apr 20 Chief Yahoo David Filo is 45.

Apr 22 Psychedlic ruminant-fancying game designer Jeff Minter (Yak) is 49.

Apr 24 Champion of modelessness Larry Tesler is 66.

Apr 28 Mathematician Kurt Gödel was born on this date in 1906.

Apr 30 Information theory pioneer Claude Shannon was born on this date in 1916.

Apr 30 Colossal Cave Adventure creator Don Woods is 57.

Apr 30 The World Wide Web is 18.

May In May, 1980, Erno Rubik’s puzzle started selling internationally under the name “Rubik’s Cube.”

May 1 2006 MacArthur Fellow Jim Fruchterman is 52.

May 2 Protoblogger Dave Winer is 56.

May 3 Simon Tatham, known for playing with PuTTY, is 34.

May 8 jQuery creator John Resig got to age 27 one day ahead of Mark Zuckerberg.

May 9 Red Hat founder Marc Ewing is 42.

May 11 Edsger Dijkstra’s 81st birthday.

May 14 Zillionaire entrepreneur Mark Zuckerberg is 27.

May 17 Youthful Alan Kay is 71(!)

May 19 Today is the tenth anniversary of the opening of the first Apple retail stores. Also, Java daddy James Gosling is 56 today; , founding member of NetBSD and founder of OpenBSD and OpenSSH, is 43; SNOBOL creator Ralph Griswold would have turned 77 today; and CP/M inventor Gary Kildall would have turned 69.

May 26 Ward Cunningham is 62.

May 27 PEZ was trademarked on this date in 1952.

May 28 Networking hotshot Adam Dunkels is 33.

May 29 62nd birthday of shareware co-creator Bob Wallace.

May 31 John Kemeny was born on this day in 1926.

PragPub April 2011 53 June In this month in 2011, Facebook will move into former Sun Microsystems digs in Menlo Park, CA.

June In this month in 1957, computer science legend Donald Knuth published his first article, “Potrzebie System of Weights and Measures,” in Mad Magazine [U172].

June 1 Tim Paterson, whose made Bill Gates a jillionaire, is 55.

June 3 One year ago today, Toro Iwatani was recognized by Guiness World Records for his game Pac-Man having the most coin-operated arcade machines installed worldwide: 293,822.

June 8 Tim Berners-Lee is 56.

June 23 Vint Cerf is 68.

June 23 Mathematica is 23.

June 28 Firefox co-creator Dave Hyatt is 29.

June 30 Lynne Jolitz is 50.

External resources referenced in this article:

[U1] http://mit150.mit.edu/symposia/computation

[U2] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U3] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U4] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U5] http://www.qaiquest.org/boston/index.html

[U6] http://www.pragprog.com/refer/pragpub22/titles/bhgwad/web-design-for-developers

[U7] http://www.pragprog.com/refer/pragpub22/titles/bhh5

[U8] http://www.pragprog.com/refer/pragpub22/titles/pad/practices-of-an-agile-developer

[U9] http://www.pragprog.com/refer/pragpub22/titles/vslg/programming-groovy

[U10] http://www.pragprog.com/refer/pragpub22/titles/vsscala/programming-scala

[U11] http://33degree.org/

[U12] http://www.pragprog.com/refer/pragpub22/titles/cfcar2/the-passionate-programmer

[U13] http://scottishrubyconference.com/

[U14] http://www.pragprog.com/refer/pragpub22/titles/cfcar2/the-passionate-programmer

[U15] http://scottishrubyconference.com/posts

[U16] http://www.pragprog.com/refer/pragpub22/titles/bhgwad/web-design-for-developers

[U17] http://www.pragprog.com/refer/pragpub22/titles/bhh5

[U18] http://www.twincitiescodecamp.com/TCCC/Default.aspx

[U19] http://www.pragprog.com/refer/pragpub22/titles/amiphd/iphone-sdk-development

[U20] http://iphonespring2011.crowdvine.com/

[U21] http://pragprog.com/refer/pragpub22/titles/algh/land-the-tech-job-you-love

[U22] http://codeconf.com/

[U23] http://www.pragprog.com/refer/pragpub22/titles/bhgwad/web-design-for-developers

[U24] http://www.pragprog.com/refer/pragpub22/titles/bhh5

[U25] http://pragprog.com/refer/pragpub22/titles/jvrails/crafting-rails-applications

[U26] http://railscamp.pl/

[U27] http://pragprog.com/http://pragprog.com/refer/pragpub22/titles/bksqla/sql-antipatterns/bksqla/sql-antipatterns

[U28] http://www.collaborate11.org/

[U29] http://www.pragprog.com/refer/pragpub22/titles/achbd/the-rspec-book

[U30] http://jaxlondon.com/

[U31] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U32] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U33] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U34] http://sqgne.org

PragPub April 2011 54 [U35] http://www.pragprog.com/refer/pragpub22/titles/ppmetr

[U36] http://www.meetup.com/DevTank/events/16558458/

[U37] http://www.pragprog.com/refer/pragpub22/titles/snfocus/pomodoro-technique-illustrated

[U38] http://rails.se/rails/show/SHRUG+13+april+2011

[U39] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U40] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U41] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U42] http://www.glsec.org/

[U43] http://www.pragprog.com/refer/pragpub22/titles/dkgrails/grails

[U44] http://www.nofluffjuststuff.com/conference/los_angeles/2011/04/home

[U45] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U46] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U47] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U48] http://glsec.softwaregr.org/

[U49] http://pragprog.com/refer/pragpub22/titles/sdcoach/agile-coaching

[U50] http://accu.org/index.php/conferences

[U51] http://pragprog.com/refer/pragpub22/titles/jvrails/crafting-rails-applications

[U52] http://www.bohconf.com/

[U53] http://pragprog.com/refer/pragpub22/titles/jvrails/crafting-rails-applications

[U54] http://en.oreilly.com/rails2011/public/schedule/speaker/76735

[U55] http://www.pragprog.com/refer/pragpub22/titles/pad/practices-of-an-agile-developer

[U56] http://www.pragprog.com/refer/pragpub22/titles/vslg/programming-groovy

[U57] http://www.pragprog.com/refer/pragpub22/titles/vsscala/programming-scala

[U58] http://www.facebook.com/home.php?sk=group_140593195987882

[U59] http://pragprog.com/refer/pragpub22/titles/sfipad

[U60] http://pragprog.com/refer/pragpub22/titles/DSCPQ

[U61] http://pragmaticstudios.com/iphone

[U62] http://www.pragprog.com/refer/pragpub22/titles/pad/practices-of-an-agile-developer

[U63] http://www.pragprog.com/refer/pragpub22/titles/vslg/programming-groovy

[U64] http://www.pragprog.com/refer/pragpub22/titles/vsscala/programming-scala

[U65] http://www.developermarch.com/developersummit/

[U66] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U67] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U68] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U69] http://www.bostondotnet.org/

[U70] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U71] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U72] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U73] http://www.bostonproducts.org/events/event_details.asp?id=151744

[U74] http://pragprog.com/refer/pragpub22/titles/nrtest/rails-test-prescriptions

[U75] http://reddirtrubyconf.com

[U76] http://www.pragprog.com/refer/pragpub22/titles/cfcar2/the-passionate-programmer

[U77] http://reddotrubyconf.com/

[U78] http://reddotrubyconf.com/

[U79] http://classes.blazingcloud.net/

[U80] http://www.10gen.com/conferences/mongophilly2011

[U81] http://pragprog.com/refer/pragpub22/titles/xquery/getting-started-with-xquery

[U82] http://www.marklogicevents.com/

[U83] http://pragprog.com/refer/pragpub22/titles/fr_j2r/from-java-to-ruby

[U84] http://pragprog.com/refer/pragpub22/titles/btlang/seven-languages-in-seven-weeks

PragPub April 2011 55 [U85] http://phillyemergingtech.com/2011/sessions/mary-poppins-meets-the-matrix-seven-programming-languages-at-the-cinema

[U86] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U87] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U88] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U89] http://phillyemergingtech.com/2011

[U90] http://www.pragprog.com/refer/pragpub22/titles/pad/practices-of-an-agile-developer

[U91] http://www.pragprog.com/refer/pragpub22/titles/vslg/programming-groovy

[U92] http://www.pragprog.com/refer/pragpub22/titles/vsscala/programming-scala

[U93] http://www.nofluffjuststuff.com/conference/reston/2011/04/home

[U94] http://skillsmatter.com/course/nosql/mongodb-for-administrators-and-operations

[U95] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U96] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U97] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U98] http://www.agilenewengland.org/

[U99] http://pragprog.com/refer/pragpub22/titles/rdbcd

[U100] http://pragprog.com/refer/pragpub22/titles/dlret

[U101] http://xp2011.org/

[U102] http://www.pragprog.com/refer/pragpub22/titles/bmrc/programming-cocoa-with-ruby

[U103] http://www.pragprog.com/refer/pragpub22/titles/bmsft/everyday-scripting-with-ruby

[U104] http://www.xp2011.org/

[U105] http://pragprog.com/refer/pragpub22/titles/sdcoach/agile-coaching

[U106] http://xp2011.org/program/

[U107] http://xp2011.org/

[U108] http://www.pragprog.com/refer/pragpub22/titles/snfocus/pomodoro-technique-illustrated

[U109] http://geecon.org

[U110] http://www.pragprog.com/refer/pragpub22/titles/dkgrails/grails

[U111] http://nofluffjuststuff.com/conference/st_louis/2011/05/home

[U112] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U113] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U114] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U115] http://en.oreilly.com/rails2011/public/schedule/detail/19279

[U116] http://pragprog.com/refer/pragpub22/titles/nrtest/rails-test-prescriptions

[U117] http://en.oreilly.com/rails2011

[U118] http://www.pragprog.com/refer/pragpub22/titles/cfcar2/the-passionate-programmer

[U119] http://en.oreilly.com/rails2011

[U120] http://en.oreilly.com/rails2011/public/schedule/detail/19359

[U121] http://www.pragprog.com/refer/pragpub22/titles/snfocus/pomodoro-technique-illustrated

[U122] http://devsum.se/

[U123] http://www.pragprog.com/refer/pragpub22/titles/cfcar2/the-passionate-programmer

[U124] http://rubyconfindia.org/

[U125] http://www.pragprog.com/refer/pragpub22/titles/ppmetr

[U126] http://euruko2011.org

[U127] http://pragprog.com/refer/pragpub22/titles/jvrails/crafting-rails-applications

[U128] http://euruko2011.org/

[U129] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U130] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U131] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U132] http://www.sqe.com/AgileDevPracticesWest/

[U133] http://www.sqe.com/AgileDevPracticesWest/

[U134] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

PragPub April 2011 56 [U135] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U136] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U137] http://www.sqe.com/AgileDevPracticesWest/

[U138] http://www.10gen.com/conferences/mongonyc2011

[U139] http://www.pragprog.com/refer/pragpub22/titles/bmrc/programming-cocoa-with-ruby

[U140] http://www.pragprog.com/refer/pragpub22/titles/bmsft/everyday-scripting-with-ruby

[U141] http://agical.se/se/tdd-in-clojure

[U142] http://www.pragprog.com/refer/pragpub22/titles/jrport/manage-your-project-portfolio

[U143] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U144] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U145] http://www.sqe.com/AgileDevPracticesWest/

[U146] http://www.pragprog.com/refer/pragpub22/titles/dkgrails/grails

[U147] http://nofluffjuststuff.com/conference/columbus/2011/06/home

[U148] http://pragprog.com/refer/pragpub22/titles/sdcoach/agile-coaching

[U149] http://www.spaconference.org/

[U150] http://rubykaigi.org/2011/

[U151] http://www.pragprog.com/http://pragprog.com/refer/pragpub22/titles/bksqla/sql-antipatterns/jrport/manage-your-project-portfolio

[U152] http://www.pragprog.com/refer/pragpub22/titles/jrpm/manage-it

[U153] http://www.pragprog.com/refer/pragpub22/titles/rdbcd/behind-closed-doors

[U154] http://www.igniteoutsourcing.com/agile-training/course-schedule

[U155] http://pragprog.com/http://pragprog.com/refer/pragpub22/titles/bksqla/sql-antipatterns/bksqla/sql-antipatterns

[U156] http://kscope11.com/

[U157] http://www.mysqlconf.com/

[U158] http://conferences.oreilly.com/where

[U159] http://www.oreillynet.com/pub/e/1763

[U160] http://www.oreillynet.com/pub/e/1814

[U161] http://velocityconf.com/

[U162] http://eurosys2011.cs.uni-salzburg.at/welcome.php

[U163] http://www.usenix.org/events/hotos11/

[U164] http://www.usenix.org/events/hotpar11/

[U165] http://www.usenix.org/events/hotcloud11/

[U166] http://www.usenix.org/events/hotstorage11/

[U167] http://www.usenix.org/events/wiov11/

[U168] http://www.usenix.org/events/atc11/

[U169] http://www.usenix.org/events/webapps11/

[U170] http://www.usenix.org/events/tapp11/

[U171] http://www.sigmobile.org/mobisys/2011/

[U172] http://www.dccomics.com/mad/

PragPub April 2011 57 Shady Illuminations

A Few Words about Oracle’s Sun In reviewing Volkswagen’s New Coupe [U1] last year, Edward Niedermeyer seems to have coined the word apathyosis. At least I assume he thought it up by John Shade himself, since he hyphenated it so we’d be more likely to get the joke. I got it once I’d I researched it. Apotheosis means exalting any subject to a supreme Some elements of Sun Microsystems were never going to survive the move to Oracle. John runs down height, so apathy-osis would mean drabbing down something to the point where the Doomed List. you bore the pants off the paying customers. It wasn’t a positive review. And it wasn’t boring.

I figured if I wrote about Oracle again I’d risk boring the pants off my customers, so I decided to emulate Niedermeyer and throw in some words in my own DIY-alect, plus some real but obscure words. That oughta work.

The Doomed List Ever since Oracle bought Sun, the punditry has been analyzing Oracle’s every move, trying to predict the next one, trying to place specific corporate decisions in some broader strategic context, examining the debris of the acquisition and the punditry’s collective navel for clues. I am not a pundit. I do not engage in omphaloskepsis (navel-gazing). I don’t know what will happen to SPARC, Solaris, or MYSQL. I doubt that those who prognosticate know, either. Count me among the omphaloskeptics. I’ve always been umbilicodubious. But some things are blindingly obvious. Certain parts of Sun were never going to survive the transition. Let’s just run down the Doomed for the Get-Go List.

Stars Sun had some big-name programmers. Stars. Not Google-class stars, but stars nonetheless. Oracle bought them along with the hardware, software, real estate, debt, frivolous patents, and customer goodwill. And like the other assets in the Sun portfolio, they had to fit into Oracle’s plans, or they would not shine in Oracle’s firmament. And they’re not. Are we surprised? Did anyone really think that Tim Bray and Charles Nutter and James Gosling were going to survive the acquisition, to join the other software superstars at Oracle, like— I’ll just step out for a cup of java while you make a list of all the famous software developers at Oracle. OK, let’s compare lists. Mine’s empty. And yours? Well, that’s my point. There are no stars at Oracle. There can’t be any stars at Oracle. All the attention has to be on Larry Ellison. There’s no room for other egos. It’s all Larry. So

PragPub April 2011 58 Gosling and Bray and anybody else with a following? They were all doomed from the signing.

Sentiment

The Register reports that Oracle is retiring the sun.com domain [U2]. That

domain is apparently the twelfth oldest currently registered domain name [U3], behind symbolics.com, bbn.com, think.com, mcc.com, dec.com, northrop.com, xerox.com, sri.com, hp.com, bellcore.com, and ibm.com. Oracle is moving all useful content from it and shutting it down. Thus saving those onerous registration fees. Cold. Precisely. Oracle doesn’t do sentiment. Oracle has no interest in Sun’s history or legacy. Oracle acquired certain assets when it bought Sun. That is all. It will now proceed to write over everything that was once Sun. Decades from now, historians of business will have to use some as-yet-uninvented technology to read the subsurface traces of Sun erased and replaced by layers of Oracle history. The page has not so much turned on Sun as it has started to be overwritten: Sun is becoming a palimpsest. Which, as Wikipedia informs us, is “a manuscript page from a scroll or book from which the text has been scraped off and which can be used again.” Since Larry seems to take the view that Oracle is monetizing Sun’s hobbies, make that a paypalimpsest.

Culture If that multi-billion-dollar company founded in the mid-90s to help people find their way around the web by two Stanford PhD students with four-letter last names were to merge with that other multi-billion-dollar company founded in the mid-90s to help people find their way around the web by two Stanford PhD students with four-letter last names, we’d have a right to be concerned about any offspring of that consanguineous coupling. In the case of Oracle now managing products developed by Sun, we’re probably more concerned about the creepy results of xenotransplantation. Not to worry. Oracle doesn’t absorb the culture of the companies it buys. It dissolves their cultures in its corrosive digestive juices. Oracle is impervious to cultural inoculation. Whatever can adapt to Oracle’s reptilian culture has a chance of surviving in the Body Oracular. What doesn’t, doesn’t. OpenSolaris didn’t. Open sourcey, community-y projects haven’t, generally. Harmony co-founder and Apache treasurer Geir Magnusson said, “The problems [that] have surfaced over the last 12 to 18 months have been sort of all around open source community.” Oracle also doesn’t think that free is the right price for Solaris. Free is part of the hippy-dippy pony-tailed do-good-to-make-good culture of Sun that just doesn’t fit in at Oracle. Like Jonathan Schwartz.

PragPub April 2011 59 About the Author John Shade was born under a cloud in Montreux, Switzerland, in 1962. Subsequent internment in a series of obscure institutions of ostensibly higher learning did nothing to brighten his outlook or his fondness for his fellow humans. If it takes a village, he says, he’d rather not.

Send the author your feedback [U4] or discuss the article in the magazine forum [U5].

External resources referenced in this article:

[U1] http://www.thetruthaboutcars.com/tag/ncc/

[U2] http://www.theregister.co.uk/2011/03/16/oracle_closes_sun_domain/

[U3] http://www.whoisd.com/oldestcom.php

[U4] mailto:[email protected]?subject=shade

[U5] http://forums.pragprog.com/forums/134

PragPub April 2011 60