Hacker News new | past | comments | ask | show | jobs | submit login
Rbenv 1.0.0 (github.com/rbenv)
170 points by nixpulvis on Dec 25, 2015 | hide | past | favorite | 86 comments



Also try the postmodern tools: ruby-install & chruby, which work perfectly in my experience:

https://github.com/postmodern/ruby-install

https://github.com/postmodern/chruby


Yep. Moved from `rvm` to `rbenv` when it came out, but didn't realize how much magic it still did. Switched to `chruby` when it came out, was much nicer experience overall, and faster too. Just wish the Emacs package for chruby was written a little less ad-hoc.


I've been perfectly content using RVM https://rvm.io/ - with all the functionality I need, and reliability, too. What am I missing out on?


The problem with rvm was always that it tried to do too much. With a tool like that, as long as it's working, you won't see the downside. When it breaks, it breaks in complicated, hard-to-debug ways. If you're saying it's reliable for you, that's great. That wasn't my experience.


Rbenv is much smaller and only does ruby version changes and installations with the ruby install add on. rvm is bigger and has more features but is a bigger pain to use in my experience.


Also the whole Gemset thing is basically redundant now Bundler has become the standard way of locking dependencies (Gems).


I fell on rvm because it seems to be the "default" recommendation. I don't see a need to use something "better" if the raw tool does the job perfectly.

I do get annoyed that "rvm list known" tends to only show old versions. For example, it suggests it can install ruby-2.2.1, but I'm fully aware 2.2.4 is available, as is ruby 2.3 now. And for me at least, this problem is consistent after applying the standard advice of "get the latest rvm".


rvm "stable" hasn't been updated in quite a while, last time I checked. you need to install the "dev" version.


rvm was perfectly happy to install Ruby 2.3.0 for me this morning, upgrading me from 2.2.4, which is what I was using until last night.


As a ruby outsider, I wonder do those have any practical effects on how you write/run programs? Do they save time or prevent bugs? Why is versioning such a huge problem in ruby?


They are tools for managing multiple installed versions of a programming language. When developing software, we often specify dependencies using version numbers, which indicate the version of the language or library that should be used when running the software. Running the software with the specified language runtime or library version ensures that the expected features of that library or language runtime are available and also helps avoid unexpected issues related to differences in the environments, including different developer's local systems as well as remote server environments.

In the case of a programming language runtime, if you have one project that's configured to use version 2.2.4 of a language and another that's configured to use version 2.1.0, these tools provide an easy way to install and switch between the two versions.

This is not unique to Ruby, and similar projects exist for other languages. For example, nvm (https://github.com/creationix/nvm) and n (https://github.com/tj/n) provide something similar for Node (JavaScript), gvm (https://github.com/moovweb/gvm) for Go, and multirust (https://github.com/brson/multirust) for Rust.


I've dabbled a little bit in Ruby, and I found this to be a much larger problem than it is with Python. Most systems have python 2 and/or python 3. Beyond that, I've rarely need to worry very much about which Python version I have. But for every new Ruby application I install on my machine, I'm messing around with rvm.

Is it truly a difference between the languages release strategy or is this just my perception because of limited experience with Ruby? I found it to be a huge pain in the ass.


It's annoying for sure, and I like that we don't need it in Python land. But, in situations when we do want to target multiple Python versions, an identical approach using pyenv works well. I've come to appreciate it more.


It's not really a problem per say. It's just taste really. There are multiple good options for managing ruby versions and environments. (as well as other languages like Phython, see pyenv). I don't necessarily switch to ruby versions between projects or with frequency. That being said, ruby is in active development and with new versions there are many improvements to performance and security. So developers like to try the latest and test out their apps, libraries and frameworks.


I'm sorry I wasn't more clear, I'm wondering why there seems to be a war of sorts between which version manager to use for ruby. Are the differences between rvm, rbenv, chruby, ruby-install practical or purely ideological? There doesn't seem to be this kind of disagreement over which version manager is best in other languages, just ruby, why is that?


There's a lot of reasons, but the most significant one is that Ruby successfully and recently made a compatibility break between versions (1.8 and 1.9), which made the ability to run multiple Ruby versions on a single machine extremely important to a large group of people. Toss in alternate implementations like JRuby and Rubinius and it's almost indispensable.

The Ruby dev team tends to prefer encouraging the community to implement competing solutions rather than adopting any of them as official. Ruby devs in general tend to be members of the "there is more than one way to do it" camp.

There isn't really much of a "war". The different version managers came to an agreement on certain things like the format of .ruby-version files, so at this point it's a personal choice akin to which text editor you use.


rvm hooks into the cd command which has caused people nightmare-level debugging marathons. rbenv's key feature was that it did not do that and uses a shim instead.


To add a little more to the history, I made the switch from rvm to rbenv when rvm broke under me (I can't remember now whether it was `cd`-hooking or rubygems-bundler which broke the camel's back). I made the switch from rbenv to chruby when rbenv's shims broke. Chruby does so little that there's almost nothing to break, so I've stayed there.


Libraries that work for an older version of ruby won't always be forward compatible. So if you're working in many projects you can't simply use the latest version of ruby. Then you have things like Jruby which is incompatible with some of the libraries designed for MRI. So, being able to segregate rubies is essential.


rbenv doesn't require _any_ special integration to be used from inside Emacs. As long as chruby needs that, it doesn't seem like a good alternative to me.


Chruby's so small that you might as well rewrite it in elisp.


Huge fan of these, been using them basically as long as they existed. They work well and are significantly simpler.


If you're missing niceties like gemsets around this, there are various companion projects to provide bells and whistles. I've written a couple myself:

https://github.com/regularfry/gemsh https://github.com/regularfry/rv

The wonderful thing is that these projects are so small and simple that writing your own tooling to interface with them feels quicker and easier than evaluating someone else's code...


Quick question: do you still need gemsets if you use Bundler? And why would you prefer using one instead of the other?


Gemsets are redundant when you use Bundler. Your second question will boil down to opinion but Bundler has been extremely solid in my experience. The feature set is huge and the work ethic of the core team is commendable.


I still use isolated $GEM_HOME directories for each project on my dev machine, and don't rely on bundler to separate installations on production machines.

In my mind, bundler was never really needed for that - it was a complexity step further than was required - so I never set myself up to rely on it, instead relying on a simpler mechanism which doesn't need runtime tooling support. As a result, I never have to run `bundle exec`. How much you might prefer this will probably be more dependent on how much you appreciate simplicity.


chruby didn’t work with fish last time I checked. Any idea if it does now?



I don't get why stuff like this isn't a solved problem and there's one solution that most people use.


Ruby developers haven't historically been as considerate to users as Perl, Python or Java developers; they don't strictly follow semantic versioning standards or preserve backward compatibility for dependents. So hacks like this and Bundler have been needed to preserve our sanity.


I wouldn't call Bundler a "hack". It's actually one of the best package managers around IMO.


I don't disagree that it works well; I'm simply arguing that it solves a problem that shouldn't have existed in the first instance.


Bundler and the RubyGems community in general is amateur hour compared to projects with more discipline like GNU/Linux distributions.


It's a different type of community, and I was only making a point about how well designed Bundler and RubyGems are for the purpose they serve. It's very easy to share gems within the community.


It is a solved problem. Good can be come better.


How is it a solved problem? chroot is not user-friendly enough clearly otherwise people would use it instead of virtualenv, rbenv, nodeenv and what have you.

GP is right, there should really be one single, generic virtualenvwrapper-like tool that doesn't give a crap about languages.


Docker?


Docker does not solve that problem...


As a Java developer who used to be a Ruby developer, I can't believe how poorly dependency versioning (and just general Ruby versioning) works. It should be simple to have multiple versions of libraries coexisting on a system. Maven can do it fairly easily.

RVM and rbenv seem like hacky solutions to a problem that is easily solved by specifying dependency versions in your project.


You can have multiple versions of libraries (gems) installed at the same time. Ruby is no worse than Java here. You can easily have multiple concurrent versions of Ruby, too. What rbenv etc do is make it easy to switch between Ruby versions and keep them separate. Bundler is not a hack, and is better than what is offered by some other solutions (pip, NPM).


As someone who clearly doesn't use Ruby often enough to "get it", I don't understand this problem: I have multiple major versions of Ruby installed on my server from Ubuntu via APT, and I don't need to "switch" between them... they are just versions in their install names like all the other versioned interpreters I install. If I want some kind of "default" build of Ruby, that seems like it would be solved with nothing more than a three line shell script to build either aliases or symlinks (and I think Ubuntu already has a way to do this using diversions).


As Ruby is an interpreter most executables just have "#!/usr/bin/env ruby" at the top of the file. If you have multiple versions of Ruby, this may or may not pick up the correct version you have installed. Historically the interpreter has made quite a few breaking changes, didn't follow semantic versioning and didn't care about backwards compatibility. What these tools do is alter the environment so that you can 'lock' specific versions of the interpreter.

The same problem also occurs with libraries, which may also have their own executables, so these tools have tried to solve both problems - which is slightly more complicated than a three line shell script. Bundler has become the standard way of managing libraries, so now something like chruby[0] can be used to do pretty much what you said for the interpreter alone. Of course the other tools (that do a lot more) still have their historical followers...

If you are wondering why you need to support multiple versions, these tools are mainly for use in development environments where you will probably have to support legacy software that is no longer actively maintained.

[0] https://github.com/postmodern/chruby/blob/master/share/chrub...


It mostly kicks in when you are a developer that supports 4 or 5 different ruby-on-rails sites, each of which require different versions of ruby. Rails, in particular, seems to be very intolerant of running on different ruby versions, so if you have been less than scrupulous in keeping all your rails apps up to date, you will be juggling different ruby versions. Using Debian "alternatives" is one way of dealing with it, but you also need to be hyper sensitive about the gem versions, so you will be using bundler in most cases. Rbenv, et all, just deals with the complexity so that it is hard to make a mistake. It's not impossible to do it other ways, but it is much harder.


If you run the right interpreter (e.g., ruby-2.1), it will know what paths to load gems and libraries from. So that's not the problem.

As others mention, scripts typically just run "ruby" (via shebang or directly), which will pick whatever is the default.

Debian/Ubuntu have the "alternatives" system, which is designed to solve this for any kind of program, but it's virtually impossible to use by humans; there's no single command to switch between versions.

Fortunately, the ruby-switch package [1] wraps the terrible UI in a single command to switch versions. I highly recommend it.

Of course, this switches the version globally. To get per-shell Ruby versions, you will need the other tools mentioned in this thread.

[1] https://wiki.debian.org/Ruby


I use Ruby often, not sure if I quite "get it" either, and maybe I don't really understand what you're saying but I think using rbenv is easier than writing a three line shell script to build aliases or symlinks. ```rbenv global 2.3.0```, and you're set.


NPM is atrociously bad. Bundler is amazingly good.


How does maven deal with multiple versions of the JRE?


You can specify which java version you're compiling and execute (unit and integration test included) within maven execution. Granted it's not rvm/rbenv that literally install multiple version of Ruby.


It doesn't. You just install the latest java and it's fully backwards compatible.


That's not really true. We still run some older Apache camel components that require Java 7. And when Java 8 first came out it had bugs that crippled Solr, it took a long time before that was stable enough to use everywhere.


I'm not sure that's really true, but it regardless misses the point. No matter what language you're using, you'll eventually need to be able to deal with multiple versions of it.

Even if you're running an operation small enough that you can upgrade every single runtime in use all in one step, you'll still need to have two versions around while you test. But many, many places have to deal with multiple language versions simultaneously. E.g., if you maintain an open source library and have any regard for your users, you have to test how it behaves in multiple language versions.


Well Ruby is too. If something worked on 1.9 it works on 2.3.


Yeah? Try rails 3.2.17 which work perfectly on ruby 1.9 and see how well it works on 2.2.

(java is not fully backwards compatible either, but it may be a bit more tolerant in some cases)


I've done the work before to make rails 3.2 work on 2.2. I recall the problem is due to a breaking Bcrypt name change and Yaml serialization, and it's a one line patch. The maintainers are aware of the issue but held back so as to not break every 3.2 installation on a minor upgrade (would have to be called Rails 3.3 for semver?). Rails 4.0 isnt that hard of an upgrade path if you include the attraccessible gem.


It took quite a while before rails released a version of 3.2 that worked.

As for how fun upgrading to rails4 is, you obviously don't have a project with 200 database tables that has models using the attr_protected for the five columns (appwide) that actually need it. Forced whitelisting is not fun, regardless of if it is on model or controller level.


Rails isn't ruby.


Did I claim that? However, it is written in ruby and as such it is a valid counterexample to the claim in the comment I commented on.


It's Ruby on Rails


No, Java is not fully backwards compatible. It may be more backwards compatible compared to ruby, but claiming that it is fully backwards compatible is simple false.


  > It should be simple to have multiple versions of libraries
  > coexisting on a system. 
This is a language issue, not a tooling issue.


I'm not sure you understand. You can have as many versions of a gem on your system as you want. You just can't have multiple Ruby versions of those gems easily without something like rbenv.


Yeah, but that's a serious problem. I can't think of other languages that suffer from this, except perhaps Python.

Why should I have to install a single library in multiple places in my system, if I have multiple versions of Ruby installed? It's a disaster for upgrades and deployment.

Plus, tools like RVM and rbenv seem to depend on a bunch of hacky symlinking and $PATH manipulation to make things work. Ensuring that developers' laptops have the same environment as production boxes is not trivial, no matter what the authors of these tools claim.


What I find annoying is that the core problem they solve boils down to manipulating three environment variables. Where's your ruby? That goes in $PATH. Where am I installing gems to? That goes in $GEM_HOME. Where am I loading gems from? $GEM_PATH. Everything else these tools try to do is icing.


Every time I have issues with rvm (which seems often) or rbenv (occasionally, I use it less), I'm reminded that Modules (http://modules.sourceforge.net/) takes care of this path fiddling and more. Yeah, it's old and it's in TCL and it doesn't solve the "how do I build a new ruby and gemset" problem but it's been working for years on the "how do I switch path" problem. I use module when I build .deb of Ruby and gems.


Bundler solves that problem; rbenv is for switching between Rubies, not Gems.


Another excellent tool for the same problem is chruby[1]. I found it simpler (in a good way) than rbenv.

[1] https://github.com/postmodern/chruby


I love Rbenv. Super simple, and it just works.


I wish I had the same good experience. Getting things running on Ubuntu 14.04 LTS is an unresolved hairball for me. http://stackoverflow.com/questions/23155289/rbenv-build-fail...


I haven't used it, but second hand I've heard that the Python version of this concept is "virtualenv".

Edit: I probably shouldn't be surprised to learn that second hand information I picked up six years ago at PyCon is out of date...


Not quite. The Python equivalent is Pyenv: https://github.com/yyuu/pyenv


I'm a relatively experienced python developer and have never even installed pyenv.

Whereas with Ruby, I can't seem to get much working without it.


You can take a fresh install of MacOSX and do anything with Ruby. Only issue is you need to install some gems using sudo. Same thing with using system python. You don't need rbenv by any means. In fact our designer has no problem getting our rails site running and making styling edits.

Hard to say the same with installing Python 3 on MacOSX and getting virtualenv running, which in my experience hasn't been so easy.

How would you work on a project that uses 3.2, then another that uses the latest features from 3.5, without pyenv?


I have a tendency to install one of python 2.x and one of python 3.x and then use the --python flag to set the particular python I want my project to run against.

At that point it should work invisibly in the virtualenv.

Unlike ruby, point releases don't often make sweeping breaking changes so it is often enough to say 'this is python 3 code' or 'this is python 2 > 2.5' code, so the granularity of something like pyenv is mostly unnecessary, imo.


That's the way I worked at my last job with Python. I filed for brain fuckery bankruptcy after trying to get pyenv and pyenv virtualevnwrapper set up.

You can't say this is Python 3 code or Python 2 code. That's completely false. If someone used latest features from Python 3.5 that wouldn't work on 3.4.

Also, I haven't had any issues upgrading point releases in Ruby(since 2.0). Point releases do not make sweeping changes by any means. You maybe talking about the weird 1.8 to 1.9.3 thing.


I seem to have all of Python 2.7, 3.2, 3.3, and 3.5 installed on my server just from APT. I happen to only use 2.7, but I certainly don't see what use I would have for some crazy tool to manage versions of Python for me... if the project needs Python exactly 3.2 for some specific reason I can just run python3.2 instead of python3.5 or python3.


If you work on multiple Django or Flask projects you'll quickly learn APT can start solving your problems but it won't be the best way to do it.

With virtualenv each project of mine has a requirements file (I use it even for Google App Engine development, having a distinct SDK per project) and runs Python from a different environment where the packages I install with pip do not interfere with any other environment. Without it an "apt-get upgrade" can end up breaking everything (to say nothing about not having the latest version packaged).


The real equivalent in the Python world is pyenv. In fact, pyenv is based on rbenv. virtualenv itself lacks the ability to manage different Python versions.


And in node world it's nvm


Nodenv [1] would be the node equivalent.

[1]: https://github.com/OiNutter/nodenv


Not so. Virtualenv's spiritual Ruby equivalent is Bundler.


But technically no. Virtualenv is quite different, both in scope and approach. https://github.com/Deepwalker/pundler is more similar to bundler


Rbenv and all other such tools are narrow, weak solutions for a general problem: Using multiple versions of a piece of software on the same machine without collision. Projects like Nix and GNU Guix solve this generally without needing a new special package manager for each thing you want more than 1 version of.


What would be really handy at this point is a shim around Nix to make it trivial to manage ruby versions without having to learn a whole new ecosystem. I don't want to learn Nix, I want to use Ruby.

Actually, that would have been really handy about 5 years ago, but the point stands: the problem with general tools like Nix is that you need a popular, specific application of them to get them across the chasm. Not only would a wrapper script using Nix to manage ruby versions be actually useful, it ought to be relatively easy to repurpose to node, elixir, elm, GHC, whatever. Make it so that I don't need to care that I'm using Nix in the background, and I'm actually more likely to use it.


I've found rbenv to be a great, narrow solution for a specific problem. And maybe those other tools you mention are great but I've never heard of them, so they could use some marketing besides this comment. That's why tools like rbenv and rvm and whatever else get more broadly picked up.


How is Rbenv weak? It does exactly what is needed.


Because it only tackles a single language.




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

Search: