Articles Feed

Authors

Categories

Zeroth rule of professionalism

by: paul | January 8th, 2010 | 1 comments »

This is a response to an article “Software Testing Craft” by Markus Gärtner in inaugural issue of Agile Record.

As an apprentice, I remember thinking that solutions to software were either right or wrong. Later this was able to be simplified to either the solution works or doesn’t work. This became my base level understanding of a software solution.

Then came the time I thought solutions should be judged by how clean or efficient they were. This was my renaissance of aesthetics in the code. How to code your intentions expressively was the goal. This too became a new base level of understanding.

Now I am of the understanding that software solutions are a judged by factors of time. Making all the trade offs correctly so the code works and is readable, but also in the shortest amount of time possible. The key thing here is to take the long term view of time. Not how much time in a single sitting, but every time you come back to the same solution. How often do you come back? How hard is it to change?

From the article, Markus says, “As a software tester, you should take responsibility for the out- come of every decision you make. I call this the zeroth rule of professionalism.”

I think this is an elegant way of stating my understanding of software solutions. Every decision you make is a function of time and understanding. By taking responsibility for each of your decisions software becomes a series of trade offs that you have to live with and learn from. When a design works and is written well, it becomes easier to live with the outcomes of your decisions.

It is much like how I learned to play chess. At first I would make a move and try to understand the consequences in position and strength. Then I learned the common openings and endgames which helped me express my strategic creativity and play moves that had aesthetic value. Finally came the important skill. Being able to project moves forward and do a risk analysis of each possible move. This let me take the previous skills and put them together in a coherent fashion. I could understand how a move fatal to my king was a consequence of a move made much earlier in the game and learn from that decision. This skill is when I started playing chess as a game rather than a set of moves.

For me, it was only through the out-comes of my design decisions that I learn this lesson. It was very important for me to be in a position transparent to the positive and negative consequences of the code I write. Like the chess analogy, I need to project forward to attempt to understand the consequences of a decision before I make it.

Pair Fridays

by: paul | October 6th, 2009 | 0 comments »

8th Light has always had an open door policy towards developers. When anyone has asked to come hang out at 8th Light offices, we don’t turn anyone away. We also invite developers to come in and pair with us. It has been a fun practice to get to know other developers here in Chicago as well as developers traveling through town. We would like to flip that practice around and invite anyone interested in pairing with 8th Lighters or just coming in to hang out.

Every Friday we have a noon lunch and learn (lunch provided by 8th Light) and then we will be available to pair for the afternoon. Want to come in and see how we work? Learn to use Limelight? Teach us something cool? Just hang out with cool developers?

Please RSVP with me (paul [at] our domain name) so we know how much food to order.

Apprenticing to Mastery

by: paul | September 29th, 2009 | 0 comments »

Come see Dave Hoover and I speak about about software apprenticeships on November 19, 2009 in San Fransisco.


Thoughts from a Boutique Software Shop

by: paul | September 12th, 2009 | 0 comments »

Michael Feathers recently wrote a blog about boutique software shops. He drew the parallel between master chefs and software shops. There were a few great points I would like to respond to:

1. “So, where are the high-end restaurants of software development?  One place to look is in the “boutique software shops.”  I don’t know where I first heard that term, but for me it is a “catch all” for all of the small software development houses that I see springing up all over the place.”

This is an interesting phenomenon. I am not sure if this has always happened or if I am paying attention more to boutique shops now that I am a part of one. 8th Light is an 8 craftsmen software shop that started in 2006 with the goal of writing high quality software. No teaching, coaching, staff augmentation. Just writing software, with the idea that focusing on proving quality has a high correlation to success.

I agree with the high-end software shop analogy. If you take a small team of trained craftsmen focused on doing their best work, the result is most often a very strong culture of quality. Ramsay creates this strong culture of quality through a theatrical performance of yelling and screaming at failure. There are other ways for masters to do the same thing. Micah Martin, the 8th Light master craftsman, creates this strong culture by setting an example of writing good code and holding yourself to a constantly higher standard. This is the common thread that I have seen through these boutique shops–they all have an owner who is a technical leader who creates a strong culture where (excuse the pun) failure is just not an option. There are other similarities like strong discipline, small teams, cutting edge technologies, and ability to develop strong skill sets in developers, however, I think that all of these are direct descendants of the strong leadership.

2. “It’s not that development teams need UX people, it’s more like UX teams need developers.”

I partially agree with Michael. I think this statement can be replaced with any critical specialization in the domain of software applications. The reason UX is getting a spotlight is because, as Michael notes, we have stuck UX on the back burner for so long. In the last few years though, the expectations from users of software have luckily skyrocketed. It is no longer okay to plow through features, but they need to be simple, attractive, and intuitive. When I worked with Gilberto Medrano in 2005, he talked about the UX revolution that was coming. In 2006, he created a UX design while at 8th Light that continues to impress 3 years later (in web application years, that is a lifetime). Well, he was right, I can no longer stand an application which is not aesthetically pleasing. It doesn’t matter how cool the feature set–which is a weird statement to come from a developer.

This is an argument for craftsmen teams. Craftsmen have many tools in their bag, and UX is one of them. Part of being a craftsman is to know enough about UX that you can talk to an expert as well as do some UX. Just like a UX expert craftsman can dabble in code. A craftsmen has many shallow skills as well as a few very deep skills. Craftsmen teams have individuals with diverse expertise talents and a common knowledge of intermediate and beginner talents. It is very fun to be on these teams, when the work is one which has quality–quality of being “aesthetically” impressive as well as “feature set” impressive.

Reasons to Attend SCNA

by: paul | July 17th, 2009 | 1 comments »

SCNA website

1 - “The list of SCNA presenters reads like Who’s Who of Software Jedi Knighthood” -- Ray Hightower

This is a complete testament to how willing and excited the thought leaders and software masters were to speak at this conference. The creme of the crop in software mastery will be talking about how to raise the bar in our industry. I have never seen a lineup of speakers who put me in such a state of awe since the early XP Universe days. Thanks to all of them for getting together for this conference.

2 - Join software craftsmanship over crap.

Last year Uncle Bob challenged software developers to become professionals. We have spent a year of summits, manifestos, meet ups, and conferences trying to figure out how to move forward towards professionalism with this paradigm of software craftsmanship. The momentum of craftsmanship is only growing.

3 - Software craftsmen all in one room.

The google map of software craftsman who have signed the software craftsmanship manifesto has proven this to be a global community of software developers. It is unique that we have people flying in from multiple continents to participate. I am excited to meet face to face with all these craftsmen whom I know only their ideas and email addresses.

4 - Richard Sennett

A sociologist who wrote The Craftsman, Dr. Sennett has provided a template for studying the habits and techniques of craftsmanship. He touches on everything from extending your concentration to why we choose vocations so passionately. It is a true authority on craftsmanship.

Apprentice Architecture

by: paul | May 6th, 2009 | 1 comments »

Good design sense is a skill that comes only from many years of coding experience. Sometimes it can be very difficult to make those design decisions when you are an apprentice or otherwise don’t have much experience.

When I was an apprentice, oftentimes I would get a problem from Micah (my mentor) and would solve it the simplest way possible. Then I would walk up to him with my head held high and say I was done. He would almost always point out some way the architecture was not easy to extend or that he didn’t even know java had goto statements.

As an apprentice, the most important thing is to get everything to work correctly; only then should you concentrate on making sure it is good code. Writing great code with great designs is not a skill that will appear overnight. It took years of honing my design sense to be able to see designs right away, and I have only scratched the surface of my mentor’s abilities.

When I was an apprentice, I lacked the experience and skill to make difficult architectural choices. Let alone the ability to get it right on the first pass. I instead stayed close to the code and continued to move forward writing working code. This led to many design mistakes, and I had to throw out plenty of code or refactor to a better design. This is an exercise in taking a step backwards to move forwards. I learned the value of working code as well as the value of refactoring to better designs. Content before form is an important lesson I learned as an apprentice. It laid the foundation for the later lesson that good form is essential for high quality code.

As an apprentice, ask your mentor when you have completed a task if they think there is a better design. Then refactor that design and compare the two. Once again, repetition and practice will pay off as these exercises help you develop a matured design sense. You will learn from having to solve the problem without being told the design first, and then later having to re-implement a better design. This practice will internalize your design sense and eventually you will start to see the better designs the first time through.

The big problem with trying to get the design right the first time is it leads to coders block. Staring at the blank screen, trying to figure out the best way to do something. Even if you are writing the wrong code, it is important to be moving in some direction. When I see the code, oftentimes the design I get will form around the reading of the code rather than trying to think in the abstract about the whole problem at once. For me the problem and the design for the solution would be too big of a mental model to fit in my head all at once. Don’t worry, as you get more experience, your mental context will expand too. Your ability to sustain concentration will build as well as you practice and become more experienced. With experience, you won’t have to think about as many of the small problems anymore.

Architecture is like most craftsman practices in the sense that there are breakthroughs but there is always more to learn. I read a blog recently where Uncle Bob Martin talks about thinking through the architecture of a problem for hours or days before he will start. When I was an apprentice, I would not have had enough experience or a large enough mental model to think about the architectural impact of a solution. Even as a journeyman, I still only have a big enough mental model to think about an aspect of a problem, write the code, then reevaluate where the solution stands in the context of the system.

For an apprentice, bad design should not be seen as the end of the world. As long as you are learning and progressing in the techniques of creating working code, you are moving in the right direction. Design sense is a long-term skill and you will have to be patient with it. Remember that practice makes perfect.

Bug free or Free Bugs

by: paul | April 26th, 2009 | 1 comments »

I will not charge a client for a bug fix. Not a penny. If I make a mistake, it is my professional obligation to fix it.

If something doesn’t work with my car, there could be catastrophic consequences, I would be mad unless the company has a solution and offers to fix it for free. As a car owner, I expect nothing less. If a doctor makes a mistake, the patient has the right to sue the doctor for malpractice. Why is it if I make a mistake, I get off scot free? Or worse, I get paid to fix my own mistakes.

I know sometimes the devil is in the details. What is a bug? This is not an easy question to answer, but if there are customer written acceptance tests for the system, the items that fall through are fewer. These are general rules I go by when deciding if something is a bug or not.

One: I made a mistake. These are usually easy to notice, due to the redness in my face when the bug is reported. It is clear to me, I made a mistake, and it is clear I need to fix the bug. It should not cost the customer any money and the process should be transparent.

Two: There is a mistake that both development and the customer team should have caught. A scenario the customer should have specified and during development I should have noticed and brought to their attention. The fault goes on both parties and can be fixed at some version of half price (i.e. every other or a half price story).

Three: The application doesn’t behave correctly due to a missed specification. a scenario that the customer missed or a piece of the business logic that wasn’t fully correct. Almost everyone makes some mistakes. This is not a bug to me, but a feature enhancement. It can be written up as a story and completed.

I think it is important to build faith with the customer that there is a team of developers that are accountable. When you create the culture of accountability, it spreads. The customer team is willing to be accountable when they make a mistake. When no one is afraid to make or admit to a mistake, the projects quality is positively affected. Finally, by taking financial ownership of a bug, I build a trust with my stakeholders of the project.

Ethical approach to Software Bugs

by: paul | April 8th, 2009 | 8 comments »

Software bugs are errors or omissions in the work we create. They are our mistakes as software developers. I am going to leave defining and dealing with bugs to a blog post I wrote last summer. I would like to take a closer look at software bugs, using an ethics metaphor to examine some of the rationale. For the sake of this blog, we fall into three camps: Software Utility, Software Relativism, and Software Craftsmanship.

Software Utility

“Fixing bugs is only important when the value of having the bug fixed exceeds the cost of the fixing it.” -- Joel Spolsky

This is the camp of software utilitarianism. I understand applying this rubric in terms of return on investment might have J.S. Mill turning over in his grave, but there is a strong correlation here. According to wikipedia, utilitarianism “is the idea that the moral worth of an action is determined solely by its contribution to overall utility.”

Let’s take an example using Mr. Spolsky’s argument. We need to be able to quantify in dollars the value of Bug X. It is worth $1,000 to the company, because the ramifications of not fixing it means we only lose 2% of our user base. The cost of fixing this bug is $3,000 worth of development time. According to Software Utility, this is a no-brainer. Let the bug go, find something more important and more financially inviting to work on.

The problem here is there are so many unquantifiable variables in the equation. How do you put a dollar amount on instability? When someone tries to reuse the code that has a bug in it, you are spreading the bug throughout the system, literally, like a disease. You can deal with smaller known bugs now, or you can have them bubble up as diseases later on, where the price of fixing them will grow much higher. The software craftsmanship approach means you don’t have to get into the tricky business of quantifying everything.

Software Relativism

I have heard that, “my team doesn’t test drive their code, and so I don’t.” This is software relativism. Famous moral relativist J. L. Mackie “argu[ed] against the objective existence of right and wrong as intrinsically normative entities on fundamental grounds unsure what kinds of things such entities would be, if they existed.” In software, this is saying that whatever works, works.

Or, “We try to keep the bug list low.” Specific practices will be chosen due to their ease or convenience, rather than due to their inherent worth. If I join a team that is making money writing software without testing it, I shouldn’t judge, but do the same. There are no objective rights and wrongs, just a series of things that will work for specific circumstances.

One of the problems is when you get into a negative feedback loop. When everyone is sprinting for the finish line and there are no objective standards, you are going to end up with junk at the other end. We need a threshold of quality we will not fall below. Otherwise you will end up with a system of piecemeal quality, with parts that are stable and parts that are not stable. This is arguably worse than an unstable system. Either way, if becomes costly to maintain or just plain unmaintainable. The software craftsmanship approach avoids this problem of relativity by placing minimum objective standards.

Software Craftsmanship

I am calling the third section software craftsmanship because it fits conveniently in line with the software craftsmanship movement. It is based on the ethics of Immanuel Kant, specifically his first formulation of moral theory. It stated, “Always act according to that maxim whose universality as a law you can at the same time will.” The classic example is dealing with lying. Can lying for the sake of some other good be considered moral? Kant says to ask yourself: “If everyone lied, would the maxim still hold?” No, our society functions based on a presumption of honesty. Well, if everyone overlooked bugs or shipped with known bugs would the maxim still hold? No, software functions based on the presumption of quality. The user expects the software to work. To me, this means as an aspiring software craftsman, I can not ship with any known bugs. If you make lying acceptable, your neighbor will start to lock their doors. I am afraid that many software users have already locked their doors. So, a software craftsman can not live with bugs in their system.

I ship with no known bugs. As Thomas Jefferson says, “In matters of principle, stand like a rock; in matters of taste, swim with the current.” Shipping with no bugs and cleaning up my own messes is a matter of pride and principle. It can’t always be done with ease or convenience. Sometimes it means fixing some obscure feature you are sure no one will use.

Material Consciousness in Software

by: paul | March 30th, 2009 | 1 comments »

The following excerpt is from Richard Sennett’s, The Craftsman. All craftsmen have [material consciousness], even those who practice the most arcane art. The painter Edgar Degas is once supposed to have remarked to Stéhane Mallarmé, “I have a wonderful idea for a poem but I can’t seem to work it out,” whereupon Mallarmé replied, “My dear Edgar, poems are not made with ideas, they are made with words.”

In this same vein, software is not made with designs and ideas, but with code. Code is the raw material. Code is the only means we have to create anything. The ideas we have are only as good as the code we can write to implement them. So, the code is the object of all a software craftsman’s material consciousness. Material consciousness for the software craftsman becomes a fancy way to say that we are aware of the code at all times.

The code being the object of our craft is an important distinction, because it provides a rationale for never being too far from the code in our practices. The farther you are from the code itself, the farther you are from being able to produce an actual object of work.

When I learned eXtreme programming, this was taught to me in a series of practices. For example, using evolutionary design rather than designing an entire system before you write the code. When you design something before you write the code, you add a level of removal from thinking about the code itself. You are thinking about abstractions. An alternative, evolutionary design, tells me to write a test, then do the simplest thing I can possibly do to make that test pass. Through looking at the code, I get a feel for what the design should be. This feel lets me refactor to a better design. This design technique allows my material consciousness to not be obstructed. I get to think critically about the design of my code, but I do it in a combination of abstractions and examples, rather than just designing in the abstract.

Another example of material consciousness in crafting software is developing in vertical slices. A vertical slice is when you develop the whole set of requirements for a specific feature before moving on to another feature. When you develop in vertical slices, you are never far from changing the code and seeing the feedback in the application. You can change some code and look at the user interface, instead of having to imagine what the front end will look like. Or if you are coding the front end first, trying to visual what the entire API should look like. This idea resonates with the famous  William Carlos Williams quote, there are "no ideas but in things."

It is important for me as a software craftsman to know what the material I need to be aware of is, so I don’t remove my thought too far from it. During the software craftsmanship summit in Chicago, Brian Marick said we need to treat the code as an end in itself, not just the means. To me, this captures the idea of thinking in code.

Software Journeyman program

by: paul | March 19th, 2009 | 0 comments »

8th Light and Obtiva have partnered up to provide a journeyman program. Traditionally, a journeyman program is when a master craftsman hires a journeyman for a specific project. This journeyman lives and works with the master, learning from her/his experience and helping the master produce craftwork. A lot has changed since this type of journeyman program was prevalent.

We are going to have to alter the journeyman idea to fit into the way that both companies do business.

Our program is the first software journeyman program that I know of. It consists of sending a craftsman to the another company for a specific amount of time. It is exciting to have the opportunity to travel to another workshop and gain new experiences. Being the first of its kind, it is hard to set hard goals. I hope among them are the ability to see how a different style and thought process goes into software craftsmanship at different workshop. As a journeyman, I think it is important to be very diverse in skills and techniques, so you can use the ones which best fit your coding style and problem sets.

Our solidarity with Obtiva on the topic of craftsmanship provided a willingness to work together to make the program work in today's business environment.

So, how did this happen? Corey Haines has been traveling the countryside on his own journeyman tour, dropping apple seeds. One of those seeds was getting 8th Light and Obtiva together in a room to hammer out solutions to all the obstacles involved in starting a cooperative journeyman program. I am very thankful to Corey for being proactive in putting it together.

History of the Software Craftsmanship Manifesto

by: paul | March 11th, 2009 | 0 comments »

I would like to prelude this with an assurance that this is not the history of the software craftsmanship. I know a little of that history, as far back as Pete McBreen's book Software Craftsmanship: the new imperative and Uncle Bob's Software Craftsmanship articles. No, this is just a brief history of the document hosted here.

It started when Uncle Bob's keynote speech last year at "Agile 2008." Uncle Bob proposed an amendment to the Agile Manifesto of "Software Craftsmanship over Crap." Now, the manifesto, to my knowledge, was never changed. However, the software craftsmanship community started to become more active.

The actual manifesto started with a summit on Software Craftsmanship in Chicago, on December 13, 2008. There we discussed what it means to be a craftsman and an apprentice and so forth. We spent the afternoon discussing who the document would be written for, what the contents of it would be, if the document already existed, and if it needed to exist at all. The attendees deserve a lot of credit on getting these ideas started, and they are listed below.

On a whiteboard, we wrote the first version of the manifesto and all the attendees signed it. For a few months afterwards, we talked about it on the google group, discussing the various ideas put forth at the summit. Then, in February, Doug Bradbury wrote an email called "The new Left Side" which started to get the values and wording which was refined into the actual Software Craftsmanship Manifesto. There was a debate about how the agile manifesto and the software craftsmanship manifesto that was instrumental in moving forward with the manifesto. You can read these threads at http://groups.google.com/group/software_craftsmanship. They start with "The new left side" by Doug Bradbury and "Right side, revisited" by Scott Pfister. It was a fascinating conversation, which spawned the final language of the manifesto.

So, the question that was asked on the software craftsmanship mailing list and in the twitterverse, is "Why a software craftsmanship manifesto?" Well, if you will permit me to give an existential answer, it is because the list has 1771 signatories as of this writing. That many people now know each other as craftsmen in some context. They know they can talk as craftsmen, and hopefully move forward in our industry as craftsmen.

Let me use some other answers to the question to give another perspective.

"As of today, there are over 1500 signatures on the Manifesto. 1500 people are fighting against "crap code". Those who have been fighting "crap code" now know that they are not alone in their fight. Those who write "crap code" now know that there are 1500 people fighting against them." -- Micah Martin

"By becoming a vocal community, publishing a manifesto, beginning work on establishing principles and concrete schools of thought, we are creating a light that new developers can see. Those who are really interested can more easily find us, talk to us about apprenticeships, meet companies that actively engage in craftsmanship activities (apprenticeships, journeymen programs, etc.). In some cases, this will introduce them sooner to these ideas, hopefully saving some from the frustrations they can face in a different situation." -- Corey Haines

Observing a Craftsman

by: paul | November 17th, 2008 | 1 comments »

“Knowledge can be communicated, but not wisdom. One can find it, live it, be fortified by it, do wonders through it, but once cannot communicate and teach it.” –Hermann Hesse, from Sidhartha

My path in becoming a craftsman was not through conventional academics. I did get a Bachelor degree in Computer Science. During those years of learning, I was taught a lot about how to learn and how to communicate, but I learned nothing about how to practice my craft of software. I learned how TCP/IP works, how registers are able to do math . All of this is interesting and some of it is useful for a broader view of computer interactions as a whole. None, however, taught me about developing software as a craft. I did some programming, which is a prerequisite for any kind of software development.

My real learning began after school. Learning software as a craft was not done in books. It took being around journeymen and master craftsmen to learn the way they think. Observing their idiosyncrasies and approach to a problem is part of the learning. Much of the wisdom is tacit. For me it is watching the way my mentor approaches a story. The way a craftsman sees a problem and digests it, without hurry, and finds a satisfactory solution. Then they write code, introducing faults and fallacies the original solution could not have predicted. Finally, a meticulous approach to improve each fault in the code. The whole time demanding perfection, without ever hitting it. This is the good code I strive to write. I can’t learn that by looking at the solution though.

These are observations of behavior and intent, not of actions. For example, I have read about Test Driven Development, and it has made my job easier. For awhile after I learned it, I wrote a lot of simple assertions, almost reverse engineering my production code in my head to figure out what the test code would look like. However, the practice itself became ten times more valuable when I saw my mentor use the tests to design their API. They would say things like “what do I want this to do” or “that doesn’t feel right, lets rename the method to this”. Those insights into the thought process provide me with the experiential learning it takes to further improve my craft. When I started thinking about TDD in a similar manner, it allows me to clean up my code and know it still works, refactor my code into easily extendable solutions, and it gives me the confidence to experiment with the aesthetics of my code. I couldn’t fully learn that from books alone.

This is why it is so important to apprentice as a software developer. There are many things about development that I only learned through watching the behaviors and actions of the craftsmen I admire. To me, these are the things that open up the software world to gain wisdom. For example, to be a better developer is not to learn a new language, but to have the wisdom to learn and understand any computer language, which requires you to learn new languages all the time.

Limelight Tutorial: Tic Tac Toe Example

by: paul | September 29th, 2008 | 0 comments »

Welcome to a Limelight production. I am going to go through a step by step introduction to limelight development using a tic tac toe game as an example. So, lets get started. I am going to create the directory structure and open it up in a text editor.

  1. $ mkdir tictactoe
  2. $ cd tictactoe
  3. $ mate .

Now I need to set up Limelight. You can just download the gem.

  1. $ jruby -S gem install limelight

We can start by creating the props.rb file in the tictactoe directory. The props.rb file defines the structure of your application. A prop is named after the theater metaphor. We are going to use them to define what our scene's physical structure look like. We can start with a simple screen with an empty board with the nine cells we need for a tic tac toe game. Lets create a spec directory to write a test for the props we are going to create.

  1. $ mkdir spec
  2. $ mkdir spec/props

Now for the spec. In the spec directory, we can name our spec props_spec.rb. We want to check that there is a cell on the scene. Here is the first test. NOTE: To be able to run the test, you will need the spec_helper.rb in your spec directory (not the props directory). You can copy it from the sample application.

  1. require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
  2. describe "Props" do
  3. include PropSpecHelper
  4. before(:each) do
  5. setup_prop_test
  6. end
  7. it "should have cell_0_0" do
  8. @scene.find("cell_0_0").should_not be(nil)
  9. end
  10. end

and when we run it (You can copy the Rakefile from the sample application as well, if you want to have a specs task),

  1. $ jruby -S rake spec

we get the failure

1) Errno::ENOENT in 'Props should have cell_0_0' No such file or directory - File not found - /Users/paulwpagel/Desktop/tictactoe/props.rb /Users/paulwpagel/Desktop/tictactoe/spec/spec_helper.rb:18:in `initialize' /Users/paulwpagel/Desktop/tictactoe/spec/spec_helper.rb:18:in `setup_prop_test' /Users/paulwpagel/Desktop/tictactoe/./spec/props/props_spec.rb:6: Finished in 0.063 seconds 1 example, 1 failure

So, lets create the props.rb file in the project root. Now we should get the error.

1) 'Props should have cell_0_0' FAILED expected not nil, got nil /Users/paulwpagel/Projects/tictac/./spec/props/prop_spec.rb:12: Finished in 0.089 seconds 1 example, 1 failure

Each of the props accepts a block of code your can give options/structure to. We can open the props.rb file and add a cell with the id of "cell_0_0" to make this test pass.

  1. main do
  2. board do
  3. cell :id => "cell_0_0"
  4. end
  5. end

And the test passes. Lets make sure we have the rest of the id's while we are at it. Here is a more exhaustive spec.

  1. it "should have cells" do
  2. @scene.find("cell_0_0").should_not be(nil)
  3. @scene.find("cell_0_1").should_not be(nil)
  4. @scene.find("cell_0_2").should_not be(nil)
  5. @scene.find("cell_1_0").should_not be(nil)
  6. @scene.find("cell_1_1").should_not be(nil)
  7. @scene.find("cell_1_2").should_not be(nil)
  8. @scene.find("cell_2_0").should_not be(nil)
  9. @scene.find("cell_2_1").should_not be(nil)
  10. @scene.find("cell_2_2").should_not be(nil)
  11. end

And it fails in a similar manner. Lets expand our props.rb file to make the test pass.

  1. main do
  2. board do
  3. cell :id => "cell_0_0"
  4. cell :id => "cell_0_1"
  5. cell :id => "cell_0_2"
  6. cell :id => "cell_1_0"
  7. cell :id => "cell_1_1"
  8. cell :id => "cell_1_2"
  9. cell :id => "cell_2_0"
  10. cell :id => "cell_2_1"
  11. cell :id => "cell_2_2"
  12. end
  13. end

And it passes. However, it is all ruby code, so I can leverage ruby functions to help me out. Lets remove the duplication.

  1. main do
  2. board do
  3. 3.times do |row|
  4. 3.times do |col|
  5. cell :id => "cell_#{row}_#{col}"
  6. end
  7. end
  8. end
  9. end

Much better. Lets now move on to the styles. Nothing will show up without a few styles. I create a styles.rb file in the project root and filled it with some simple content. In Limelight, styles refer to how a prop is aesthetically displayed on the screen. Here is an example which defines the size and gives a border to the board and the cells.

  1. board {
  2. width 152
  3. height 152
  4. border_width 1
  5. border_color "black"
  6. }
  7. cell {
  8. width 50
  9. height 50
  10. border_width 1
  11. border_color "black"
  12. }

We should be able to start up Limelight and see the board. We start Limelight like: (From the tictacctoe directory)

  1. $ jruby -S limelight open .

and there is your first Limelight screen. Pretty easy, and all ruby code. Lets make it more interesting. Let us make it such that if you click on one of the squares, the square shows the 'X' mark denoting the first move.

First we create a directory called players. Inside go the players, which contain the actions and behavior of the props for a Limelight scene (the controllers).

  1. $ mkdir players

We want to now make a player for the cell prop. We create a file inside of the players directory called cell.rb. The file will start with a definition by looking like:

  1. module Cell
  2. end

We define all players in modules of the same name as the file and prop, by convention. This allows Limelight to include this behavior when it needs it. You can specify specific mappings between the props and its players, but we don't need to do that here. So, let's make the cell more interesting. When we click on the cell, we want it to make a large 'X' mark. Lets start by creating a spec for the behavior.

I created a new directory for the players spec

  1. $ mkdir spec/players

We have to add the players directory to the ruby search path, so I added the following line to the spec_helper.

  1. $: << File.expand_path(File.dirname(__FILE__) + "/../players")

My spec is going to find the prop that was clicked on and make that prop display an 'X', denoting the first move. Here is what my first spec looks like (I call it cell_spec.rb):

  1. require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
  2. require 'cell'
  3. describe Cell do
  4. include Cell
  5. attr_accessor :id
  6. it "should make first move an X" do
  7. @id = "cell_0_0"
  8. @cell_one = Limelight::Prop.new
  9. @scene = MockScene.new
  10. @scene.register("cell_0_0", @cell_one)
  11. self.stub!(:scene).and_return(@scene)
  12. mouse_clicked(nil)
  13. @cell_one.text.should == "X"
  14. end
  15. end

Which provides the feedback when run:

F 1) NoMethodError in 'Cell should make first move an X' undefined method `mouse_clicked' for # /Users/paulwpagel/Projects/tictac/spec/players/cell_spec.rb:14: Finished in 0.007423 seconds 1 example, 1 failure

If you have seen a rSpec specification before, this should look syntactically familiar. Before we move on to making the test pass, let us take closer look at a few aspects.

@id = "cell_1_1" - This line is setting the id of the imaginary prop that the players behavior will be executed against. @scene = MockScene.new - This creates a scene to mock out. The scene will be explained later, but for this test we are going to use the find method on scene to find our props. @cell_one = MockProp.new - Create a mock prop that will turn to 'X' when clicked @scene.register("cell_1_1", @cell_one) - We are giving the scene the mock prop, so the find method will find it by its id. mouse_clicked(nil) - Simulates a mouse_click on the cell. It takes an event, but we don't care about that yet, so lets just pass in nil.

All right, time to make this test pass. Lets open up the cell.rb player and see what we need done to make the test pass.

  1. module Cell
  2. def mouse_clicked(event)
  3. cell_prop = scene.find(id)
  4. cell_prop.text = "X"
  5. end
  6. end

Run the test again, no failures. We needed to find the prop on the screen which we are concerned about. We do this by calling find on a method scene, which will give us any prop by its unique identifier. We are looking for the id of the element we clicked, and then we set the text of that element to 'X', which makes the test satisfied.

Now, we can run the application from the root directory.

  1. $ jruby -S limelight open .

If we click on the box that is displayed, a small 'X' should appear in the upper right corner.

Congratulations, that is your first piece of Limelight behavior. However, this is not very interesting yet. Lets take it the next step and make the tic tac toe game work. I am going to create a lib directory to hold the game model.

  1. $ mkdir lib
  2. $ mkdir spec/lib

And before I write my first spec, I am going to add the new lib directory to the ruby search path by adding the following line to the spec_helper (It is already in the example spec_helper.rb, you don't need to add it).

  1. $: << File.expand_path(File.dirname(__FILE__) + "/../lib")

So, here is what my first spec looks like:

  1. require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
  2. require 'game'
  3. describe Game do
  4. it "make a move in the middle square" do
  5. game = Game.new
  6. game.move(1, 1)
  7. game.mark_at(1, 1).should == "X"
  8. end
  9. end

To make it pass, we need to create a game class in the lib directory and give it this code.

  1. class Game
  2. def move(row, column)
  3. end
  4. def mark_at(row, column)
  5. return "X"
  6. end
  7. end

And we can follow the test driving of the model to make the game class. I have already done this, and you can download the models in the sample application. Lets move past that back to the players and hook up the game.

I am going to create a file init.rb in the root directory. The init.rb class gets loaded up by Limelight when you start the application. We want to create a new game and have a way to keep it in memory for the other classes to use. Here is what the spec looks like in a init_spec.rb in the spec directory:

  1. require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
  2. require "game"
  3. describe "init" do
  4. it "should create new game on initialization" do
  5. game = mock('game')
  6. Game.should_receive(:new).and_return(game)
  7. Game.should_receive(:current=).with(game)
  8. require File.expand_path(File.dirname(__FILE__) + "/../init")
  9. end
  10. end

The simplest way to start that is to have a current_game class variable. Here is the code for the init.rb.

  1. $: << File.expand_path(File.dirname(__FILE__) + "/lib")
  2. require "game"
  3. Game.current = Game.new

I add the lib directory to the ruby search path so the Limelight application would know what a game is when I require it.

Now we need to plug the game model into the cell player. Lets change the spec we made earlier to make the first move depending on the game model. Here is the new version.

  1. it "should make first move in a game" do
  2. @id = "cell_0_0"
  3. @cell_one = Limelight::Prop.new
  4. @scene = MockScene.new
  5. @scene.register("cell_0_0", @cell_one)
  6. self.stub!(:scene).and_return(@scene)
  7. game = mock('game')
  8. Game.should_receive(:current).and_return(game)
  9. game.should_receive(:move).with(0, 0)
  10. game.should_receive(:mark).and_return("X")
  11. mouse_clicked(nil)
  12. @cell_one.text.should == "X"
  13. end

I am mocking out the game model and passing the values from the id into the game's move method. Here is the code that makes this pass.

  1. module Cell
  2. def mouse_clicked( event)
  3. game = Game.current
  4. x, y = get_coordinates
  5. game.move(x, y)
  6. cell_prop = scene.find(id)
  7. cell_prop.text = game.mark
  8. end
  9. private ################################
  10. def get_coordinates()
  11. x = id[(id.length - 1)..(id.length - 1)].to_i
  12. y = id[(id.length - 3)..(id.length - 3)].to_i
  13. return x, y
  14. end
  15. end

Minus the ugly string manipulation, it is a pretty straight forward approach. Now we should be able to start up the application and click on any of the squares and make some moves. There are 2 things left to do for this demo. We need to make sure that a player can not move on a square that is already occupied, and we need to display a winner. So for the first task, we need to write a spec to have some kind of feedback to the players that the move is invalid. Let's add this spec to the props_spec file.

  1. it "should have message center for feedback to the user" do
  2. @scene.find("message_center").should_not be(nil)
  3. end

Nice and simple. Here is the new props.rb file.

  1. main do
  2. board do
  3. 3.times do |row|
  4. 3.times do |col|
  5. cell :id => "cell_#{row}_#{col}"
  6. end
  7. end
  8. end
  9. end
  10. message_center :id => "message_center"

Now lets write a spec for the cell_spec to make sure that the move is valid, else we display a message in the message center to the user they must move somewhere else. Here is the spec.

  1. it "should display in the message center if the space is occupied." do
  2. @id = "cell_0_0"
  3. @cell_one = Limelight::Prop.new
  4. @message_center = Limelight::Prop.new
  5. @scene = MockScene.new
  6. @scene.register("cell_0_0", @cell_one)
  7. @scene.register("message_center", @message_center)
  8. self.stub!(:scene).and_return(@scene)
  9. game = mock('game')
  10. Game.should_receive(:occupied?).with(0, 0).and_return(true)
  11. mouse_clicked(nil)
  12. @message_center.text.should == "This space is occupied, please move in an unoccupied square"
  13. end

Same as before, with a new prop added. Here is the new cell.rb file.

  1. module Cell
  2. def mouse_clicked( event)
  3. game = Game.current
  4. x, y = get_coordinates
  5. if game.occupied?(x, y)
  6. message_center = scene.find("message_center")
  7. message_center.text = "This space is occupied, please move in an unoccupied square"
  8. else
  9. game.move(x, y)
  10. cell_prop = scene.find(id)
  11. cell_prop.text = game.mark
  12. end
  13. end
  14. private ################################
  15. def get_coordinates()
  16. x = id[(id.length - 1)..(id.length - 1)].to_i
  17. y = id[(id.length - 3)..(id.length - 3)].to_i
  18. return x, y
  19. end
  20. end

Simple if, makes it all work. Lets remove the duplication in the specs. Here is the new spec file.

  1. require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
  2. require 'cell'
  3. describe Cell do
  4. include Cell
  5. attr_accessor :id
  6. before(:each) do
  7. @id = "cell_0_0"
  8. @cell_one = Limelight::Prop.new
  9. @scene = MockScene.new
  10. @message_center = Limelight::Prop.new
  11. @scene.register("message_center", @message_center)
  12. @scene.register("cell_0_0", @cell_one)
  13. self.stub!(:scene).and_return(@scene)
  14. @game = mock('game', :occupied? => false)
  15. Game.should_receive(:current).and_return(@game)
  16. end
  17. it "should make first move in a game" do
  18. @game.should_receive(:move).with(0, 0)
  19. @game.should_receive(:mark).and_return("X")
  20. mouse_clicked(nil)
  21. @cell_one.text.should == "X"
  22. end
  23. it "should display in the message center if the space is occupied." do
  24. @game.should_receive(:occupied?).with(0, 0).and_return(true)
  25. mouse_clicked(nil)
  26. @message_center.text.should == "This space is occupied, please move in an unoccupied square"
  27. end
  28. end

Much better. Now lets do the case of a winner. Here is the spec for the cell.

  1. it "should display there was a winner in the message center" do
  2. @game.should_receive(:move).with(0, 0)
  3. @game.should_receive(:is_winner?).and_return(true)
  4. mouse_clicked(nil)
  5. @message_center.text.should == "Player X has won the game, congratulations"
  6. end

And here is the new cell.rb

  1. module Cell
  2. def mouse_clicked( event)
  3. game = Game.current
  4. x, y = get_coordinates
  5. if game.occupied?(x, y)
  6. message_center.text = "This space is occupied, please move in an unoccupied square"
  7. else
  8. game.move(x, y)
  9. cell_prop = scene.find(id)
  10. cell_prop.text = game.mark
  11. message_center.text = "Player #{game.mark} has won the game, congratulations" if game.is_winner?
  12. end
  13. end
  14. private ################################
  15. def get_coordinates()
  16. x = id[(id.length - 1)..(id.length - 1)].to_i
  17. y = id[(id.length - 3)..(id.length - 3)].to_i
  18. return x, y
  19. end
  20. def message_center
  21. return scene.find("message_center")
  22. end
  23. end

Now we can finish off the application by adding new game functionality, or even a computer player that can not be beaten! However, before I let you go, we have to add some styles to the message center and pretty up the board to make it look better. To find a comprehensive list of the styles supported in Limelight, go here(http://limelightwiki.8thlight.com/index.php/Style_Attributes). Here is a new version of the styles.rb.

  1. main {
  2. width "100%"
  3. horizontal_alignment "center"
  4. }
  5. board {
  6. width 152
  7. height 152
  8. border_width 1
  9. border_color "black"
  10. }
  11. cell {
  12. width 50
  13. height 50
  14. border_width 1
  15. border_color "black"
  16. }
  17. message_center_container{
  18. top_margin 100
  19. width "100%"
  20. horizontal_alignment "center"
  21. }
  22. message_center {
  23. width 300
  24. height 100
  25. rounded_corner_radius "10"
  26. border_color "black"
  27. border_width 2
  28. padding 5
  29. }

There was one change to the props.rb file, to wrap the message_center in a prop called message_center_container. Also, notice the pretty rounded corners. Easy to do.

Here is the props.rb

  1. main do
  2. board do
  3. 3.times do |row|
  4. 3.times do |col|
  5. cell :id => "cell_#{row}_#{col}"
  6. end
  7. end
  8. end
  9. end
  10. message_center_container do
  11. message_center :id => "message_center"
  12. end

Happy Limelight coding!

How Paul started coding

by: paul | August 13th, 2008 | 0 comments »

Tagged by Micah Martin

How old were you when you started programming.

I was around 12

How did you get started programming.

Whenever I would visit my grandmother growing up, one of the highlights was she had space invaders on her computer. Once, my Uncle Don saw me captivated by space invaders and decided to show me how computer games/application are written. He pulled up a command prompt in DOS and started writing QBasic code to create a simple application. I was amazed that it was so easy to talk to a computer. I wanted to do it myself.

What was your first language?

BASIC

What languages have you used since you started programming?

Java, C++, C#, SAS, JavaScript, CSS, HTML, Ruby, C, Basic, Python, Assembly Language, Visual Basic, SQL, ASP

What was the first real program you wrote?

In school I wrote a Jabber client in C#. I was impressed by the drag and drop rich client tools in Visual Studio. That lasted about a day.

What was your first professional programming gig?

Working for a client project with Object Mentor. The first team I was on included Micah Martin, David Chelimsky, Tim Ottinger, Dave Astels, Craig Demyonovich, James Grenning, and Dean Wampler. I had more than just a few mentors to learn from. It was an awing experience for me seeing how great coders code.

If there is one thing you learned along the way that you would tell new developers, what would it be?

Play well with others. It takes teams working well together to create most meaningful software.

What’s the most fun you’ve ever had programming?

Working with the 8th Light team on a project. Many times seeing the requirements for a story, I will say to myself, “can that even be done”? After seeing creative solutions from the team, it has taught me if you are working with good people and good tools, there are only endless solutions. The most amusing thing to learn about programming is if something isn’t all ready there, invent it.

Tagging: Adam Wonak, Jim Suchy, Bob Payne

Apprenticeship month one report

by: paul | June 30th, 2008 | 0 comments »

8th Light has an apprenticeship program whereby an 8th Light craftsman will mentor an individual for three months. During that time, the craftsperson becomes responsible for a single apprentice. I am one month into a mentorship with an apprentice. This blog is about observations I have made about myself as a mentor.

Curiosity

He asks me questions that I wouldn’t ask myself. I had him do an exercise about Law of Demeter , to find Law of Demeter violations in my code base. He found something like:

Law of Demeter

“Ted Williams”.to_s.strip.upcase

He was counting the periods, which is what I explained is often good measurement of Law of Demeter violations. Yet this is not a Law of Demeter violation. Each one of those methods returns itself (a string) in a changed state. It is not a string of implementation details- this example is just changing a single object. The pivotal piece of information is that all of these methods on string return the string itself. Also, is anything inside of Ruby core language capable of Law of Demeter? It is unlikely to change, and is there a problem being coupled tightly to your language?

I sometimes get desensitized to the original premises of good development. When I first learn something, I remember the example of the rule more than the value of the rule. The value of learning about Demeter is rooted in encapsulating logic in such a way to hide implementations from an object’s clients. When I first learned about Demeter, all I could do was point out violations. The more I developed, the more it was internalized as a guide for a higher development idea. I want to keep my modules as decoupled as possible. However, that notion only came with development experience. Now I don’t think in terms of violations or non-violations of Demeter when I read a piece of code. It is just ingrained in my developmental context that I should develop my modules in such a way that they are autonomous. This weeds out most Law of Demeter violations by itself. Bringing these premises back up in my development as a craftsman gets my curiosity started. Like a good song or piece of writing, every time I come back to it, I take something different from it, because I am in a state of constant change.

Teaching

Sometimes I forget how important teaching is to the craftsmanship model, because I am still an extreme novice at it. It is one of the steps involved with internalizing development skills. When I pair with my mentor, I am constantly amazed at how he skips steps in the development rational process. Instead of following a linear thought pattern to a solution, it seems there is a giant shortcut in the rational processes I go through. That gap is a lookup table of solutions in his head. It appears so easy and effortless. Teaching is part of a formula that has given him a development context that is superior to mine. The more I am able to teach, the more I internalize the ideas about development.

There is a baseball story from about a year ago. Greg Maddux was warming up before a game and his catcher exclaimed to the pitching coach, “I bet I could catch him with my eyes closed.” Well, after much effort, they convinced Maddux to give it a shot. The catcher was going to call his pitch, then close his eyes. When the ball was about to hit his mitt, the pitching coach with his eyes open was going to yell “now”, whereupon the catcher would squeeze his glove on the ball. Well, on the third try, the catcher caught the ball. The degree of difficulty of the exercise is incredible, but Greg Maddux had spent so many years internalizing the mechanics of his craft that he could effortlessly hit the catcher’s mitt. There probably are only a few pitchers in the long history of baseball who could match that exercise. I am not anywhere near that kind of skill in development, but that is my goal. When you get the mechanics of your craft to be intuition, it frees your mind to think about and solve larger problems. I have been fortunate to spend time with enough great developers to see this mastery in action.

Communication

For me, what is special about teaching is the commitment of thoughts to sound. Forcing something outside of my internal monologue always changes it, even if it is a small change. When I explain something, I often have to explain it multiple ways (this is telling of my communication skills, not of my apprentice’s learning skills). So, the more I am forced to answer questions on the spot, the better I get at quickly thinking through a question and giving a good answer. This dialogue is another one of the mental exercises which translates into my everyday development. It makes me a better pair programmer, better presenter, and better writer. Being able to accurately explain a problem and a solution using the language of software development is a very important tool in being a successful craftsman, and a tool that I fight uphill to improve upon. When I go to a talk at a conference and the presenter hits the problem and solution perfectly, it is a wonderful experience. The same is true when a team member can explain a solution in such intuitive terms that everyone gets it immediately.

Apprenticeship for me is as much about internalizing and expanding my own skill set as it is about expanding my apprentice’s.

###############