Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Monthly Archives: May 2009

Pivotal Labs

Tuesday 5/5 standup

Pivotal Labs
Tuesday, May 5, 2009

Help

No Helps today.

Interesting

Beware of using OpenStruct. It is very slow to create instances. Evidently it defines a new class for every instance created. When you need to create lots of instances of a struct-like object, use Struct.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Railsconf: In Praise of Non-fixtured Data – Kevin R. Barnes

Pivotal Labs
Tuesday, May 5, 2009

Fixtures Suck

When modeling complex business domains, not 3 model blog software, fixtures quickly become a quagmire. What’s the size of your domain? Kevin was working on a project with 180 models. This quickly became unworkable even with only 1 fixture file per model. Fixtures don’t scale well. Scenarios are also problematic as now you have to maintain a directory hierarchy of fixtures.

Use Data Generation instead

Factory Girl

# Define

Factory.define :user do |f|
  f.first_name 'John'
  f.last_name  'Doe'
end

# use

user = Factory(:user)

Object Daddy

Reopens your ActiveRecord class and adds generators for each attribute.

# define

class User << ActiveRecord::Base

  generator_for :username, :method => :next_user

  generator_for :email, :start => 'test@domain.com' do |prev|
    user, domain = prev.split('@')
    user.succ + '@' + domain
  end
end

# use

@user = User.generate!

Others

Machinist

Foundry

Fixjour

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Railsconf: Don't mock yourself out – Dave Chelimsky

Pivotal Labs
Tuesday, May 5, 2009

Martin Fowler says Mocks Aren’t Stubs and talks about Classical and Mockist Teting. Dave shows slightly amusing set of photos about “ists” – Rubyists etc. Ist bin ein red herring. The big issue here is when to use a mock.

Overview of Stubs and Mocks

Terminology: test double – an object standing in for a real object (like a stunt double).

customer = Object.new
logger = Object.new
customer.stub(:name).and_return('Joe Customer')
logger.should_receive(:log)

customer.should_receive(:name).and_return('Joe customer')
# bad - very tightly bound to implementation

customer.stub(:name).and_return('Joe customer')
# also tighly bound to implementation
  • Stubs are often used like mocks, mocks used like stubs.
  • We verify stubs by checking state after an interaction.
  • We tell mocks to verify interactions.
  • Sometimes stubs just make the system run.

When are method stubs helpful?

Isolation from non-determinism: Simulate random value geneators or Time.now.

Isolation from external depedencies: e.g. external database or network. Have gave anexample or an ActiveMerchant test that takes 1.5s to run, and stubbed out gateway.stubs(:authorize).returns(AM:Billing:Response.new(true, ‘ignore’)

Polymorphic collaborators: e.g. employee that knows how to pay itself, uses a strategy. paymet_strategy = mock() employee = E.new(p_s)
p_s.expects(:pay)
employee.pay

mixins/plugins

When are messsage expectations helpful?

side effects: background processing

caching: only call a network zipcode lookup once

validator = mock()
zipcode = Zipcode.new("01234", validator)
validator.should_receive(:valid?).with("01234").once
zipcode.valid?
zipcode.valid?

interface discovery: tool to discover the parts of the system that you haven’t really worked out yet. Mock something out that doesn’t exist yet, while designing its interface.

Isolation Testing

All of these concepts are Isolation Testing – testing an object in isolation from others. This is a good fit when you have lots of little objects (ravioli code, as opposed to spaghetti code).

Isolation Testing in Rails

Rails is calzone code. Three layers: View Controller Model. These 3 layers are not the whole picture: browser, router, database. Standard rails testing:

  • Unit tests: Testing in isolation. Test model classes (repositories), model objects, database.
  • Functional tests: 2 or more non-trivial components work together. Test model classes, model objcets, database, views, controllers.
  • Integration tests: Test model classes, model objects, database views controllers, routing/sessions.
    This is !DRY

Mocking and stubbing you can do in Rails

Partials in view specs:

before :each do
  template.stub(:render).with(:partial => anything)
end

...

template.should_receive(:render).with(:partial => 'nav')

Conditional branches in controllers: Stub new and save! methods of models.

Dave has a new project stubble on github: You will need to build RSpec locally to use this for now.

stubbing(Registration) do
#  Stubs ActiveRecord finder and save methods on model

Chains are a new RSpec feature: user.stub_chain – some people say this is a test no-no, use with caution.

Guidelines, concerns & Common Pitfalls

  • Keep things simple
  • Try to avoid tight coupling
  • Complex setup is a red flag for design issues
  • Don’t stub and mock the object that you are testing
  • Concern: impedes refactoring (but some say refactoring is improving design without changing behavior, so tests should not change. This really depends what level you are refactoring at).
  • Concern: false positives
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

AutoTagger 0.9 released

Pivotal Labs
Tuesday, May 5, 2009

I’m happy to announce that AutoTagger 0.9 has been released thanks to Brian Takita and Mike Grafton. This resolves a few major issues and brings AutoTagger a big step closer to being ready for prime-time.

You can read more at http://github.com/zilkey/auto_tagger.

You can install the gem like so:

gem sources -a http://gems.github.com
sudo gem install zilkey-auto_tagger

Thanks Brian and Mike!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Railsconf 2009 DHH Keynote

Pivotal Labs
Tuesday, May 5, 2009

Looking Back

This year is the 5th/6th year he has been working with Rails. What hasn’t changed is worth looking at. Things are moving fast at a micro level, but not at a macro level. Stop fretting about whether you are
up to date with the latest features. His 5 year old code might have some old idioms, but generally is still working and doing the same thing.

Mortal wounds that are supposed to have killed Rails

Not Enterprise Ready “You may have noticed that pretty much everyone on the Ruby camp are insultants with many of them being book authors attempting tp capitalize on hype” – James McGovern. Lesson: You can’t win over over everyone in the world with better logical arguments.

Find the One Thing to make Rails work Sails, Biscuit Grails Monorail – all claimed to have found “The Formula” to make Rails work. Later proven to be a wothless exercise. Lesson: Most worthwhile things in the world can’t be boiled down to one thing.

Waves of Pushback “7 reasons I switched back to php after 2 years on Rails” – Derek Sivers. Communities erupted for 2 days. Lesson: Comments on Reddit don’t change peoples minds.

The Fail Whale – “Rails doesn’t scale”. Some memes are so increadibly powerful and it is useless to fight them. Rails actually has a poster-boy that is one of the most talked about sites of our time. We can take the bad with the good. People can be both proud of things and annoyed at them at the same time.

We’re still here

We have the same core principles we had 5 years ago. Take it easy. Chill out. Most of these things don’t matter as much as you think they do, and the importamnt pieces of them will be extracted and used.

The Philosophy of Rails 3

Lock up all the unicorns: Rails 3 is not going to be a complete rewrite and is not going to solve evertbody’s problems. Not everyone is going to get the wonderful feature (unicorn) they want.

No holy cows: No “that is the way it has to be”. That was a mistake the Rails team made in that past and what caused Merb to come into existence. Concrete example: alias_method_chain. Nothing is holy in Rails and if you have an idea that is going to break every Rails app in the world, if it is good enough, it is on the table.

Have it your way: (a la Burger King). How many questions do you get asked when you order a burger. Mot people just want to eat; They just want to get their applications done. On the hand if you really hate pickle, you get to make that choice.

Rails 3 Progress

New Router

Faster. Route by subdomains, user agents, more. Route to other Rack machinery.

resource :projects, :controller => :project do
  resource :attachments
  resources :participants do
    put :update_all, :on => :collection
  end

  resouces :companies do
    resources :people
    resource :avatoar
  end
end

Note no block variables. Uses instance_eval to make a cleaner DSL. There goes a holy cow (not using instance_eval in Rails DSLs). Still questioning if this is a good idea. Enjoys the asthetics of this.

XSS protection

(Refresher: Allows someone to inject JS code into your public pages, then steal cookies and do other bad things). Old:

=h (html_escape)

New: By default everything will be escaped in views.

=raw

"random_string".html_safe!

(ed: Yahoo! – Security on by default!)

JavaScript goes unobstrusive & agnostic

No more inline onclicks. Adopt HTML5 approach to having custom attributes.

<a href="/comments/1" data-remote="true" data-method="delete">Destroy</a>

<a href="/comments/1" data-confirm="true"

- form_for(@comment, :remote => true) do

Under the covers:

$(document.body).observe("click", function(event) {
  // javascript
});

More Agnosticism

Action ORM – a shim layer on top of all the ORMs.

Generators – make generators smarter about whether they are using RSpec etc.

The Great Refactoring

Things you probably won’t notice. Cleaing up a lot of old code. Abstract Controller + Action Dispatch. Active Relation underpins Active Record. Cherry picking from Active Support. Speedy callbacks.

The real secret to high productivity

The humorous bit. What were the elements/principles that made him so productive back in the old days working on BaseCamp. One thing: Renegotiate requirements. Don’t treat requirements as stone tablets. Suggest a better way. “Sure, whatever” – Stakeholders everywhere.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Monday 5/4 standup

Pivotal Labs
Monday, May 4, 2009

Help

Feed Validation: There are a couple of options for validating feeds.

  • http://feedvalidator.org: You can enter a URL and view the validation results. Pretty self explanatory. However, we can’t figure out how to get it to access resources that are protected with basic auth. If you like, you can download the validator and run it locally at http://feedvalidator.org/docs/howto/install_and_run.html
  • Google Feed Reader API: A great resource is the Google Feed Reader API. Rather than rehash too much here, browse over to Niall Kennedy’s post for a great introduction to the API and how to use it.

Firefox shortcuts for bookmarks: In Safari, you can use shortcuts like Apple-1 to load the first bookmark. Is there an equivalent for Firefox?

Interesting

Nothing interesting to report today. Check back tomorrow.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Pivotal Tracker Tip: Organizing with Labels

Joe Moore
Sunday, May 3, 2009

At Pivotal Labs, our clients, customers, and developers love Pivotal Tracker; after all, we wrote it and selfishly kept it to ourselves for 2 years! With that much history, some of our Tracker projects have built up thousands of stories, and keeping these stories organized is a challenge. Luckily, we designed Tracker with a simple yet powerful organizational tool: Labels. Here are some labeling patterns we find useful.

Label Stories with Feature Set Name

How many Stories, Bugs, and Chores make up that big Facebook integration feature set, anyway? Which stories are related to the big UI version 3 update? Simply label everything related to a feature set with an easy-to-remember name. This is especially helpful when different pairs or teams are focused on certain groups of features.

Labels for Features

Bug Priority Labels

It’s true that Tracker doesn’t have the traditional bug categories of P0, P1, P2, to PN. We tend to simply prioritize the most important or critical bugs higher than those less critical, but you can simply create the Labels for bug priorities. That said, there is one Label we almost always create to categorize a subset of bugs — want to guess what it is? If you guessed “ie6″ then you feel our pain!

Labels for Bugs

Labels for Communication

We often use labels to communicate the state of a Story beyond it’s delivery status. For example, a Story we don’t understand that was added by a remote project manager can be labeled “needs discussion.” A bug that we can’t duplicate might be labeled as such. Designers will want to know which UI stories “need assets.” Team leads and project managers are especially interested in seeing any Story labeled “blocked.” Of course, Labels are not intended to replace actual person-to-person communication — talk to each other!

Labels for Communication

Watch out for Label Spam

While Labels are a powerful tool to quickly view the state of the world, don’t go too Label crazy. Labels are not intended to be a discussion forum, flame war, or dumping ground for thoughts.

Label Spam

Labels and Saved Searches Panel

The Labels and Saved Searches panel brings this all together; activate it at View => Labels and Searches. A picture’s with a thousand words, so check out the following screenshots to see just how powerful Labels are for organizing your project.

Label Panels

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Adam Milligan

Pondering a low grade slump (4)

Adam Milligan
Sunday, May 3, 2009

The concept of flow holds a mystical, holy place in the lore of software development. Nearly any programmer can tell you about being “in the zone,” totally immersed in code, oblivious to the passage of time. Countless programmers have cited this apparently hyper-productive state when stating their need for enclosed office space, separation from their colleagues, working from home, working at night, or any other similarly isolated work situation.

I’m not going to dispute the existence of a flow state; I’ve experienced it myself. I know the feeling of looking up after solving an interesting problem to find that fourteen hours have passed, it’s the middle of the night, and I haven’t eaten anything since the previous morning. I’ve felt the satisfaction of burying myself in ideas until finally finding a way to convert them into code.

However, I will suggest that working in isolation in order to promote a flow state is not the most productive way to write software. It’s better than working in an environment filled with distractions unrelated to the task at hand, but less productive than working in a collaborative space, or pair programming. To illustrate this, consider another, simpler task that also often involves working in a flow state: cruciverbanalysis.

There’s no such word, of course, but if there were I’d like to think it would mean solving crossword puzzles (a cruciverbalist is someone who constructs crossword puzzles, hence a cruciverbanalyst would be someone who solves them; much like the relationship between cryptographer and cryptanalyst).

Standard American-style crosswords depend on uncertainty for their trickery; many of the clues can have two or more answers. As an example, consider the clue “put away.” The answer could be any of “EAT,” “STOW,” “STORE,” “HOARD,” “JAIL,” or a synonym for any of these. The answer could also be the past tense of any of these answers, since “put” can be either past or present tense.

Thus, to find the correct answer for one clue you have to consider the answers to the clues that cross (or “check,” in crossword parlance) the letters for that clue. But the answers to those clues may depend on the answers to yet more clues, or the possible answers to the original clue. So, the solver has to build a mental picture of the puzzle with possible answers for each clue, as well as the interactions between them. As you might imagine, it takes some time to build up this mental picture, and a great deal of concentration to maintain it. Interruptions, distractions, and time away from the puzzle all quickly destroy it. In short, crossword solvers often work in a flow state.

However, there are a number of ways that a solver can fail to complete a puzzle:

  • The clues require knowledge of specific facts that you don’t know.

I dislike this type of clue, because you either know the answer or you don’t; there’s no wordplay or clever trick to figure out. If you know that the capital of Mali is Bamako, or that John McCormack was Dame Nellie Melba’s preferred tenor, then good on you. But, if you don’t know, then you’d better hope you know the answers to all of the checked clues.

Think about when this happens while you’re writing code (it happens to everyone, you’re not omniscient). You come across an API you don’t know, an unfamiliar area of the code, or a language feature you haven’t used before. You’re stuck. You can take the time to look it up, but that takes time and interrupts your flow anyway. If you’re working with someone, such as a pair, who does know the answer, then you keep moving forward without a hitch and learn the answer in the process.

  • You don’t get the trick.

Lots of crossword clues try to play on your assumptions to lead you down the wrong path. For example, the clue “Hall of fame” probably makes you think of the Baseball Hall of Fame, or something similar, but the answer could be “ANNIE.” The clue “Peter, Paul, and Mary” probably makes you think of the musical group, but the answer could be “SAINTS” or simply “NAMES.” Infrequently, puzzles will go outside the boundaries of the English alphabet to add to the trickery. Consider an eight letter answer for “The city of brotherly love.” You have to use Greek letters to get the correct answer: “(phi)LADEL(phi)A.”

If you miss the trick, you can’t get the answer. Having more than one person, with more than one viewpoint, looking at the clues will greatly increase the chance that you’ll see all the possibilities.

Designing software well requires choosing a correct approach to each problem. You can’t choose the right approach if you don’t think of it. Sometimes starting a conversation with “I’m thinking of solving problem X with approach Y, what do you think?” can be the best possible use of your time. Someone with a fresh perspective, or just a different perspective, might suggest a better approach than the one lodged in your mind. It’s up to you to set aside your ego long enough to accept the new approach, but that’s a different blog post.

  • You go down the wrong path.

Truly insidious crossword clues not only attempt to lead you to the wrong answer, they try to lead you to a wrong answer with the same number of letters as the right answer. In some cases the wrong answer will have some of the same letters in the same positions as the right answer, increasing your confidence that the wrong answer is, in fact, correct. This wrong answer will then give you the wrong letters for checked clues, leading to more wrong answers. Once you start down this dark path, it’s very, very difficult to recover. This is, incidentally, why crossword enthusiasts insist on solving in pen: you have to be certain before you write in an answer. Otherwise you have to keep everything in your head, which adds to the challenge.

In software, as in solving crosswords, this is a path you do not want to go down. Once you choose the wrong approach (for example, using inheritance where it isn’t appropriate), subsequent decisions take this into account. It can be very difficult to figure out where the true problem lies once you do run into a brick wall. Having someone question your design decisions, or offer alternatives, can help to avoid going down the wrong path to start with. And, when you do have to backtrack, you absolutely want to involve someone with a fresh perspective. Another person, free of your assumptions, will more likely see the misstep.

Finally, consider that crossword puzzles are far simpler than software: there’s only one correct answer to any puzzle (with one notable exception). Software problems can have any number of workable solutions, with various trade-offs that make each more or less appropriate in a given situation. Also, working on any software project of significant size is really more like working with multiple people to solve several puzzles which check against one another in various dimensions. As the complexity of interactions increases, I’d expect the advantages of collaboration to increase at least linearly.

For those who would still argue that flow is necessary because it’s how programmers prefer to work (it can be quite enjoyable), I’d suggest you get yourself a book of crosswords. With puzzles you can sit by yourself and exercise your flow state as much as you like without spending anyone else’s money, or making anyone else’s life more difficult.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Quick Tip: Viewing Gradients and Transparencies in OS X Preview

Joe Moore
Friday, May 1, 2009

As web developers in the Web 2.0 world, we work with transparencies and gradients all the time. Sometimes we get a bunch of assets from a designer and can’t easily see how the visual assets are constructed: what parts are transparent? Is the background grey or transparent? How drastically does a gradient fade? Get some answers quickly by tweaking OS X Preview.

Tip #1: Show Image Background

These four images from OS X have a lot of grey in them, making it hard to see the transparencies and gradients.

Grey Backgrounds

Tell Preview to show the image’s background in View => Show Image Background so you can at least see the dimensions and transparencies. But, this leaves a lot to be desired since it’s still pretty hard to see the grey pieces.

Show Image Backround

Tip #2: Change Background Color

I like this one even better: change Preview’s window background color to something something that definitely will now show up in your images by going to Preview => Preferences => Window Background. Here I’ve chosen “Tangerine” and you can very easily see the dotted lines in ftvpnode.png and might be surprised to find out that the bottom part of user_14.png is not actually a transparent gradient, but a grey gradient.

Window Background

Hope that helps!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Standup 05/01/2009: JQuery ajax POST with no data; Git "ours" merge strategy is destructive; New Relic RPM GEM problems; Collectl; MySQL Analyze Table

Pivotal Labs
Friday, May 1, 2009

Help

  • JQuery ajax post with no data: If you use JQuery to POST with no data element, it will work fine in development mode (with mongrel) but Nginx will will respond with a HTTP 411 “Length Required” response code, as JQuery is not adding a Content-length header. This solution is to add an empty data hash to the call. Anybody have a better solution? Post-standup-research: Several People have encountered this issue and spoken of filing it as a JQuery bug, but I could find no followup that it got filed or fixes.

Interesting

  • Git merge strategy “ours” is destructive: When doing a git merge that causes a conflict, picking “ours” as the merge strategy causes git to choose our changes for ALL files, not just those with a conflict, i.e. it ignores the changes in the other branch. From git-merge(1): “ours”: This resolves any number of heads, but the result of the merge is always the current branch head. It is meant to be used to supersede old development history of side branches.

  • New Relic RPM GEM problem: We encountered a case where using the GEM version of RPM in a project caused no telemetry to get logged. This may be an interaction with Desert or Geminstaller (or the GEM may be broken but we consider that unlikely). After switching from the GEM to the plugin, everything worked fine.

  • Collectl is a system performance data gathering tool. From it’s website: “Unlike most monitoring tools that either focus on a small set of statistics, format their output in only one way, run either interatively or as a daemon but not both, collectl tries to do it all.” Kinda like sar+top and user friendly too.

  • MySQL Analyze Table – no substitute for Explain: From the MySQL 5.0 docs: “ANALYZE TABLE analyzes and stores the key distribution for a table. MySQL uses the stored key distribution to decide the order in which tables should be joined when you perform a join on something other than a constant. In addition, key distributions can be used when deciding which indexes to use for a specific table within a query.” Sounds great huh. However we found a case here where using FORCE INDEX to get a select statement to use the right index caused a 2 order of magnitude speed increase. Moral: There is No Substitute for Explain and a Brain.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (780)
  • rails (113)
  • testing (88)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (55)
  • techtalk (44)
  • rspec (38)
  • ironblogger (32)
  • productivity (30)
  • activerecord (29)
  • gogaruco (29)
  • git (28)
  • nyc (27)
  • rubymine (26)
  • bloggerdome (23)
  • mobile (22)
  • process (21)
  • pivotal tracker (20)
  • cucumber (20)
  • jasmine (19)
  • design (18)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • tracker ecosystem (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • css (13)
  • tdd (13)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to Community Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 7
  9. 8
  10. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >