This Time Self-Hosted
dark mode light mode Search

Ruby-NG: Bin Man (or, the binwrapper problems)

One of the problems that we definitely need to hash out before we start marking as stable the ebuilds based on the new Ruby eclasses is the handling of the current “binwrappers”. I dislike the name sincerely — while they are obviously in the bin directory for the gems, they are definitely not binaries, but rather executable scripts. Sigh, let it be for now though.

RubyGems already creates a wrapper by itself, so that it calls the correct (latest) binary for a given gem. On the other hand we don’t use that wrapper, but a different one that can be generated by the ebuild with much more stable targets. The end result is generally pleasing, as we can use the same wrapper for any implementation the gem is installed for. But here start the trouble.

Right now, this works all fine only if the gem is installed for every implementation, or at least every installed implementation. This again is mostly correct for most users as they will only have Ruby 1.8 installed. It starts being a bit different for JRuby, as not all of those scripts can be launched through that (but on the other hand, since we cannot set JRuby up as default Ruby implementation with eselect, it shouldn’t be much of a problem). It will be come a problem when we’re going to have Ruby 1.9 fully supported in Gentoo, as setting it up as default Ruby provider for the system will cause most of the scripts, installed only for Ruby 1.8, to fail.

The problem described above is to be intended when a package lacks an implementation, but conversely the problem applies when a package is available only for an implementation. Take for instance the (for now unpackaged) Duby — a strongly-typed Ruby-inspired scripting language developed by JRuby developer Charles Nutter. It will only ever be available for JRuby (minus possible reimplementations) as it generates Java Bytecode that JRuby can execute. It also has a duby script, but the ebuild I have here installs a broken wrapper: it calls into /usr/bin/ruby, but of course that cannot ever be JRuby, problems ensures.

Another problem is what Hans tried to solve some time ago: when multiple slots of the same gem are installed, and they all install the same named commands, how do you choose between them? Most of the times, you install them slotted, so you got cmd-${SLOT} named commands around, but you also need to have a way to just call cmd and have it work. Hans worked on eselect-gem for that reason: it’s a generic approach to the same thing that eselect-rails does. Right now, we’re not integrating well with that, so we might need to find a way to handle that.

One of the reasons why I’m now writing all this about the wrappers, is that I’d love for people to comment (after looking at the implementation, possibly, as I’d seriously love to avoid noise due to users wishing ponies, or detractors just saying that RubyGems is perfect — it’s not), with possible approaches we can take. So, comments welcome! And you might want to use the pre HTMLish tag to submit code via the comments, so that it won’t be screwed up by the formatting. You can also use at-symbols for inline code keywords, like I’ve done in the post.

Comments 2
  1. Would it be possible to have a variable in the ebuilds like ARCH and specify the ruby implementations that either don’t work or are unavailable so in Duby’s instance haveRV=”-ruby18 -ruby19″Or something similarAs for the wrappers a general eselect for the default ruby and have the wrappers use the above too so if the default is ruby18 and you try and run duby it’ll still run under jruby if installed or error if it’s not available

  2. The @USE_RUBY@ variable in ebuild tells exactly which implementations are supported by the ebuild.The main issue I find with having auto-fallback is that there is no clear way to auto-fallback, unless you add a scoring system so you select the *order* for the implementations (“ruby18 first, then ruby19, then jruby” or “ruby19 first, then jruby, then ruby18”).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.