G
Gavin Sinclair
[Botp:]
I'd like to make some comments on the use of 'require' vs 'require_gem' in
general.
'require' is as old as Ruby, and it's something people use all the time.
'require_gem' is new and commonly perceived as a hassle because it
involves a dependency (RubyGems), and you have to do "require 'rubygems'"
first.
I'm not going to argue that it's _never_ a hassle, but in many contexts,
using 'require_gem' is just fine.
If you are writing a program for home or work use, where you control the
runtime environment, then this is a reasonable approach:
* in the "base file" of your project, require 'rubygems'
* in other project files, require the "base file"
* now 'require_gem' is available wherever you like
For instance, my work project is called 'dmv1'. Nevermind what that
means. So I have 'lib/dmv1.rb' which is the "base file", which defines
some modules, constants, etc., that are used across the board.
'lib/dmv1/**/*.rb' all "require 'dmv1'" and build on those modules. So
without any real effort -- just some thought in project structure --
require_gem is available everywhere.
The only gem I'm actually using in the project is ActiveRecord. Of
course, I could just "require 'active_record'" instead of bothering with
the gem, since the stub is installed as well. However, while I like the
stub system, I see it as a convenience, not something I would make a
project depend on. Since it's actually quite easy for me to use
require_gem, I do so.
OK, so much for in-house projects. What about a more general project that
gets released on RubyForge and where the author has no control over the
target environment? In that case, the project author will probably be
loath to *depend* on RubyGems, and will target the lowest common
denominator: i.e. having the file installed in site_ruby. For example,
David H. H. encourages people to install ActiveRecord via RubyGems, but to
ensure the stub is installed as well. In the project code, such authors
are unlikely to actually use require_gem. So RubyGems is effectively
limited to a distribution (and package management) mechanism, not a
runtime concern.
Targeting the lowest common denominator is a tried and true software
practice. At some point in the future, however, I hope RubyGems is a
guaranteed part of every (new) Ruby installation, and is therefore a
common enough denominator for authors to target in *general* code, not
just tightly controlled in-house efforts.
The benefits of preferring to use require_gem instead of require in
general code such as this are not obvious, and perhaps not even real, from
the point of view of the project's author. The direct benefit is that you
can specify the version requirement of the gem that you are loading.
That's probably a concern in only a minority of projects, and even then,
the real or perceived hassle of using require_gem might outweigh the real
or perceived benefit of such version constraining ability. The indirect
benefit of using require_gem is that a Ruby ecosystem based on RubyGems is
better than one based on site_ruby, and each usage of require_gem helps
make that ecosystem a reality.
Neither of these benefits - direct and indirect - of targeting RubyGems in
a general released project actually bring any benefit to the authors of
most projects, since they don't need the version constraints, and their
contribution to the ecosystem is an evolutionary step. Evolutionary steps
tend to be small and unnoticed in and of themselves, so there's not much
incentive for a project author to deliberately do it.
In summary, concerns about target environments are likely to limit the
features of RubyGems that are commonly used for some time. Assuming it
does become a real standard sometime in the future, it will be a sliding
scale of usage between now and then. During the life of RubyGems
(effectively the six months of this year), it has been propelled by people
making an effort to use it and giving feedback to the development team.
We are very grateful for this input; without it we would have only made
half the progress we have.
RubyGems as an excellent package installer and manager is a good place to
be. RubyGems as part of the runtime fabric is also good and is
technically implemented. It will probably also be socially implemented in
time. Between now and then lies a lot of evolutionary steps. Knowing the
feelings of the community during this transition via general discussion
and specific feedback is essential.
Cheers,
Gavin
P.S. Keep those gems coming! If you are a project author and would like
help creating and releasing a gem, email me. Remember that releasing a
gem file on RubyForge means it automatically becomes available via remote
install, offering a tremendous convenience to the Ruby community. Look at
http://gems.rubyforge.org/gems to see what's available already.
P.P.S. If you are an enthusiatic user of a particular project, or your
project depends on it, and it's not available as a gem, then you can offer
to help its author release it as a gem. A lot of people will benefit from
this small effort.
[Rich Kilmer:]
Actually, because of our stub capability, you don't need to do
require_gem anymore.
You can just:
require "ruvi"
And it now works. The 'stub' is a file in site_ruby/1.8 (named ruvi.rb)
which contains:
require 'rubygems'
require_gem 'ruvi'
So, require_gem is not longer necessary UNLESS you need to require a
particular version of a library. In that case you need the require_gem
because it takes the optional second parameter that holds the version
requirement.
I'd like to make some comments on the use of 'require' vs 'require_gem' in
general.
'require' is as old as Ruby, and it's something people use all the time.
'require_gem' is new and commonly perceived as a hassle because it
involves a dependency (RubyGems), and you have to do "require 'rubygems'"
first.
I'm not going to argue that it's _never_ a hassle, but in many contexts,
using 'require_gem' is just fine.
If you are writing a program for home or work use, where you control the
runtime environment, then this is a reasonable approach:
* in the "base file" of your project, require 'rubygems'
* in other project files, require the "base file"
* now 'require_gem' is available wherever you like
For instance, my work project is called 'dmv1'. Nevermind what that
means. So I have 'lib/dmv1.rb' which is the "base file", which defines
some modules, constants, etc., that are used across the board.
'lib/dmv1/**/*.rb' all "require 'dmv1'" and build on those modules. So
without any real effort -- just some thought in project structure --
require_gem is available everywhere.
The only gem I'm actually using in the project is ActiveRecord. Of
course, I could just "require 'active_record'" instead of bothering with
the gem, since the stub is installed as well. However, while I like the
stub system, I see it as a convenience, not something I would make a
project depend on. Since it's actually quite easy for me to use
require_gem, I do so.
OK, so much for in-house projects. What about a more general project that
gets released on RubyForge and where the author has no control over the
target environment? In that case, the project author will probably be
loath to *depend* on RubyGems, and will target the lowest common
denominator: i.e. having the file installed in site_ruby. For example,
David H. H. encourages people to install ActiveRecord via RubyGems, but to
ensure the stub is installed as well. In the project code, such authors
are unlikely to actually use require_gem. So RubyGems is effectively
limited to a distribution (and package management) mechanism, not a
runtime concern.
Targeting the lowest common denominator is a tried and true software
practice. At some point in the future, however, I hope RubyGems is a
guaranteed part of every (new) Ruby installation, and is therefore a
common enough denominator for authors to target in *general* code, not
just tightly controlled in-house efforts.
The benefits of preferring to use require_gem instead of require in
general code such as this are not obvious, and perhaps not even real, from
the point of view of the project's author. The direct benefit is that you
can specify the version requirement of the gem that you are loading.
That's probably a concern in only a minority of projects, and even then,
the real or perceived hassle of using require_gem might outweigh the real
or perceived benefit of such version constraining ability. The indirect
benefit of using require_gem is that a Ruby ecosystem based on RubyGems is
better than one based on site_ruby, and each usage of require_gem helps
make that ecosystem a reality.
Neither of these benefits - direct and indirect - of targeting RubyGems in
a general released project actually bring any benefit to the authors of
most projects, since they don't need the version constraints, and their
contribution to the ecosystem is an evolutionary step. Evolutionary steps
tend to be small and unnoticed in and of themselves, so there's not much
incentive for a project author to deliberately do it.
In summary, concerns about target environments are likely to limit the
features of RubyGems that are commonly used for some time. Assuming it
does become a real standard sometime in the future, it will be a sliding
scale of usage between now and then. During the life of RubyGems
(effectively the six months of this year), it has been propelled by people
making an effort to use it and giving feedback to the development team.
We are very grateful for this input; without it we would have only made
half the progress we have.
RubyGems as an excellent package installer and manager is a good place to
be. RubyGems as part of the runtime fabric is also good and is
technically implemented. It will probably also be socially implemented in
time. Between now and then lies a lot of evolutionary steps. Knowing the
feelings of the community during this transition via general discussion
and specific feedback is essential.
Cheers,
Gavin
P.S. Keep those gems coming! If you are a project author and would like
help creating and releasing a gem, email me. Remember that releasing a
gem file on RubyForge means it automatically becomes available via remote
install, offering a tremendous convenience to the Ruby community. Look at
http://gems.rubyforge.org/gems to see what's available already.
P.P.S. If you are an enthusiatic user of a particular project, or your
project depends on it, and it's not available as a gem, then you can offer
to help its author release it as a gem. A lot of people will benefit from
this small effort.