-
Alfred — I mostly use this as an application-launcher and file-opener.
-
AppZapper — Uninstalls apps completely (along with its extra files).
-
Balsamiq — Wireframing on the desktop.
-
Boom — Boost your Mac’s volume. Especially useful for Movies downloaded on iTunes which tend to be too quiet on the speakers.
-
Caffeine — Toggle your Mac’s ability to go to sleep on and off. Useful during presentations.
-
Cloak — Simple VPN to secure your connections on public wifi.
-
Soulver — Calculator on steroids. And crack.
-
DayOne — Beautiful journal.
-
Divvy — Awesome window management tool. I used it to arrange windows on my large monitor.
-
Evernote — To jot stuff down on the go.
-
Fantastical — Menu-bar calendar for convenient access.
-
Flint — Campfire client. We use campfire as our group chat.
-
f.lux — Adjusts your screen’s color temperature to match the sun.
-
GoToMeeting — For screensharing and conferences.
-
LittleSnapper — Organize screenshots of stuff you like.
-
MindJet — Mindmapping.
-
OmniGraffle — Diagramming tool. There’s a huge ecosystem of stencils and templates available. Many use it for wireframing & UX.
-
OpenOffice — Faster than Microsoft Office sometimes.
-
SizeUp — Defines keyboard shortcuts to arrange windows and split the screen in two.
-
MacVim — Desktop version of the popular terminal text editor.
-
Adobe Creative Cloud — Photoshop, Illustrator, and all the other Adobe apps in one SaaS package.
-
Fluid — This is one of my favorite apps. I creates a .app file that launches a predetermined URL, essentially creating a desktop version of the web app. I use it for Pivotal Tracker.
-
Adium — I use this for GChat and AIM, but it supports a range of other protocols.
-
Skype
-
Reeder — The best RSS Reader out there.
-
Cloud — Drag and drop file sharing.
-
Skitch — This used to be great (I still have version 1.0.11). The newer versions have gotten horrible reviews.
-
iAWriter — Distraction-free minimalistic editor with Markdown support.
-
Byword — Very similar to iAWriter.
-
PathFinder — Finder replacement. I never use the standard finder anymore.
-
Hazel — Create rules and actions for file processing. I recently started using this to group my scanned files into folders based on year and date.
-
Google Chrome — My web browser
Let’s say you have an application where a User can subscribe to a Channel. With ActiveRecord associations, it would look something like this:
# app/models/subscription.rb
class Subscription < ActiveRecord::Base
belongs_to :channel
belongs_to :user
end
# app/models/user.rb
class User < ActiveRecord::Base
has_many :subscriptions
has_many :users, through: :subscriptions
end
# app/models/channel.rb
class Channel < ActiveRecord::Base
has_many :subscriptions
has_many :users, through: :subscriptions
end
Unfortunately, someone forgot to add dependent: :destroy to the has_many :subscriptions. When a user or channel was deleted, an orphaned subscription was left behind.
This issue was fixed by dependent: :destroy, but there was still a large number of orphaned records lingering around.
There are three ways you can use to remove the orphaned records.
Approach #1 — Bad
Subscription.find_each do |subscription|
if subscription.channel.nil? || subscription.user.nil?
subscription.destroy
end
end
This executes a separate SQL query for each record, checks whether it is orphaned, and destroys it if it is.
Approach #2 — Better, but still pretty bad
Subscription.all.each do |subscription|
if subscription.channel.nil? || subscription.user.nil?
subscription.destroy
end
end
This loads all records into memory, and then iterates over them performing the same check as above.
Approach #3 — Good
Subscription.where([
"user_id NOT IN (?) OR channel_id NOT IN (?)",
User.pluck("id"),
Channel.pluck("id")
]).destroy_all
This approach first gets the IDs of all Users and Channels, and then executes one query to find all Subscriptions that don’t belong to either a User or a Query.
Benchmarks
Let’s take a look at how long it takes in each case.
When you run it on 2596 subscriptions, out of which 1058 are orphaned, you get:
user system total real
bad 3.020000 0.160000 3.180000 ( 4.058246)
better 2.950000 0.170000 3.120000 ( 3.982329)
good 0.010000 0.000000 0.010000 ( 0.030346)
Even as the number of subscriptions is reduced, Subscription.all.each remains faster than Subscriptions.find_each, because it performs less SQL queries.
With 10 subscriptions, the results were
user system total real
bad 0.010000 0.000000 0.010000 ( 0.022374)
beter 0.010000 0.010000 0.020000 ( 0.017584)
good 0.010000 0.000000 0.010000 ( 0.014330)
Conclusion
Approach #3 is a whopping 134 times faster than approach #1.
While the time difference in our scenario was only 4 seconds, it could be hours for millions of records.
This demonstrates how important refactoring is to the development process. Refactoring your code furthers your understanding of the technologies you work with. It also illustrates how important it is to minimize the SQL queries performed within your web application. If this was an action initiated by the user, the difference in the request time would be 4.02 seeconds vs. 30 ms.
First, focus on the first field of the form when it loads. This allows the user to start typing right away, go through the form with the TAB key, and sign in faster. I see a lot of forms that don’t do that, and don’t even allow you to jump to the first field with the TAB key, forcing you to perform an additional action by grabbing the mouse and clicking inside the field.
Second, don’t clear the entire form when the user does not authenticate successfully. If I typed my password incorrectly, I should not have to retype my email address as well. When the user does not authenticate completely, leave all information except for the password intact, and focus on the first field.
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
This is a pain to type each time, so I made it an alias in my .zshrc:
alias git-clean-merged-branches='git branch --merged | grep -v "\*" | xargs -n 1 git branch -d'
Easy, right?
The perfect response to the old ‘I need a technical co-founder’ email.
- If you want to snag a developer you’re going to have to bring some value to the table. The developer is going to be asking himself, “why do I need you to execute this idea?” I could just build it myself..
- So, either you need to:
- Have some way to pay the developer.
- Have an impressive track record of expertise / success in the relevant industry.
- Have considerable technical skills.
- Have considerable design skills.
Finally, Facebook made the move to (more) native iOS.
Today we’re announcing an update to the Facebook app for iPhone and iPad that makes keeping up with friends faster and easier. Facebook 5.0 for iOS is twice as fast as the previous version when launching the app, scrolling through news feed and opening photos in feed.
I just tried it out — it is much faster. Perfect example of when native is a much better choice than HTML5 & JavaScript.
I’m attending Frozen Rails 2012, a Ruby on Rails conference in Helsinki from September 20-21st, 2012. If you’re going to be there, get in touch, I love meeting fellow developers. If you’re not going — you should. The speakers are great.
We’re cleaning up a project that has loads of unused files and CSS rules. This nifty trick I found on Pivotal Blabs uses git to check whether your images are used anywhere in your git repository, and removes them if they’re not.
for FILE in $(git ls-files ./app/assets/images); do
git grep $(basename "$FILE") > /dev/null || git rm "$FILE"
done
Head over to Pivotal Blabs for the full post.
Vim has reduced me to a pathetic teary wreck every time I have to use a text editor that isn’t vim.
Vim is awesome. I also wrote this in Vim.
I’m fairly convinced this is what the next iPhone will look like. If true, this design will be noteworthy for being the first unibody iPhone, making it the thinnest, strongest, and lightest housing to date.
I definitely want one.
A stub replaces a method with code that returns a specified result.
let(:user) { User.create! }
controller.stub(:current_user).and_return(user)
A mock is a stub with an expectation that the method gets called.
User.should_receive(:find).with(1).and_return(user)
require 'net/http'
AWS::S3::Base.establish_connection!({
access_key_id: 'your-access-key-id',
secret_access_key: 'your-secret-access-key'
})
# Use the Google Logo as an example
#
url = URI("https://www.google.com/images/srpr/logo3w.png")
Net::HTTP.start(url.host) do |http|
resp = http.get(url.path)
AWS::S3::S3Object.store(File.basename(url.path), resp.body, 'yourbucketname', access: :public_read)
end
Finally, all my dreams have come true:
Today, we are launching into public beta two new plans: Crane and Kappa. These plans are part of our production tier, offering the same monitoring, operations, support, and data protection features as our more expensive plans.
Crane is available for $50 per month and features a 400 mb cache. Kappa is $100 per month and features a 800 mb cache.
I have a ton of apps for which the shared database is too slow, but the $200 Ronin database is too expensive. These two plans fill the gap perfectly.
Here are my favorite things about Backbone.js:
It’s lightweight
Backbone.js weighs in at 16.3 KB (minified), it’s dependency Underscore.js at 12.2 KB.
It makes your apps faster
Rendering views in Rails is slow. By using Rails as an API, you can spread the rendering workload on your user’s browsers, rather than putting it all on your servers. The result? - blazing fast applications that are easy to cache. Diasporate rewrote their newsfeed with Backbone and loved it.
One of the most frequent requests from my clients is higher speed. Nobody wants to wait for a page to reload to see their changes anymore.
It doesn’t force anything on you
There are many ways in which you can use Backbone.js. You can write a completely client-side application that communicates to the back-end via a JSON API. Or you can enhance your existing pages with dynamically loaded resources, such as sidebars.
It pushes you towards a cleaner separation between data and presentation.
Your controllers become responsible for just one thing: delivering data. That makes them incredibly easy to test. Code that’s easy to test is easy to change and maintain.
It’s extensible
Even if you’re not a JavaScript wizard, Backbone.js is trivial to extend. There’s already a solid library of plugins out there.
You are a web programmer. You have users. Your users rate stuff on your site. You want to put the highest-rated stuff at the top and lowest-rated at the bottom. You need some sort of “score” to sort by.
Evan Miller describes an accurate scoring algorithm and how to implement it.
The critical part of rubber duck problem solving is to totally commit to asking a thorough, detailed question of this imaginary person or inanimate object. Yes, even if you end up throwing the question away because you eventually realize that you made some dumb mistake. The effort of walking an imaginary someone through your problem, step by step and in some detail, is what will often lead you to your answer. But if you aren’t willing to put the effort into fully explaining the problem and how you’ve attacked it, you can’t reap the benefits of thinking deeply about your own problem before you ask others to.
My iPad 2 version of this post has been extremely popular for the last year. It’s time for the same choice with the iPad 3 (a.k.a. the “third-generation iPad”).
Sometimes, you need to quickly clone your production database to your local environment. Taps is an option, but at 10 minutes, it’s way too slow for some of my databases.
The faster option is to create a Postgres dump for your database, download it, and import it locally. Initially, I used this code, which lived in each project’s readme, and copied it into the terminal.
heroku pgbackups:capture --expire --remote production
curl -o latest.dump `heroku pgbackups:url --remote production`
pg_restore --verbose --clean --no-acl --no-owner -h localhost \
-U azolotov -d project_development latest.dump
rm latest.dump
That’s better, but not good enough, because the snippet has to be modified for each project, and user who uses it.
The better solution
I wanted a short script that is run with one command. It should have sensible defaults that can be overriden and gather all information from it’s environment.
Here’s what I came up with:
#!/usr/bin/env ruby
module Heroku
class Db < Thor
method_option :keep, :type => :boolean, :default => false
method_option :remote, :type => :string, :default => "production"
method_option :host, :type => :string, :default => "localhost"
method_option :user, :type => :string, :default => `whoami`
method_option :dbname, :type => :string
method_option :dump, :type => :string, :default => "latest.dump"
desc "clone", "clone a remote heroku database to the local environment"
def clone
puts "Cloning production database to local environment. This might take a few minutes\n"
puts "(1/4) capturing production database snapshot..."
puts `heroku pgbackups:capture --expire --remote #{options[:remote]}`
puts "(2/4) downloading snapshot..."
puts `curl -o #{options[:dump]} \`heroku pgbackups:url --remote #{options[:remote]}\``
puts "(3/4) restoring snapshot..."
puts `pg_restore --verbose --clean --no-acl --no-owner -h #{options[:host]} -U #{options[:user]} -d #{options[:dbname] || dbname} #{options[:dump]}`
unless options[:keep]
puts "(4/4) cleaning up..."
puts `rm #{options[:dump]}`
else
puts "(4/4) skipping cleaning..."
end
end
no_tasks do
def dbname
YAML.load_file('config/database.yml')["development"]["database"]
end
end
end
end
Thor
I use thor because it’s very lightweight and makes passsing options to the script a breeze. From thor’s description:
Thor is a simple and efficient tool for building self-documenting command line utilities. It removes the pain of parsing command line options, writing “USAGE:” banners, and can also be used as an alternative to the Rake build tool. The syntax is Rake-like, so it should be familiar to most Rake users.
Usage
Make sure you have thor installed
gem install thor
Put the script in your Rails root directory, and run it with
thor heroku:db:clone
Assumptions
- The production application lives under the git remote
production.
- The database host is localhost.
- The database user is the same as the currently logged in user.
- Import into the
development database as specified in config/database.yml.
- We don’t need the dump file after importing it.
Configuration
If those assumptions don’t match your environment, you can override them:
To keep the dump file after importing it:
thor heroku:db:clone --keep
To change the name of the remote:
thor heroku:db:clone --remote staging
To change the name of the user:
thor heroku:db:clone --user bob
Frankly, the professional experience I have had with TSA has frightened me. Once, when approaching screening for a flight on official FBI business, I showed my badge as I had done for decades in order to bypass screening. (You can be envious, but remember, I was one less person in line.) I was asked for my form which showed that I was armed. I was unarmed on this flight because my ultimate destination was a foreign country. I was told, “Then you have to be screened.” This logic startled me, so I asked, “If I tell you I have a high-powered weapon, you will let me bypass screening, but if I tell you I’m unarmed, then I have to be screened?” The answer? “Yes. Exactly.” Another time, I was bypassing screening (again on official FBI business) with my .40 caliber semi-automatic pistol, and a TSA officer noticed the clip of my pocket knife. “You can’t bring a knife on board,” he said. I looked at him incredulously and asked, “The semi-automatic pistol is okay, but you don’t trust me with a knife?” His response was equal parts predictable and frightening, “But knives are not allowed on the planes.”
Great and insightful account of everything that’s wrong with the TSA by a former FBI agent and counter terrorism specialist.
By controlling the quality and relevancy of the sites on our network, we preserve the integrity of the network’s target audience. Sites and services on Fusion are the best in their class – chosen based on their exceptional content and established readership.
Fusion Ads is an ad network only displays ads on a small number of hand-picked blogs of
designers, developers, publishers, creative professionals, and tastemakers in tech-related circles.
So there you go, someone has done all the hard work of curating a list of great writers for you. Go on, check them out.