"require 'rubygems'" In Your Library/App/Tests Is Wrong?

I found the write up at http://gist.github.com/54177 very interesting.
In it Ryan states:

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.

Fair enough. However this implies that there are other managers. But
I really haven’t heard of any. Seems like everyone uses Rubygems, and
now it’s part of 1.9. So, if there are other managers, what are they?
Google doesn’t really turf up anything definitive (maybe using the term
‘rubygems alternatives’ was too vague).

TIA

On Sat, Jan 30, 2010 at 6:05 PM, Joe W.
[email protected] wrote:

Fair enough. Â However this implies that there are other managers. Â But
I really haven’t heard of any. Â Seems like everyone uses Rubygems, and
now it’s part of 1.9. Â So, if there are other managers, what are they?
Google doesn’t really turf up anything definitive (maybe using the term
‘rubygems alternatives’ was too vague).

Problem is the way software is installed in your users’ machine is not
your library’s business. Dependencies may be running as vendored gems
in a self-contained application, or installed with apt-get. Maybe the
user fetched them by hand and threw them in some custom place,
whatever.

If your library needs the foo library that is a dependency, and should
require foo to be loadable. But it shouldn’t assume foo is going to be
loaded via rubygems and require rubygems itself. Leave that choice to
the client code.

On Jan 30, 12:05 pm, Joe W. [email protected]
wrote:

Fair enough. However this implies that there are other managers. But
I really haven’t heard of any. Seems like everyone uses Rubygems, and
now it’s part of 1.9. So, if there are other managers, what are they?
Google doesn’t really turf up anything definitive (maybe using the term
‘rubygems alternatives’ was too vague).

I have had only one occasion where I had to require ‘rubygems’: An old
version of RDoc is included with my Ruby install, in order to force it
to pick up the new version of RDoc, installed via RubyGems, I have to
load rubygems first.

As for other managers. There is Rip (http://hellorip.com/), and there
is also Roll (http://github.com/proutils/roll). Roll is my project and
I use it at all times, but there are still a few features I need to
finish before I bill it for public consumption, so I don’t oft talk
about it yet.

I wonder how many people don’t use rubygems. What creates more work,
requiring rubygems so that people who don’t want it don’t have to use
it, or
not requiring rubygems so that people who do want it have to keep
putting
-rubygems when they load files?

Perhaps a compromise? If I am working on some gem that uses mechanize, I
could require it like this:

def require_gem( gem_name )
begin
require gem_name
rescue LoadError
require( begin GEM_MANAGER rescue ‘rubygems’ end )
require gem_name
end
end

require_gem ‘mechanize’

This would have three benefits (assuming it is implemented by Ruby, and
not
the gem maker)

  1. it would stop people from having to require rubygems all the time, so
    less work / issues (for newbies who don’t know about this, figuring out
    they
    need to require rubygems can take a while / be frustrating)
  2. when you are writing a gem, you won’t have to worry about how you are
    loading the gems, because that decision is determined dynamically, so if
    a
    user wants to use a different manager, they just change GEM_MANAGER,
    then
    that same code uses rubygems on your system and in your tests, but uses
    their gem manager on their system and their tests.
  3. the end user doesn’t get strongarmed into rubygems by gem creators,
    and
    can easily switch between various managers by simply defining a single
    constant

These are just thoughts, I don’t like the idea of forcing things like
this
on people either, but I also don’t like the idea of creating headaches
and
hoop jumping every time everyone else wants to use the code. If anyone
with
more knowledge than me would like to critique the idea, I’d be
interested to
know how viable it is.
-Josh

On Sat, Jan 30, 2010 at 7:21 PM, Josh C. [email protected]
wrote:

I wonder how many people don’t use rubygems. What creates more work,
requiring rubygems so that people who don’t want it don’t have to use it, or
not requiring rubygems so that people who do want it have to keep putting
-rubygems when they load files?

If they installed your gem using rubygems they will load rubygems.
They can’t load your library otherwise in the first place. Executables
may be a different story.

The way dependencies are available in your client’s machine is not
your business! I gave several examples where rubygems may not be
available at runtime.

On Jan 30, 1:21 pm, Josh C. [email protected] wrote:

I wonder how many people don’t use rubygems. What creates more work,
requiring rubygems so that people who don’t want it don’t have to use it, or
not requiring rubygems so that people who do want it have to keep putting
-rubygems when they load files?

You should not have to do that. Just add ‘-rubygems’ to your RUBYOPT
environment variable --that’s a necessary part of setting up RubyGems
for one’s system.

end
You should simply not have to use require ‘rubygems’ in your code at
all.

Xavier N. wrote:

The way dependencies are available in your client’s machine is not
your business! I gave several examples where rubygems may not be
available at runtime.

Desktop code, for example, where an app is bundled up as a
self-contained entity.

Even if rubygems is available, I may want to be sure that specific
code gets loaded from specific places.


James B.

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development

Intransition wrote:

You should not have to do that. Just add ‘-rubygems’ to your RUBYOPT
environment variable --that’s a necessary part of setting up RubyGems
for one’s system.

Not for me. I stopped doing that a while ago.


You should simply not have to use require ‘rubygems’ in your code at
all.

Unless you want to be deliberate about when you use it and when you
don’t.


James B.

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development

On Jan 30, 9:18 pm, James B. [email protected] wrote:

Intransition wrote:

You should not have to do that. Just add ‘-rubygems’ to your RUBYOPT
environment variable --that’s a necessary part of setting up RubyGems
for one’s system.

Not for me. I stopped doing that a while ago.

How so? I can understand that for web app. But not for reusable ruby
library.

Josh C.:

I wonder how many people don’t use rubygems. What creates more work,
requiring rubygems so that people who don’t want it don’t have to use
it, or not requiring rubygems so that people who do want it have to
keep putting -rubygems when they load files?

Ruby 1.9 has RubyGems built-in, and for the legacy version you can
simply add -rubygems to your RUBY_OPTS and be done with the problem.

— Shot

On Sat, Jan 30, 2010 at 1:05 PM, Xavier N. [email protected] wrote:

On Sat, Jan 30, 2010 at 7:21 PM, Josh C. [email protected] wrote:

If they installed your gem using rubygems they will load rubygems.
They can’t load your library otherwise in the first place. Executables
may be a different story.

The way dependencies are available in your client’s machine is not
your business! I gave several examples where rubygems may not be
available at runtime.

On Sat, Jan 30, 2010 at 1:31 PM, Intransition [email protected]
wrote:

end
end

You should simply not have to use require ‘rubygems’ in your code at
all.

Perhaps I am confused, is there a problem with this code?:
begin
require ‘mechanize’
rescue LoadError
require ‘rubygems’
require ‘mechanize’
end

From here, it appears that if you have your own way of managing gems,
then
rubygems will not be loaded, because you will not experience a
LoadError.
Thus it satisfies that I don’t tell you how to load your gems, while for
the
vast majority of people, it simply works the way they want / expect it
to.

If this is not acceptable, please be explicit in explaining why (perhaps
an
example of how it would require rubygems if you are using a different
manager).
If it is acceptable, but my code earlier is not, please explain the
difference.
If it is acceptable, and my code earlier is, then perhaps Ruby should
behave
this way by default, since it would make life easier for both rubygems
users
(because they don’t have to tell their code to require rubygems) and
non-rubygems users (because the gems they get will not have required
rubygems). In this case, the language would encourage the proper
behaviour,
because there would be no need to require rubygems (and thus no hurdles
for
people who do not want it loaded).

On Sat, Jan 30, 2010 at 2:32 PM, Shot (Piotr S.)
[email protected]wrote:

— Shot

I don’t have 1.9, but this sounds like it requires rubygems
automatically,
which seems to contradict what several people earlier have said we
should
do. For example, the original post quotes “The system I use to manage my
$LOAD_PATH is not your library/app/tests concern.” If I understand what
you
have said, it sounds like the language has done what they are saying
that we
should not do.

Josh C.:

On Sat, Jan 30, 2010 at 2:32 PM, Shot
(Piotr S.) [email protected] wrote:

Josh C.:

I wonder how many people don’t use rubygems. What creates more
work, requiring rubygems so that people who don’t want it don’t have
to use it, or not requiring rubygems so that people who do want it
have to keep putting -rubygems when they load files?

Ruby 1.9 has RubyGems built-in, and for the legacy version you can
simply add -rubygems to your RUBY_OPTS and be done with the problem.

I don’t have 1.9, but this sounds like it requires rubygems
automatically, which seems to contradict what several people
earlier have said we should do.

I think what most of us (can’t really say for others, though) want to
say is this: if you’re creating a library, don’t ‘require 'rubygems’’
if all you use them for is to make ‘require 'some-other-lib’’ work
automagically. This is because there are cases where people want to
manage their libraries outside RubyGems, and by requiring them you add
a dependency that is simply not needed in their case.

If your lib is to be used by third party applications, their authors
will take care of satisfying your lib’s dependencies; if you want to
provide an executable wrapper that utilises your library, make the
wrapper’s code intelligent enough to look for the dependencies (e.g.
by doing the LoadError tango before it says that its dependencies cannot
be satisfied).

For example, the original post quotes “The system I use to
manage my $LOAD_PATH is not your library/app/tests concern.”

Yes, and this is what I mean above.

If I understand what you have said, it sounds like the
language has done what they are saying that we should not do.

Ruby 1.9 did what is convenient, and (I’m guessing here) to promote
wider RubyGems adoption, but I still believe you shouldn’t assume
RubyGems presence (especially if you want to be nice to stripped-down
embedded systems, for example).

What I meant by the ‘1.9 does this for you anyway, and in 1.8 you can
adjust RUBY_OPTS once and be done with it’ comment was to provide the
solution to the problem of ‘it’s inconvenient for me to use libraries
that do not “require 'rubygems’”, because I need to explicitely require
them myself’. That said, I do agree with James B. that putting any -r
switches in RUBY_OPTS feels bad to me (but then I don’t mind requiring
RubyGems myself where needed – and I try hard to use Ruby 1.9 anyway).

— Shot

Intransition wrote:

I don’t follow.

When I write my apps and library, I want to be sure that rubygems is
only used when I decide it’s appropriate. Leaving rubygems out of
RUBYOPT settings doesn’t stop me from doing anything.

Truthfully, I’m puzzled by the idea of implicitly requiring a library
for every piece of ruby you run. (Of course, in 1.9, it becomes
more like String than, say, Yaml. But imagine you have RUBYOPT pulling
in YAML for every thing you do. At some point this will bite you.)

I’ve helped more than one person sort out a “missing file” mystery by
pointing out that the system they are currently using does not have
magic gem inclusion; seems some number of new rubyists don’t even know
when they have RUBYOPT doing things for them.


James B.

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development

Josh C. wrote:

rubygems will not be loaded, because you will not experience a LoadError.
Thus it satisfies that I don’t tell you how to load your gems, while for the
vast majority of people, it simply works the way they want / expect it to.

If this is not acceptable, please be explicit in explaining why (perhaps an
example of how it would require rubygems if you are using a different
manager).

Suppose I have an app that uses Mechanize, but I’ve unpacked the
Mechanize gem into a local directory. When my app starts I munge $: so
that my own local relative dirs are checked to find files. But suppose
I screw that part up. :frowning:

My app calls your code, and when your code runs it should be finding my
unpacked copy of Mechanize, but because I have some error in my code, it
falls back to loading the rubygems version. It also now has rubygems
loaded, so other attempts at controlling the load path may quietly do
something I did not want. Sadness follows.

BTW, I’ve seen the above style of secret gem-loading code used inside
a gem. ActiveRecord, I think. This is insane.

If I’m using something as a gem then I already have rubygems loaded,
and if I’m not using your code with rubygems (say I’ve unpacked a gem)
then I likely do not want rubygems loaded, and if there is a loading
error it needs bubble up, not be quietly caught and “fixed.”


James B.

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development

On Jan 30, 5:00 pm, Joe W. [email protected]
wrote:

Fair enough. However this implies that there are other managers. But
I really haven’t heard of any. Seems like everyone uses Rubygems, and
now it’s part of 1.9. So, if there are other managers, what are they?
Google doesn’t really turf up anything definitive (maybe using the term
‘rubygems alternatives’ was too vague).

Rip:

http://hellorip.com/

Bundler
(To overwrite and disable system gems)

http://github.com/wycats/bundler

On Sun, Jan 31, 2010 at 11:32 AM, James B. [email protected]
wrote:

If I’m using something as a gem then I already have rubygems loaded, and
if I’m not using your code with rubygems (say I’ve unpacked a gem) then I
likely do not want rubygems loaded, and if there is a loading error it
needs bubble up, not be quietly caught and “fixed.”

That makes sense. So what if I am making some code to use, for myself,
but
putting it out for other people to use (namely classmates, who don’t
know
Ruby), but it isn’t a gem.

In this case, since it is not intended to be used as a resource by some
other code, is it acceptable to require rubygems, to make it more
autonomous
for the people who are likely to use it (via rake tasks)?