Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Rubies and Bundles - switching from RVM to rbenv (hmarr.com)
48 points by hcm on Nov 8, 2012 | hide | past | favorite | 23 comments


Why manage something manually when there are good tools to abstract it away in to the background? That's kind of the feeling I get when using rbenv + bundler.

Let me predicate this by pointing out that I manage a lot of Ruby projects (many are old) that require a wide variety of Ruby and gem versions. Obviously my solution isn't the best for everyone. Some developers will never have to worry about conflicting gem versions, because they work primarily on one project with one set of dependencies. The incremental value of the items I'm about to point out don't represent significant value to them. Enough with the disclaimers.

Bundler has the ability to alter your Ruby env variables so that you can easily install and execute gems from any location. This is the feature that allows you to use completely different gems across many projects without any conflicts. As the author suggests, you can pass a path at the time you invoke `bundle install` as a means to specify this location. This allows you to segregate gems to avoid conflicts. The author also points out that the trade-off is "one annoying side effect: any binaries that are installed (e.g. rspec, foreman, cap) are no longer available in your shell’s path". Bummer. I wonder if there's a way around that? Hey, we could manage our environment so that these items are in our path, but remain segregated. We could even write some tidy scripts that automate it for us. Enter RVM.

This is why I don't understand the drive to move to rbenv for developers who need these features. I use RVM and bundler all the time. RVM doesn't preclude the use of bundler, and bundler doesn't make RVM obsolete. When I establish an RVM gemset and .rvmrc, I've abstracted away all the '--path=./.somebundledir' and `bundle exec` nonsense. I only think about it once, then I'm free to use the tools without additional cruft. I'm probably happier than I should be that I can type `cap staging deploy:pending` instead of `bundle exec cap staging deploy:pending`.

If you don't need gemsets, or you're only managing a very small number of Ruby projects, I suppose I can understand wanting a simpler tool, but I don't find RVM terribly complex. A lot of people will say "choice is good", but principle applied without cause isn't good, it's just pedantic.


Perhaps it wasn't clear enough, but the post pointed out that typing 'bundle exec' and explicitly using --path isn't necessary. Once you've added one item to your PATH, and two lines to your bundler config file, you don't need to think about it ever again, it just works. If you want all your gems in one place, simply remove the BUNDLE_PATH line and change the BUNDLE_BIN directory to whatever you want (presumably something within your home directory).

I don't want to get in to the rbenv vs RVM debate - they're both good tools and it's an issue that has been done to death. I linked to five articles in the post, and you can find many, many more with a simple Google. My personal motivation for switching was that bundler's overridden 'cd' function includes some commands that fail, which is fine under most circumstances but it breaks as soon as you use 'set -e' in bash. We spoke to the author and he said he said that RVM wouldn't be 'set -e' compatible in the foreseeable future.


To be clear, my goal is not to sway your decision, but to provide an informed discussion for those making the evaluation. Whether we want it to be, it is an rbenv vs RVM debate, because those are the tools we're evaluating.

My observation is that rbenv users often tack on additional ad hoc solutions to arrive at the same convenience provided by RVM. The primary objection I hear to RVM is the `cd` override, which is optional.


RVM is complicated internally (overwrites commands like "cd" with it's own shell functions etc.) and this tends to turn into user-facing problems again and again, I spent several hours getting it to run on my computer and I know other people who had a similar experience. I guess rbenv is much more independent from the environment you run it in.


I've never found it necessary to use the --path or --binatubs options with rbenv.

For --path, I just use the default which presumably puts everything in the main rbenv folder for gems. I've never had a problem with this.

For the problem of having to type "bundle exec" before every command that uses a binary from a gem, I've heard of two alternative solutions. One is aliasing "bundle exec" to "be" or something to make it quicker to type. The other is using zsh/oh-my-zsh instead of bash and using a plugin (can't remember the name off the top of my head) that automatically figures out what should be bundle execed and takes care of it behind the scenes. I've never had trouble with this either.


The issue with not using --path is that gems will leak between different projects, so you'll probably run in to trouble when projects depend on different versions of the same gem.

I've also used shell plugins to remedy the bundle exec issue, but they've often caused more problems than they solve. I'd much rather just stick something in my PATH than use shell plugins.


I find it much easier to simply explicitly require a specific version in my Gemfile if I'm having trouble with a gem, rather than having the extra overhead of managing multiple sets of gems.

I think it's a more correct solution as well. You won't have any guarantees that Bundler will resolve the dependencies correctly in production when it doesn't in your development environment.


That's also a good approach. The moving the bundler binstubs to a central location would work nicely as well, I imagine.


Absolutely.

I'm using oh-my-zsh with the bundler plugin, which aliases all binstubs to a function that prepends bundle exec if there's a Gemfile. It works very well in practice. rbenv handles the correct ruby version, Bundler loads the right gem, and it all falls back to the newest version on the system default ruby.

It's a few more moving parts behind the scenes than I'd prefer, but once configured it's completely transparent.


Isn't this solved by storing Gemfile.lock? I thought that was the whole purpose of that file..


Sometimes the simpler solution is the more complex tool -- if that's what everybody already uses and if it already works. Just like RVM.


I've used them both and found rbenv's Just Works factor to be higher for me, personally. There's definitely enough people out there using both tools that neither can be said to be the one that "everybody is already using".


:) I mean "everybody is already using" in the context of most dev area, including my own.

Here's how it usually works: We're coasting along with some tool and doing well, then some dev announces that we're ALL WRONG because another tool is better. Sometimes the tool he's announcing is something like git when we're using TFS, and we switch. Other times, say RVM vs. this right now... I just don't see a big gain.


I hear you. I never had any "real" issues with RVM other than I probably never really learned how to use it, so it kept tripping me up. (I'm not very good at this stuff..)

I was setting up a new computer a few months ago and decided to give rbenv a try and it hasn't given me any reason not to like it so far. Just guided someone on the west coast who has never worked with Ruby before through installing it and getting her first Rails project up and running last night, via approximately 65 emails. Does that make me an advocate?


If the python community felt this way we'd all still be using easy_install and installing our libraries at system root.


I'm not saying it's always the rule. It depends on the context. If the context is a group of Ruby/Rails devs who are efficiently building applications in exchange for money, and the new(er) tool is one that:

1.) Ends with the same net result for the developer, and 2.) Adds a little bit of complexity on setup and rules around use, then

why switch? I'm perfectly willing to trade up my development tools, but I want a better net gain before I switch.

Perhaps that net gain will be to keep up with a growing number of devs who use it? We'll see.


You can use the right tools in the wrong way and be productive. You're still using them wrong. Most people use Bundler and RVM gemsets in a way that Bundler wouldn't even be needed. Rbenv forces you to learn the proper way of project management and it actually reduces complexity once people get over the small learning curve of using the correct tools for each thing. Bundler manages dependency, Rbenv just switches rubies. RVM adds so much more that it blurs the lines between things.


> Rbenv forces you to learn the proper way of project management and it actually reduces complexity once people get over the small learning curve of using the correct tools for each thing.

Boy did you overreach on this one. What about rbenv constitutes the "proper way" versus a tool like RVM? If the argument is that RVM abstracts away too much of the underpinnings, then you've just a made a philosophical argument that is in conflict with much of the work that we do as developers.

RVM is simply an environment manager. One should always understand the environment that they're managing, but using tools to increase the efficiency of that management is not in violation of the "proper way". If abstraction of underlying complexity is bad, we shouldn't be using bundler, rbenv, or even init scripts and package managers. We should start all system processes with the direct invocation and build and install software by hand, lest we not learn the "proper way".

If we accept that abstraction is not necessarily a bad thing, then we can recognize that there's nothing about rbenv that is any more "proper" than RVM, and we can all use the tools we prefer.

I prefer not to have to append '--path=./somedir' every time I run `bundle install`.

I prefer not to have to prepend 'bundle exec' to every shell tool in my toolchain.

I prefer to have all my rubies and gemsets organized in a single location instead of spread out across my projects.

I understand that by using RVM a background process is altering my environment. I also know how to run `rvm info`, read the output, and understand the terms.

Those are my preferences. They're no more right (or wrong) than yours.


You're talking about huge degrees of difference between easy_install and what came after vs rvm vs rbenv.

Personally, I never have trouble with rvm. It works great despite a little magic and I like the way that I can use it without having to worry about installing bundler, installing binary shims, etc.

Speaking of attitudes affecting the Python community, does it have anything approaching the ease of use of rbenv or rvm yet?


Just a little plug, I wrote this language-agnostic environment loader: http://direnv.net . Unline rvm it doesn't hijack all your shell builtins and is very lightweigh (keeps your prompt fast). I use it every day load load ruby/python/go/... projects in isolation.


For something even simpler, check out redenv -- https://github.com/damballa/redenv . It tries to provide something which works more like Python's virtualenv, just doing the minimum necessary to setup an environment referencing a particular system-provided Ruby installation, but with an isolated gemset.


In one of the linked posts they compare it to the rails vs Sinatra relationship, but in this case, since rvm and rbenv don't ever make their way to a consumer there's no real reason to switch.

I suppose if you're someone who has to work with multiple Ruby versions, it COULD save you time switching between them.





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: