I learned recently about min-width and max-width css selectors that allow you to specify certain properties that are applied under a maximum width and above a minimum width. This can enable a flexible layout that works on many different screens without multiple distinct layouts (instead, just CSS). This also makes it relatively easy to spot-test by simply resizing your browser to get an idea of how it will look on different size devices.
This example shows a ‘Watch the Video’ button on screens smaller than 480px wide. Perfect for phones.
<body><divclass='video'><!-- embedded youtube video --></div><divclass='video-alternative'><divclass='btn'><ahref="http://youtu.be/linkylink">Watch the Video</a></div></div></body>
Nifty for a dev guy like me who doesn’t know much about design/CSS :)
When you’re in the same room, often your communication is done via waving at each other, overhearing a conversation, happening by a desk, etc. It’s accidental communication in many cases, and it’s good.
But it can have detrimental side effects to productivity when interruptions can happen at any time. That was the main impetus behind deploying HipChat to our organization–having a way to allow people to communicate without directly interrupting. Let people come to the communication, rather than taking the communication to them
But it did a lot more than that. Suddenly, the developer in Romania and the developer in Florida felt a lot more connected to the team. They were able to participate in daily conversations because there was an IRC style chatroom that let them “overhear” conversations that were occuring. Since we also had lots of github and capistrano hooks in place it also communicated things we were doing to the codebase too.
Then we realized that treating our team as though it was always distributed mad a drastic difference in how we were able to work. Open source teams do this by necessity, but private teams often ignore this idea. With video chat, always-on-chatrooms, mailing lists and bug trackers, you can take most of your communication online where physical location no longer matters and communication is nearly always archived, accessible and referencable.
The benefits are pretty significant:
potentially less physical distraction to your developers
easy reference and review of past communication
fewer decisions made “behind closed doors”
the ability for employees to work from anywhere
the ability to hire employees from anywhere
If you’re interested, I’d highly suggest setting up the following:
A group chat client (HipChat, Campfire, IRC) - make it part of the culture to have it “always on” and to put most of your conversations in there.
A video chat service (Google+ Hangouts, Skype) - use it for standups to keep facetime at a premium for all members of the team
A mailing list or distribution list (optionally) - to encourage open communicaiton among the whole team
Pull Requests are used often in the open source world, but less so on private teams. They are a great way to provide an automatic, team-wide code review mechanism. If your private team doesn’t use pull requests, I’d encourage you to investiage it.
Why would you move your team over to pull requests?
it provides a mechanism for code and source control review
it gives more visibility and accountability to the whole team
you can (optionally) restrict access so only trusted members bless the merge
If you want to restrict access, have developers fork your repository from github. Otherwise, you can simply submit pull requests from feature branches.
From the release branch, the developer creates a feature branch, does work, and pushes it to their fork
From github, the developer can click the “pull request” button on that branch, github even has a “recently pushed branches” section now!
From there the developer can review the pull request commits and diff to confirm conciseness and clarity.
After submission, anyone with read access to the main repository can review and comment on the pull request (including inline comments)
What makes a good pull request?
This is a much harder question to answer, since it is, in fact, subjective. However, I do think there are some good guidelines nearly any team could follow.
A Good Pull Request is…
Concise - Less than 200 changed lines. Preferably less than 50. If you need more to solve your problem, break your problem into smaller pieces.
Clean - It follows the “single responsibility principle” in the fact that it’s only solving one problem.
Related to a Ticket - Since it’s only solving one problem, that problem should be documented in a ticket in whatever bug tracking system you have.
Tested - Some kind of automated test should be included within all but the most trival pull requests. This provides increasing coverage and tests to document and prove the problem is fixed.
Pull Requests have changed the way our team does work. If you are on a private team and arent’ using them, I’d highly recommend trying it out on one of your projects.
About a week ago, we had an elusive error that appeared when we deployed our latest app to staging. Suddenly, any submission resulted in a “Stack trace too deep” error that gave no meaningful way to determine where the issue was coming from. We were stuck for a couple of days, but then I was reminded of git bisect.
git bisect is a great way to trace down problems to a specific commit for purposes of isolation or blame (though I’d suggest against the latter). Like you’d expect from a programmer, it even searches efficiently, using a binary search, hence bisect.
Fundamentally, what bisect does is split the commits from the latest good commit to the earliest bad commit in half over and over again until one commit has been isolated which transition occurred.
Let’s say that you were a terrible developer and didn’t run your tests before checking in. After several days of doing this, you run your spec suite and get an unhelpful error which prevents the spec suite from even being run. Since you don’t know when that was introduced, you use git bisect
1234
$ git bisect start
$ git bisect bad # marks the current commit as bad$ git bisect good production #marks the commit pointed to by 'production' (branch or tag) as goodBisecting: 62 revisions left to test after this (roughly 6 steps)
Now you are in the middle of bisecting. You can then attempt to run specs (or manually test for an error) and mark the commit accordingly
12345678910
[3939bac050b2779d5d13a3757054511eb0f8961a] Update Rakefile to point to sensible server.
$ rake spec
ERROR! ...
$ git bisect bad
Bisecting: 31 revisions left to test after this (roughly 5 steps)[f2230b2e2ccf636266891ce6be3750994f414fe4] Fixing Issue #2294$ rake spec
....... ^C
$ git bisect good
...
You continue until you’ve isolated the commit…
123456
$ git bisect good
1c675b26e5b8472d28d3fb44a23119ba41e7002c is the first bad commit
commit 1c675b26e5b8472d28d3fb44a23119ba41e7002c
Date: Wed Apr 4 16:11:40 2012 -0500
Adding support for Guard
Then you can look at that commit and address it specifically. This is a huge argument for small commits, especially when you’re looking for small, difficult to find bugs related to subtle business logic.
When you’re done, just git bisect reset and you’ll be back on your HEAD.
You may be asking if you could do this manually – and then answer is an absolute YES, but bisect provides a very simple and easy way to step through the process without a lot of extra thought or effort.
I had a Rails 2.3.X app that I migrated to Rails 3. When I did, I upgraded CanCan and Devise. Suddenly, my delete links weren’t working. I remembered that unobtrusive JS was the default so I hopped into the application.html.erb template and added the relevant javascript tags.
Great! Now my delete links weren’t just links to the show action, but when I did click them I noticed that a CanCan error appeared. After some debug statements, it became clear that current_user wasn’t set, but only on the POST/DELETE methods. Hmmm. What could be causing this?
Yes! The csrf tags!
If you’re upgrading to Rails 3 and you see odd behavior on POSTs with the session (anything that tries to protect_from_forgery), make sure you have this line in the head section of your application layout.
You want to always use the “pessemistic” version numbers for a handful of reasons.
12
gem 'rails', '~> 3.0.3'
gem 'rspec', '~> 2.7.0'
This allows the most efficient resolution of gem dependencies (in this case, any version of rails from 3.0.3 up to and not including 3.1, and any version of rspec from 2.7.0 up to and not including 2.8) and the added benefit of allowing you to easily patch everything safely using only bundle update.
You also want to be familiar with the various levels of ‘conservatism’ in updates.
123
bundle install # once the Gemfile.lock exists... most conservative
bundle update <gem>[ <gem>] # only update specified gems
bundle update # update all gems to latest validly specified versions
This allows you to properly patch everything and keep your gems in proper sync in the most efficient manner.
You should also update to bundler 1.1 since it uses a much faster API call to download the latest index of gems and dependencies from rubygems.org. Yay, faster bundler!
If there is one thing I have said over and over again in one form or another, but never seem to learn completely, it’s “Always Fight for Simpler.”
Everything could be simpler. Sure, we think it can’t, but it can. Don’t assume you need a feature in an app, a gadget in your life, or a certain amount of money… fight first for simpler.
Ask yourself, for any given situation, what the simplest possible solution to the problem is. Maybe it’s not good enough… but maybe it is. Fight for the simplest solution and go from there.
Simple doesn’t always mean cheap, fast, easy, or perfect. Simple means it lacks complexity. Simple means it depends on few other things. Simple means less instead of more.
About three or four times a year, I find myself wishing my application wasn’t so complicated. I wish I was some stud developer who always made the right architectural decisions and didn’t back myself into a corner. I read about OO ideas regarding change management and coding for change even when you don’t know what that change is and mostly, I find myself baffled.
Hindsight is 20/20. I can see easily how the decision that seemed good at the time to make a Model.seed! method that allowed you to specify all the department data in the database AND change it in the app was a bad idea. I can see that allowing users to change values of reports from within the reports, like a spreadsheet without using the adjustment-as-a-line-item pattern is now a bad idea… but we’re 3 years on and it’s just not something we’re going to be able to convince the users to change or the management to invest the money in fixing.
Then I ran across one of the best tweets ever. from @jeremyckahn - “All codebases are abominations. They are all terrible. If your codebase isn’t a disaster, it probably doesn’t do anything interesting.”
It’s so true. Remembering that you’ll always make some wrong choice when designing a complex app helps you to be able to cope with the pile of technical debt that has accumulated. Making poor choices because you’re lazy is one thing, but making poor choices because you don’t have the experience or expertise is quite another thing entirely.
If you don’t think your code is crap, you’re probably doing it wrong, or you haven’t been doing it long.