The following was originally published at gist.github.com/54177 but has been copied here for posterity and because people keep asking me on IRC for the original link; it must be hard to find on gist for some reason.

In response to all the “huh?” responses to this tweet: You should never do this in a source file included with your library, app, or tests:

require 'rubygems'

The system I use to manage my $LOAD_PATH is not your library / app / tests concern. Whether rubygems is used or not is an environment issue. Your library or app should have no say in the matter. Explicitly requiring rubygems is either not necessary or misguided.

When you feel the urge to "require 'rubygems'" because some shit isn’t working, stop and consider whether one of these solutions is more appropriate:

1. RubyGems installs special wrapper versions of executables included with gems. Here’s /opt/local/bin/rake on my system as an example:

$ cat /opt/local/bin/rake
#!/opt/local/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'rake' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
version = ">= 0"
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
  version = $1
  ARGV.shift
end
gem 'rake', version
load 'rake'

In this case, rubygems is required when the executable is run. Explicitly requiring rubygems in code loaded by these files doesn’t make sense. The whole point of these wrapper scripts is to push the rubygems loading machinery into the environment and out of your app / library / tests.

2. When running ruby FOO.rb and a LoadError occurs because rubygems is not available, DO NOT add require 'rubygems' to FOO.rb. Instead, run the command as ruby -rubygems FOO.rb. This will require rubygems before evaluating FOO.rb.

3. When running ruby FOO.rb and a LoadError occurs because rubygems is not available, DO NOT add require 'rubygems' to FOO.rb. Instead, set the RUBYOPT environment variable:

$ RUBYOPT="rubygems"
$ export RUBYOPT
$ ruby FOO.rb

You can even put that in your ~/.{bash,zsh,sh}rc if you prefer to always have rubygems loaded and available.

Why You Shouldn’t Force Rubygems On People

When I use your library, deploy your app, or run your tests I may not want to use rubygems. When you require 'rubygems' in your code, you remove my ability to make that decision. I cannot unrequire rubygems, but you can not require it in the first place.

Discuss

  1. If the case is that you don’t want to use rubygems and I have written a library or an app that requires it… then you can simply NOT USE MY CODE.

    I will write my code to MY OWN conventions, not YOURS. It’s simple.

    Arcturus Kirwin on Thursday, September 10, 2009 at 10:16 AM #

  2. Hey, I suppose this changes when Ruby 1.9 is released with bundled Rubygems?

    Vishnu on Thursday, September 10, 2009 at 10:17 AM #

  3. I agree that it should be unnecessary.

    Obvious workaround if you want to use libs that do include it and don’t ever want to use it yourself for performance reasons or whatever:

    echo "" > $SOMEWHERE_IN_LOAD_PATH/rubygems.rb
    

    Anonymous on Thursday, September 10, 2009 at 10:18 AM #

  4. @Vishnu Why would it?

    @Ryan On news.yc, somebody pointed out an interesting use case: what if the library needs a specific version of a specific third-party library? With gems, this can be specified with e.g. gem 'png', '= 1.1'.

    Would that be a valid use case for require ‘rubygems’ or do you suggest just putting the version requirement in the lib’s doc?

    Masklinn on Thursday, September 10, 2009 at 10:18 AM #

  5. @Vishnu: well apparently Ruby 1.9 comes with gems in the stdlib and requires it automatically. So if anything require 'rubygems' is even more wrong in 1.9.

    Masklinn on Thursday, September 10, 2009 at 10:19 AM #

  6. @Arcturus try this. Load up irb and check memory usage, then require rubygems and check again. Good times… Libraries shouldn’t be so tightly coupled to their packaging/delivery mechanisim that you need to load it up at runtime.

    Scott Bauer on Thursday, September 10, 2009 at 10:19 AM #

  7. “I dislike being called an ‘Anonymous Coward’”

    I think the borders on the textarea and text field don’t contrast the background enough, so it’s hard to see there’s a field below the textarea where you can leave your name.

    adnan. on Thursday, September 10, 2009 at 10:20 AM #

  8. I AM ANGRY. RAWR

    Aaron Patterson on Thursday, September 10, 2009 at 10:20 AM #

  9. adnan +1

    I'm not going to tell Ryan how to design his own blog, but IMHO:

    A border color of #eee, when the background of the textarea and the body are both #fff doesn’t provide enough contrast for many users.

    And something like “Name:” instead of “—” would be a huge boost in terms of usability and accessibility.

    Joe Grossberg on Thursday, September 10, 2009 at 10:20 AM #

  10. The comment form definitely needs a ton of work. Sorry guys, work in progress. Thanks for the feedback.

    Ryan Tomayko on Thursday, September 10, 2009 at 10:21 AM #

  11. Requiring rubygems allows one to reference the internal API used by the Gem commands – something I plan to do in an upcoming version of Chef.

    Any suggestions? :)

    AJ on Thursday, September 10, 2009 at 10:21 AM #

  12. Ryan raises an interesting issue. At what point does it become considered polite to advocate proscribing how people chose to write their project/application? Specifically can’t some one make the case Ryan does for almost any Gem your application may use?

    For example your gem might use library A to provide method x, however I prefer library B’s method x. Do I really have grounds to tell you: “You should never do this in a source file included with your library, app, or tests: require ‘a’”

    Or can a rational case be made for determining which library’s are subject to proscription and which are not? Could that case please be made? It will be interesting.

    Ryan’s post doesn’t give much insight into why he arrived at rubygems. @ScottBauer suggests memory is a criteria, but also suggests a library should be orthogonal to packaging and distribution. Why just these dimensions. Shouldn’t a library be independent of file IO? network IO? Or just about any other external process? Overall I think Ryan’s point would have been well made when RubyGems came out. By coming out with this rebuke after RubyGem is standard in 1.9, this admonition seems more like sour grapes about a community’s choice. No?

    Mark V on Thursday, September 10, 2009 at 10:21 AM #

  13. The point I was hoping to make is that rubygems is designed so that you don’t have to add the line “require 'rubygems'” in order to take advantage of its features. Rubygems functions at a level above your library and there’s a lot of work that went into making it work that way. The executable wrapper scripts, dependency loading by gemspec, etc. These features work the way they do so that you don’t have to require 'rubygems' in your code.

    The point I was not trying to make is that rubygems is bad or that people shouldn’t use it. I use rubygems and think it’s a critical piece of Ruby’s success – I just don’t have the line “require 'rubygems'” anywhere in my library’s source code because it’s not necessary or convenient and makes it hard / impossible for other environments (like bundler, rip, GAE, debian, hand rolled, etc) to use the library without rubygems, which is often important.

    This piece obviously didn’t get those points across very well and that’s my fault. Most people came away with the idea that I'm attacking rubygems and suggesting that people not use it. I'm not. I like rubygems tremendously and use it every day — I don’t like code that explicitly requires it for no reason. Luckily, Yehuda and Josh have published much better pieces that argue something similar to what I intended to say here.

    Ryan Tomayko on Thursday, September 10, 2009 at 10:23 AM #

  14. good news though that the conversation (as nasty & annoying as some of it was on the msg board) maybe was seen by a lot of Ruby devs and more folks understand more about rubygems because of it.

    Mark on Thursday, September 10, 2009 at 10:24 AM #

  15. Ideally, we shouldn’t have to use require at all since Ruby is easily capable of autoloading based on references. I should be able to just reference a class, module or method and let the environment worry about loading libraries. In addition to granting flexibility to admins, this would also be more convenient for the programmer.

    Jedediah Smith on Thursday, September 10, 2009 at 10:24 AM #

  16. That’s a pretty stupid argument, rubygems is one of those things that should simply be a default for Ruby, and it indeed is in Ruby 1.9.

    Tomasz Wegrzanowski on Thursday, September 10, 2009 at 10:25 AM #

  17. Tomasz: even more reason to not require it.

    Ryan Tomayko on Thursday, September 10, 2009 at 10:25 AM #

  18. Goddamit. Sorry, people. I accidentally deleted all comments across the site and didn’t have a backup of the one’s left on this article. I've entered them all in manually (the horror) from a cached version of this page but I'm not adjusting the timestamps one by one so those are all wrong. Also, permalinks to comments were broken. My bad.

    Ryan Tomayko on Thursday, September 10, 2009 at 10:29 AM #

  19. Sorry, comments are temporarily closed due to a broken spam filter. bbl.