Last updated: 2008-05-07T15:43:06Z
Dirty object functionality has been in edge rails for a month now, allowing you to see what changes have been made to an object prior to saving it. Here's an example from Ryan's edge rails blog -article = Article.find(:first)article.changed? #=> false# Track changes to individual attributes with# attr_name_changed? accessorarticle.title #=> "Title"article.title = "New Title"article.title_changed? #=> true# Access previous value with attr_name_was accessorarticle.title_was #=> "Title"# See both previous and current value with attr_name_change accessorarticle.title_change #=> ["Title", "New Title"]Dirty objects should be available with the next release of Rails. Unfortunately, you need it in your Rails 2.0 project right away and can't wait. Well, you're in luck; adding this functionality to a Rails project turns out to be dead simple thanks to Dirty being a nicely decoupled module.Here's what you need to do:Download the source for dirty.rb from http://dev.rubyonrails.org/browser/trunk/activerecord/lib/active_record/dirty.rb?rev=9127. I'm specifically picking revision 9127 because later versions incorporate partial updates (also new in edge rails), which complicates matters.Once you've got the file create a directory called active_record under RAILS_ROOT/config/initializers and copy dirty.rb into it. Thus, if your project is under /home/work/myproj, the path to dirty.rb should be /home/work/myproj/config/initializers/dirty.rb.Reopen active_record and mixin Dirty. Do this by creating a file called active_record.rb under RAILS_ROOT/config/initializers and putting the following bit of code in it:require "#{File.dirname(__FILE__)}/active_record/dirty"ActiveRecord::Base.class_eval do include ActiveRecord::DirtyendThere, you're all set. Note that Rails automatically loads files under config/initializers - you can put these files elsewhere in your project, but make sure you tell Rails to pick them up and that the paths are alright. It is also possible that Dirty Objects may break some plugins, acts_as_audited being a case in point.
Last updated: 2008-05-07T14:15:06Z
Quoting Cleartrip's about section, "Cleartrip is dedicated to making travel simple". So simple that you can easily buy tickets worth thousands of rupees. And then lose thousands of rupees by clicking the 'Cancel Booking' link by accident.ClearTrip is so easy to use that it apparently doesn't believe in confirmation dialogues - your booking will simply be canceled. Cool, what? The good Mr. Narla just lost Rs. 8000/- this way. That's what I call usabilty in action.UpdateLooks like cleartrip.com isn't bad at all once you get past the call centre. Narla contacted them via the feedback section of their website and this elicited a very quick response. They've been exceptionally helpful and have offered to refund Rs. 4000, half the cancellation charge due. This is pretty decent of them, keeping in mind the fact that cleartrip.com cannot recover the cost (it's already been canceled at the airline). Good stuff!
Last updated: 2008-05-06T05:31:00Z
Back in January of 2006 I wrote about Using Stubs and Mocks to Convey Intent. In those days I was working mainly with C# and NMock and the simplest way to create a stub was to allow ReSharper generate a stub based on an Interface. This introduced a bit more effort when first generating the stub and added complexity around where the stubs should live and how they should be used. Despite the additional effort, I still felt that using them was a net gain.Things are very different in the Ruby world. While using C#, Dependency Injection was something I used religiously; however, using Ruby I can simply stub the new method of a dependency. C# had hurdles that made stubbing controversial; however, using stubs in Ruby tests is basically seamless thanks to Mocha. Mocha makes it easy to Replace Collaborators with Stubs, but you shouldn't stop there--you should also Replace Mocks with Stubs.Replacing Mocks with Stubs is beneficial for several reasons. Stubs are more concise. One of the largest problems with tests is that they can be overwhelming the first time you look at them. Reducing a 3 line mock definition to stub(:one => 1, :two => 2) is almost always a readability win.Stubs are great, but you may need to use a mock to verify behavior. However, you don't need to verify several behaviors in one test. Using a single mock to verify specific behavior and stubbing all other collaborations is an easy way to create tests that focus on essence. Following the One Expectation per Test suggestion often results in using one or more stubs... and more robust tests.Using stubs is a good first step towards concise and relevant test code; however, you can take stubs a step further. Mocha defines a stub_everything method that creates an object which will return nil to any message it doesn't understand. The stub_everything stubs are fantastic for dependencies that are used several times, but you are only interested in specific interactions. The interactions which are unimportant for the current test no longer need to be defined.Stubs can be even more valuable if you are interested verifying a single interaction but are completely uninterested in all other interactions. In that case it's possible to define a stub_everything and set an expectation on it. Consider the following sample code.class MessageService def self.deliver(message) message.from = current_user message.timestamp message.sent = Gateway.process(message) enddef test_the_message_is_sent Gateway.stubs(:process).returns(true) message = stub_everything message.expects(:sent=).with(true) MessageService.deliver(message)endSince the expects method is defined on Object you can set expectations on concrete objects, mocks, and stubs. This results in a lot of possible combinations for defining concise behavior based tests.Lastly stubbing can help with test essence by allowing you to stub methods you don't care about. The following example defines a gateway that creates a message, sends the message, and parses the response. class MessageGateway def process(message_text) response = post(create_request(message_text)) parse_response(response) end def post(message) # ... end def create_request(message_text) # ... end def parse_response(response) # ... endThe Gateway#process method is the only method that would be used by clients. In fact, it probably makes sense to make post, create_request, and parse_response private. While it's possible to test private methods, I prefer to create tests that verify what I'm concerned with and stub what I don't care about. Using partial stubbing I can always test using the public interface.def test_create_request gateway = MessageGateway.new gateway.expects(:post).with("<text>hello world</text>") gateway.stubs(:parse_response) gateway.process("hello world")enddef test_post gateway = MessageGateway.new gateway.stubs(:create_request).returns("<text>hello world</text>") gateway.expects(:parse_response).with("<status>success</status>") gateway.process("")enddef test_parse_response gateway = MessageGateway.new gateway.stubs(:create_request) gateway.stubs(:post).returns("<status>success</status>") assert_equal true, gateway.process("")endThe combination of partial stubbing and defining small methods results in highly focused tests that can independently verify behavior and avoid cascading failures.Mocha makes it as easy to define a mock as it is to define a stub, but that doesn't mean you should always prefer mocks. In fact, I generally prefer stubs and use mocks when necessary.© Jay Fields - www.jayfields.com
Last updated: 2008-05-06T00:33:30Z
I’ve only thought of blogging about Lois Vuitton once before and that was on how they positively encourage queueing outside their stores during busy periods. It’s a pretty strong brand that can tell its customer to hang about before being allowed to come in and shop.
This time I’m not blogging about them in a positive light, and nor are many others. Jeremiah Owyang describes the situation they are in well. Their brand has been hijacked by Nadia Plesner, an artist trying to raise awareness about Darfur and how the media considers Paris Hilton with her “designer bags and ugly dogs” to be more worthy of attention than genocide in Darfur. She uses an image of a LV bag in her T-shirts. LV take offence and sue, she refuses to budge and suddenly the image, the issue and LV all hit the spot-light. And in this David and Goliath contest, who is going to come out worst? There can only be one looser.
So why didn’t LV just ignore it, or even as Jeremiah suggests, harness the issue, turn it into a conversation that would paint them in a good light? I’ll argue that it is because they don’t understand risk.
There was always a risk to the brand be de-valued by being associated by asociation with Dafur. And this is what the marketing and legal team jumped on with such zeal. Did no-one think about the risk to the brand of turning this into the issue it has become on the web? Laying out the options and doing a risk analysis would have been a worthy exercise.
Option 1. Assess the global impact of nadia plesner, assume it is minimal and do nothing. Risk to brand: minimal.
Option 2. Follow standard route of brand defamation and sue. Ignore association with ‘good cause’, ignore blogosphere. Risk to brand: potentially significant.
Sadly, it seems that LV ignored the whole concept of risk and went with the default option - sue. They are not alone in failing to assess the risks properly before pursuing a course of action. In IT this approach is endemic. Where is the greater risk? Placing all your eggs in one basket, investing heavily in a desired outcome that will be many months before it sees the light of day. Or take a more gradual approach, investing ‘just enough’ to get ‘just enough’, ‘just in time’. The latter approach is lean and agile. A good agile project is a lesson in risk management, building resillience into the process and testing options as you go. It is organic and evolutionary, (rather like nature), as opposed to the plan and control approach of waterfall which is brittle and will struggle to react to or accommodate risk appropriately. I should write more but there is a day’s work ahead.
Last updated: 2008-05-05T12:58:31Z
Via
Mark Graban,
Mike Thelan writes about the difference between a true understanding of Lean versus what is typically believed is Lean.
I think it's a worthwhile article and Mike closes with a quote from Konusuke Matsushita which the
Poppendieck's are also fond of:
We will win, and you will lose. You cannot do anything because your failure is an internal disease. Your companies are based on Taylor’s principles. Worse, your heads are Taylorized, too. You firmly believe that sound management means executives on the one side and workers on the other, on the one side men who think and on the other side men who only work.
So if I reframe this in a positive way...
Your success can be based on an inherently superior philosophy embedded in your internal beliefs. If you firmly base your company on sound management, meaning engaging everyone in thinking about how to work, then you will win... and inevitably so.


Last updated: 2008-05-05T12:56:09Z
When you think or hear "That's the way things are done here"...
When you have that sense that you're about to accept imperfection...
You interrupt with "Why?"... repeatedly until you understand the root cause... and then you address it.


Last updated: 2008-05-05T12:25:10Z
Solve the problem that's there not the one they tell you is there.


Jake Scruggs http://www.blogger.com/profile/16274380203959781950 noreply@blogger.com :
Employee Appreciation
Last updated: 2008-05-04T17:01:57Z
As a consultant, I spend a lot of time at big companies and big companies generally have a morale problem. Bureaucracy, cubicles, and lax management will tend to do that. Typically they try to solve this problem by exchanging money for goodwill. A few projects ago I was consulting at one such company where they spent a ton of money having a day of games, burgers, and events during business hours. There was a big ad campaign, lots of promotional tie-ins and give-aways -- a team of people clearly worked on this for weeks (or maybe months). Now add up productivity, food, and sumo-suit rental costs and we are talking some serious money. All worth it in service of employee good will, right?
A few days after this spectacle, my team and I decided to walk to lunch. Now the most direct route to our restaurant of choice happened to be through the front door. However, the security guy stopped us when we tried to leave. Employees aren't allowed to enter or leave through the front door. Why? That's the policy.
So we backtracked, went out another door, had lunch, and came back. At which point we discovered that our badges wouldn't let us in the side doors. So we tried another side door. No luck. We went around to the front where we found out that security had turned off our badges intentionally so that we would have to go in the front door and get a lecture from the head security guy. I'm not kidding. 3 grown men got a talking to for trying to exit through the front door.
Later we heard, informally, that the company wants to keep the front entrance looking nice so that's why employees may not enter or leave through the front door. The obvious implication here is that visitors would be put off by the sight of employees walking in through the same door as them. Does anyone really believe that one day of corporate sponsored fun is likely to make up for the daily humiliation of having to enter through the back door of your own company?
Jake Scruggs http://www.blogger.com/profile/16274380203959781950 noreply@blogger.com :
Employee Appreciation
Last updated: 2008-05-04T17:01:57Z
As a consultant, I spend a lot of time at big companies and big companies generally have a morale problem. Bureaucracy, cubicles, and lax management will tend to do that. Typically they try to solve this problem by exchanging money for goodwill. A few projects ago I was consulting at one such company where they spent a ton of money having a day of games, burgers, and events during business hours. There was a big ad campaign, lots of promotional tie-ins and give-aways -- a team of people clearly worked on this for weeks (or maybe months). Now add up productivity, food, and sumo-suit rental costs and we are talking some serious money. All worth it in service of employee good will, right?
A few days after this spectacle, my team and I decided to walk to lunch. Now the most direct route to our restaurant of choice happened to be through the front door. However, the security guy stopped us when we tried to leave. Employees aren't allowed to enter or leave through the front door. Why? That's the policy.
So we backtracked, went out another door, had lunch, and came back. At which point we discovered that our badges wouldn't let us in the side doors. So we tried another side door. No luck. We went around to the front where we found out that security had turned off our badges intentionally so that we would have to go in the front door and get a lecture from the head security guy. I'm not kidding. 3 grown men got a talking to for trying to exit through the front door.
Later we heard, informally, that the company wants to keep the front entrance looking nice so that's why employees may not enter or leave through the front door. The obvious implication here is that visitors would be put off by the sight of employees walking in through the same door as them. Does anyone really believe that one day of corporate sponsored fun is likely to make up for the daily humiliation of having to enter through the back door of your own company?
Last updated: 2008-04-30T12:33:14Z
Continuous integration was one of the original twelve XP practices introduced in Kent Beck's book
Extreme Programming Explained, back in 1999. It was designed to solve a specific and acute problem in the software development process: making sure that when an individual developer completes new functionality, or makes a change to the code, the software as a whole still works. Continuous integration requires that every time a developer writes some code, he or she builds the software and runs some tests on a non-development environment to make sure that his or her changes haven't broken anything. If done manually this process can be error-prone and time consuming, so it needs to be automated. The upshot is that to do continuous integration well, you need an automated build and a set of automated tests, and once the team is large enough, a continuous integration server to run them for you every time a developer submits code. Thus, CruiseControl and its many siblings were born.
However, the problem that continuous integration solves is only a part, albeit an important one, of a greater problem: how to get software that satisfies its functional requirements actually working in production. The part of the software development process between an application being functionally complete and releasing it into a production environment is known as the "last mile" (the opening chapter of the
ThoughtWorks Anthology covers this issue in more detail). If sufficient effort has been put into preparing for a production release during the development process, the last mile can take seconds or minutes. However at ThoughtWorks we have been called in to projects where it takes weeks or even months.
This phenomenon has several causes. First of all, any kind of deployment of a complex application — whether or not to a production environment — is difficult. When an application is first deployed to a non-development environment, or when there are significant changes in the application or its environment, it is usual for all kinds of bugs to be exposed. When the application undergoes user testing, further issues are often discovered, such as violations of non-functional requirements. These problems have to be fixed, and the whole process repeated until the application is stable enough to be deployed into production. If deployment to testing environments is hard, it's a good bet that production release will be risky. The options open to you when a production deployment goes wrong are usually very limited — in most cases, backing out is the best option — and downtime costs money. This leads most organizations to be extremely conservative about production releases. This in turn means that releases don't happen very often, which translates to big changes in process between releases, which means the risk doesn't decrease over time. These various factors combine to make releasing applications expensive and slow. Your release process can be the difference between being a market maker and a late entrant.
There is a solution to the problem of the last mile. It is regular, automated deployment and testing of your software in a production-like environment — and ultimately, into production itself. In this paradigm, which we call the deployment pipeline, software is built and then passes through a series of tests — unit tests, functional tests, performance and other non-functional tests and user acceptance testing — before being deployed into staging and then production. The benefits of putting in place an automated
deployment pipeline are huge, and ThoughtWorks has been helping companies to solve their last mile problems with this technique for several years. In one organization we turned a deployment process that took days into one that took less than 15 minutes and resulted in split-second downtime, with full rollback, through automating the release process. This had positive knock-on effects throughout the delivery phase of the software lifecycle, making it a push-button process to prepare testing environments. This in turn reduced defects and proved out the deployment process, significantly reducing the risk of performing releases. As a result releases became more frequent and required less effort, freeing up the teams to concentrate on what they wanted to be doing: developing new features.
That's why we at ThoughtWorks Studios have been working to bring you
Cruise. We wanted to create a tool that embodies the best practices we have learned through years of solving the last mile problem for our clients. Cruise provides you with an engine that lets you implement deployment pipelines simply and intuitively. It uses a robust, reliable architecture that allows you to scale pipelines across your whole operation by creating fault-tolerant grids of hardware so you can parallelize your long-running builds and test your software on a variety of different platforms. It includes an artifacts repository to manage binaries, reports and other artifacts. And because we are committed to making continuous integration and automated deployment an ubiquitous industry-best practice, we will be offering a one-agent free edition of Cruise which gives you all the features of the commercial edition, as well as free licenses to open source projects, non-profits, and academic institutions.
The other major roadblock to a low-risk deployment is writing a sufficiently comprehensive automated test suite. That's why ThoughtWorks Studios has created
Twist, a testing IDE that makes creating functional tests a snap for analysts and business users. This, in combination with Cruise's ability to run test suites in parallel to minimize cycle time, will provide a powerful and simple solution to the problem of the last mile.