Yehuda Katz is a member of the Ruby on Rails core team, and lead developer of the Merb project. He is a member of the jQuery Core Team, and a core contributor to DataMapper. He contributes to many open source projects, like Rubinius and Johnson, and works on some he created himself, like Thor.

@garybernhardt @steveklabnik I guess I have to ask… is cls a troll project?

Archive for July, 2010

Everyone Who Tried to Convince Me to use Vim was Wrong

A couple weeks ago, I took the plunge and switched to vim (MacVIM, to be precise). It wasn’t the first time I tried to make the switch, and I had pretty much written it off entirely.

Why? Because the past few times I tried switching to vim, I took the advice of a master vim user, and quickly sunk into the quicksand of trying to learn a new tool. In every prior attempt, I gave vim a few days before I gave up. And every time, I managed to get virtually no work done the entire time, spending about 90 percent of my day fighting with my editor (a more charitable way to put it would be “learning my editor”).

Invariably, the master vim users that were helping me make the switch would encourage me to stick it out. “If you just give it a few weeks, you’ll never want to switch back.”

The trouble was, I had work to do. I could only switch editors if the new editor did not significantly impede on my day-to-day work. I can already hear the responses: “That’s simply impossible. It’s a new editor designed for advanced users. You’ll just have to put up with the pain until you get used to it.”

Here’s the thing, though: I didn’t really have to put up with a huge amount of pain when switching to Textmate for the first time. In fact, it was downright pleasant.

The last few times someone tried to get me to switch to vim, I issued them a simple challenge. Can you tell me a way to switch that will not significantly reduce my productivity for the first few weeks. It wasn’t a challenge that was intended to fully shut down discussion. When I really thought about it, Textmate wasn’t doing all that much for me. It was a glorified Notepad which had working syntax highlighting and understand where to put the cursor when I hit enter (most of the time).

I don’t actually use “snippets” all that often, or all that many “commands”. I don’t mind the extensibility of Textmate, but I’m not a hardcore Textmate hacker myself, meaning that I’m ok with any editor that has the same level of extensibility that Textmate has (namely, all of them).

Despite what I considered a relatively reasonable request, my challenge was met with disdain and even anger by most of the people I talked to. “If you feel that way, Vim probably isn’t for you.” “You’re learning a new EDITOR for God’s sakes. Of COURSE there’s going to be a learning curve.”

I had written off the entire sorry affair.

A few weeks ago, Carl told me that he was playing with Vim. His explanation was that he had seen a number of people be really productive with it, and he was curious. Carl is definitely willing to put up with more pain to learn something new than I am, so I issued the same challenge to him.

Perhaps because he wasn’t steeped in hardcore vim hacker lore, he didn’t angrily dismiss the entire premise of my question. Thinking about it a bit more, I realized that most of the people who had tried to get me into vim had suggested that I dive in head first. “First thing: turn off the arrow keys.” “Don’t use the mouse. Force yourself to use the keyboard.”

Carl convinced me to use vim for the first couple of days pretty much exactly as I use Texmate (with the exception of having to switch between normal and insert modes). I installed NERDTree on MacVIM, grabbed the most common vim “packages”, and was off to the races. (I should note that I installed topfunky’s PeepOpen, which definitely helped with a very common workflow that I find it hard to live without).

For the first day, I clunked around by using my mouse’s scroll wheel, clicking and highlighting things, and spending most of my time in insert mode. It was slightly less productive than Textmate, but mostly in the range of what I’d expect switching to a new tool. In short, while I felt a bit out of sorts, I was able to get plenty of work done that first day.

As the days went on, I learned a few commands here and there. The first big one for me was ci as in ci " (it means: replace what’s inside the next set of " and go into insert mode). This singlehandedly made up for most of the productivity losses I was feeling from learning a new tool. Throw in o, O, A, :N and /search and I was already quite a bit more productive than I had been in Textmate.

Sure, I’m still plodding around in some cases, but only a handful of days later, using Textmate for anything feels clunky (most commonly, I try to use o or O to insert a new line above or below the one I’m currently on).

I was able to get here because I used my mouse wheel and button, arrow keys, apple-f to find text, apple-s to save files, and a whole slew of other common idioms, instead of grinding to a halt and trying to switch all of my practices at once.

To those who would say “that’s obvious; of course you learn vim incrementally”, I would simply say that having spoken to a number of vim users in the past, I never got that advice. Instead, I got a lot of advice about turning off my arrow keys, disallowing the use of the mouse, and learning the (MORE EFFICIENT!!!) vim ways to do everything, all at once. People just couldn’t stomach the idea of me continuing to use an outmoded practice (like apple-f) when vim had much better tools available just a (huge volume of) memorization away.

To those who are considering using vim, my recommendation is to use MacVIM, NERDTree, PeepOpen (or command-t), and use the mouse, arrow keys, and familiar OSX’isms all you want. Very quickly, it will become obvious that there’s a better way to do all kinds of things, and you can pile on the newly found efficiency once you’ve successfully made the switch without losing the ability to do work in the short-run.

What’s New in Bundler 1.0.0.rc.1

Taking into consideration the huge amount of feedback we received during the Bundler 0.9 series, we streamlined Bundler 1.0 significantly, and made it fit user expectations better.

Whether you have used bundler before or not, the easiest way to get up to speed is to read the following notes and go to http://gembundler.com/v1.0 for more in-depth information.

(note that gembundler.com is still being updated for the 1.0 changes, and should be ready for the final release).

Starting a new project with bundler

When you generate a new Rails application, Rails will create a Gemfile for you, which has everything needed to boot your application.

Otherwise, you can use bundle init to create a stub Gemfile, ready to go.

First, run bundle install to make sure that you have all the needed dependencies. If you already do, this process will happen instantaneously.

Bundler will automatically create a file called Gemfile.lock. This file is a snapshot of your application’s dependencies at that time.

You SHOULD check both files into version control. This will ensure that all team members (as well as your production server) are working with identical dependencies.

Checking out an existing project using bundler

After checking out an existing project using bundler, check to make sure that the Gemfile.lock snapshot is checked in. If it is not, you may end up using different dependencies than the person who last used and tested the project.

Next, run bundle install. This command will check whether you already have all the required dependencies in your system. If you do not, it will fetch the dependencies and install them.

Updating dependencies

If you modify the dependencies in your Gemfile, first try to run bundle install, as usual. Bundler will attempt to update only the gems you have modified, leaving the rest of the snapshot intact.

This may not be possible, if the changes conflict with other gems in the snapshot (or their dependencies). If this happens, Bundler will instruct you to run bundle update. This will re-resolve all dependencies from scratch.

The bundle update command will update the versions of all gems in your Gemfile, while bundle install will only update the gems that have changed since the last bundle install.

After modifying dependencies, make sure to check in your Gemfile and Gemfile.lock into version control.

By default, gems are installed to your system

If you follow the instructions above, Bundler will install the gems into the same place as gem install.

If necessary, Bundler will prompt you for your sudo password.

You can see the location of a particular gem with bundle show [GEM_NAME]. You can open it in your default editor with bundle open [GEM_NAME].

Bundler will still isolate your application from other gems. Installing your gems into a shared location allows multiple projects to avoid downloading the same gem over and over.

You might want to install your bundled gems to a different location, such as a directory in the application itself. This will ensure that each application has its own copies of the gems, and provides an extra level of isolation.

To do this, run the install command with bundle install /path/to/location. You can use a relative path as well: bundle install vendor.

In RC1, this command will use gems from the system, if they are already there (it only affects new gems). To ensure that all of your gems are located in the path you specified, run bundle install path --disable-shared-gems.

In Bundler 1.0 final, bundle install path will default to --disable-shared-gems.

Deployment

When deploying, we strongly recommend that you isolate your gems into a local path (using bundle install path --disable-shared-gems). The final version of bundler will come with a --production flag, encapsulating all of the best deployment practices.

For now, please follow the following recommendations (described using Capistrano concepts):

  • Make sure to always check in a Gemfile.lock that is up to date. This means that after modifying your Gemfile, you should ALWAYS run bundle install.
  • Symlink the vendor/bundle directory into the application’s shared location (symlink release_path/current/vendor/bundle to release_path/shared/bundled_gems)
  • Install your bundle by running bundle install vendor/bundle --disable-shared-gems