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

J

Joe Wangkauf

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
 
X

Xavier Noria

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


Fair enough. =C2=A0However this implies that there are other managers. = =C2=A0But
I really haven't heard of any. =C2=A0Seems like everyone uses Rubygems, a= nd
now it's part of 1.9. =C2=A0So, if there are other managers, what are the= y?
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.
 
I

Intransition

Fair enough. =A0However this implies that there are other managers. =A0Bu= t
I really haven't heard of any. =A0Seems like everyone uses Rubygems, and
now it's part of 1.9. =A0So, 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.
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

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
 
X

Xavier Noria

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

Intransition

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.
Perhaps a compromise? If I am working on some gem that uses mechanize, I
could require it like this:

def require_gem( gem_name )
=A0 begin
=A0 =A0 require gem_name
=A0 rescue LoadError
=A0 =A0 require( begin GEM_MANAGER rescue 'rubygems' end )
=A0 =A0 require gem_name
=A0 end
end

You should simply not have to use require 'rubygems' in your code at
all.
 
J

James Britt

Xavier said:
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 Britt

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
 
J

James Britt

Intransition said:
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 Britt

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
 
J

Josh Cheek

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.




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 th=
e
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 behav=
e
this way by default, since it would make life easier for both rubygems user=
s
(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).

Josh Cheek:


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.

=97 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 w=
e
should not do.
 
J

James Britt

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

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 Britt

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
 
J

James Britt

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

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. :(

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 Britt

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
 
L

Luis Lavena

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




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
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

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)?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top