
Why "require 'rubygems'" Is Wrong - blasdel
http://tomayko.com/writings/require-rubygems-antipattern
======
ionfish
Context failure: linking to Ryan Tomayko's article without linking to the
article that's brought it to people's attention again, namely Josh Peek's 'Gem
Packaging: Best Practices'.

[http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-
pr...](http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices)

Giles Bowkett has also written about the related issue of screwing up the load
path:

[http://gilesbowkett.blogspot.com/2009/04/unshiftfiledirnamef...](http://gilesbowkett.blogspot.com/2009/04/unshiftfiledirnamefile.html)

It's also worth noting that Ruby 1.9 requires rubygems automatically, as it's
included in the standard library.

~~~
defunkt
Thanks! Both the Rubygems Bundler and Rip (as Josh explains) are great
examples of why "require 'rubygems'" might not always be the best idea.

Bundler: <http://github.com/wycats/bundler>

Rip: <http://hellorip.com/>

------
anatoly
Please don't start your shell scripts with #!/bin/sh. If a script foobar needs
to be interpreted with sh, just run it with '/bin/sh foobar', instead of
./foobar.

Please don't put #include <stdlib.h> in your C source files. By doing this you
remove my ability to compile your files in an environment where the standard
library is not present. Instead, whenever you need to compile a file that uses
stdlib.h functionality, simply use a small wrapper file that includes stdlib.h
and then includes your source file, and compile that.

~~~
masklinn
Analogy failures:

* Configuring /bin/sh to point to my shell of choice is trivial (and common)

* Overriding the shebang is even more trivial, if I don't like sh, I can call `./mysupershell foobar`

Meanwhile, if I don't want gems on my machine and manage my $LOAD_PATH
manually or through other means (which seems to be Ryan's case) but you
decided that your library was going to require rubygems dammit, I have the
choices between

* Installing rubygems (and duplicating my $LOAD_PATH handling efforts) anyway because you decided I was to have rubygems on my machine whether or not I liked it

* Adding an empty rubygems.rb to my $LOAD_PATH (yeah, kludge)

* Hacking Kernel#require to ignore gems request (yeah, horrible hack)

~~~
tptacek
If you're going to be in the tiny tiny minority of Ruby devs that insists on
not installing rubygems, having a stubbed "rubygems.rb" in your load path is
not an unreasonable request --- particularly compared to the request that
_everybody else_ uses some contorted command line to execute their script to
accomodate you.

~~~
extension
It's unreasonable if you want to have both rubygems and some other package
system available at the same time, as is most often the case. Having to use
the contorted command line is the rare case, as you almost always invoke ruby
scripts through the rubygems generated wrapper or some other isolated script
intended specifically for command line use, which takes care of rubygems
itself.

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

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

1) An empty rubygems.rb in your $LOAD_PATH should do the trick.

2) Redefine Kernel#require to intercept calls to load rubygems and silently
discard them.

Why You Shouldn't Force Non-Rubygems On People

When I write you a library, appplication, or tests, I may not want to have to
care how you execute my program. When you require that I not include
'rubygems' in my code, you remove my ability to make that decision. I cannot
anticipate all of your requirements in advance, but you _can_ set up your
environment properly such that the defaults I choose are overridden.

~~~
masklinn
So instead of separating the library and the environment you suggest that ugly
hacks are more appropriate? Really?

~~~
tptacek
Having the 99.9% of ruby users who don't have a religious problem with
rubygems all specify rubygems on the commandline seems like a more ugly hack
than having the 3 developers in the world who care about this problem alter
their environment.

~~~
extension
You underestimate the amount of discontent with rubygems. There is at least
one replacement available (hellorip.com) and for good reason. I've already
come across a few libs that use it exclusively.

Ruby 1.9 actually ignores "require 'rubygems'" entirely which I suppose will
make this whole issue moot, as soon as we all start using it.. um, any day
now.

------
toretore
The point about not requiring rubygems in a library or a gem (as ironic as
that may sound) is that by doing so you're coupling your implementation to
your environment. This is as bad as coupling your classes to global constants,
and not something you should do. Case in point: Rails allows you to "unpack"
gems to make your app more portable, and it shouldn't matter if the "foo" gem
uses the unpacked version or the one installed in the gem repository on the
server.

------
nanijoe
Let me see...every time I have required rubygems it has done exactly what I
intended for it to do (which is to allow me to load some ruby gem), so I think
I'll just go ahead and ignore your advise.

------
sunkencity
Stupid article.

So if I write a ruby program that needs rubygems I need to ask people that
will run it to please run my program with "ruby -rubygems foo.rb" or set an
environment variable, instead of just requiring the gems. Because that would
infringe on the domain system administrator of that system. That doesn't make
much sense to me.

~~~
masklinn
> So if I write a ruby program that needs rubygems

I think Ryan's point is that most of the time your program doesn't require
rubygems itself. You just happen to manage your libraries using gems, somebody
else could do it an other way (and never need rubygems), but you're forcing
that person to install gems regardless.

~~~
sunkencity
Things tend to break a little less over time if I can require a version of a
gem, like:

gem 'png', '= 1.1'

The good part about rubygems is that it's possible to get a certain version of
a gem. I'd rather use gem and version than just require "png", and get god
knows what version or file.

~~~
masklinn
That's a good point, and in this case requiring rubygems does make sense, but
I really doubt that's the most common use case.

Stuff like this:
[http://github.com/mojombo/jekyll/blob/2f2e45bedf67dedb8d1dc0...](http://github.com/mojombo/jekyll/blob/2f2e45bedf67dedb8d1dc0d02612345ee5c893f2/lib/jekyll.rb)
or that:
[http://github.com/mwunsch/weary/blob/cd7b35ccee66757c5efb0a0...](http://github.com/mwunsch/weary/blob/cd7b35ccee66757c5efb0a03cd54f9e89f1eaad7/lib/weary.rb)
is probably the kind of stuff Ryan rages against in his rant (though you'd
have to ask him if that's that, and how he'd see you use case)

~~~
sunkencity
yep I can agree that

    
    
      require 'rubygems'
      require 'png'
    

is kind of pointless.

------
jdminhbg
This is called begging the question:

"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."

------
ajkirwin
Whoever this guy is, he really needs to pull his head out of his ass.

If someone's writing a library or app.. it's up to THEM whether they want to
require rubygems or not. If you don't like how they do it.. then don't use
their application/library, it's simple.

Most people create code for their OWN use and THEN publish it for others to
use.

~~~
masklinn
> If someone's writing a library or app.. it's up to THEM whether they want to
> require rubygems or not.

But… why? Most of the time it's not like _they_ actually _need_ gems. They
just happen to use gems as a $LOAD_PATH manager, so they're leaking their
environment configuration into the library. How can anyone defend that?

It's like hardcoding the paths of dynamic libraries, or respawning your shell
scripts because damn it if any god damn user is going to run it with anything
other than /bin/bash.

It's completely insane.

~~~
sho
_they just happen to use gems as a $LOAD_PATH manager_

Oh come on. That's like saying "you should not make your MacOSX app require
Finder just because some people just happen to use it as their file manager".
Just happen? It's the default, and overwhelmingly dominant, choice! It's
freaking bundled in 1.9 core!

rtomayko is a prominent and well regarded community member but he's pretty
much a crank on this issue. He is the extreme odd one out who doesn't like
rubygems, so it's on him to deal with it, rather than causing inconvenience
for everyone else. He doesn't even give a good, or any, reason why he doesn't
use gems. And as if I'm going to write -rubygems every time I run anything,
give me a break.

Rubygems is the official package manager and is used without any issue by
99.9% of Rubyists. It's not 100% perfect but in general works beautifully and
greatly contributes to making everything in Ruby "just work". There is no
reason for people to stop using it as the default choice.

~~~
defunkt
I'm also a crank.

So is Rails core member Yehuda Katz.

So is Rails core member Josh Peek.

So is Rails core member Jeremy Kemper.

Calling Ryan "the extreme odd one out" is a) untrue and b) unfair.

~~~
sho
Right. Now I am really confused. You went out of your way to build gem
building support into GH. _You run a fricking gem repository_ , probably the
largest after Rubyforge itself. If you honestly agree that using Rubygems is
"utterly insane" then .. wtf are you doing?

And Rails uses Rubygems. Of course. Its ease of use is one of the reasons
Rails, and indeed Ruby itself, is so popular. Is it "utterly insane" for Rails
to use Rubygems, too? And if all the core members are so against it, why does
it? Why is Rails even in the gem repositories?

What am I missing here? Seriously, I just don't get it.

I'm currently kinda mentoring a friend of mine who's just getting started
programming (my 3rd student!). I can personally attest that Rubygems is an
_invaluable_ resource for the beginner and intermediate Rubyist. Have you
considered the possibility that your ultra-expert status has blinded you to
the needs of the lesser 99% of programmers?

~~~
defunkt
No one has suggested, is suggesting, or will suggest that you stop using
Rubygems. That is not what this is about in any sense of the phrase. Everyone
loves Rubygems, including Ryan Tomayko.

This is about the best way to use Rubygems. Check out Josh Peek's recent
article: [http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-
pr...](http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices)

There are ways to use Rubygems without putting "require 'rubygems'" in your
code. Those are the correct, most portable, least painful ways of using
Rubygems. Learn them and cherish them!

That is what this is about: how you are using Rubygems, not whether or not to
use them.

~~~
sho
I just read that post again. Good post, but it's talking about something
different. This HN article is about Ryan's views on the matter.

Of course I agree that _libraries_ should not require it. I often want to use
libraries by themselves. But _apps_!? What do you suggest - manually place
each gem directory, by its full system file path, into $LOAD_PATH? How on
earth are you going to use a gem installed in its default location by the
ubiquitous "gem install" method, if not by, at some point, requiring rubygems?

This whole kerfuffle was started by this gist: <http://gist.github.com/54177>.
Note the title: Why "require 'rubygems'" In Your Library/App/Tests Is Wrong. I
thought that was a ridiculous thing to say then and still do. In my _app_!?
That no-one else will ever see, my personal little IRC bot or something? What,
pray tell, is the difference between loading rubygems on the command line
every single time you run the program, or just writing in the source because
you know your app needs it?

I have no quarrel with best practise for responsible use of gems. I agree
completely with what Josh Peek writes. People publishing gems to public repos
should absolutely learn how to do it without stepping on anyone's shoes. But
that is not what Ryan says. Ryan says this:

    
    
      You should never do this in a source file included 
      with your library, app, or tests:
      
      require 'rubygems' 
    

and that is extremist and indefensible and, IMO, flat out wrong.

update: I mean, let's have an example. Let's take a top-level app that depends
on things. I know, thin.

Here we are:
[http://github.com/macournoyer/thin/blob/9f391ed7fcc7c202a32e...](http://github.com/macournoyer/thin/blob/9f391ed7fcc7c202a32e520bda9323be25d666e4/lib/thin.rb)

He needs eventmachine. He requires rubygems and loads it. Tell me what he is
doing wrong. Tell me how he should do it differently. Because I can not see
what is wrong with that. And if that usage is wrong, then what is the point of
even having Rubygems.

update 2: And I would like to clarify that I agree Rails should only be
requiring Rubygems when it is being used at the top level, such as being
launched from the binary or from the script directory, not when it is being
loaded as a lib. It is always the top level app's responsibility to set up
paths, etc - rails is a special case because it's both an app and a library.

~~~
masklinn
> He needs eventmachine. He requires rubygems and loads it. Tell me what he is
> doing wrong.

He requires rubygems even though what he wants is eventmachine. What's the
sense?

> Tell me how he should do it differently.

Don't require rubygems. Rubygems isn't used anywhere in the code, why require
it?

> And if that usage is wrong, then what is the point of even having Rubygems.

Managing your own $LOAD_PATH on your own machine(s). That's the point of
rubygems in the first place.

~~~
sho
Oh for fuck's sake. So what do you suggest? Bundle eventmachine with thin?

 _"He requires rubygems even though what he wants is eventmachine. What's the
sense?"_

Do you know even know what rubygems is? It is used to require other libraries.
Like eventmachine. That is a textbook usage.

I was regretting insulting you before, but after hearing that, I don't anymore
- you're an idiot.

Hey defunkt, do you endorse masklinn's comment above too?

