Reputation: 12251
The title is the question, and here's the context that prompts it.
The Gemfile:
source "http://rubygems.org"
# Specify your gem's dependencies in the gemspec
gemspec
Here is the top of the rackup file:
require 'rubygems'
require "bundler/setup"
On running the rackup file an error is thrown:
<module:Rack>': GemName is not a class (TypeError)
Why? Because I'm writing a piece of Rack middleware, and the standard layout is:
lib/
rack/
gem_name.rb
gem_name/
version.rb
gem_name.rb will contain:
module Rack
class GemName
version.rb will contain:
module Rack
module GemName
VERSION = "0.0.1"
Finally, the gem_name.gemspec will contain:
require "rack/flash-in-the-pan/version"
#...
s.version = Rack::GemName::VERSION
Naming a module and a class by the same name isn't a problem as long as you don't require both files at the same time. Normally, this wouldn't happen, as you either need the version for building the gem, or you need to run the gem library, only one or other gets required.
But, this time I decided to use Bundler to manage the gem's dependencies. When requiring the gem library via bundler it obviously runs the gemspec too. I can "fix" it easily enough, I define the version number by hand in the gemspec.
So back to my question - why does Bundler need to look in the gemspec at the library's runtime?
bundler (1.0.21)
Any insight is much appreciated.
Upvotes: 2
Views: 871
Reputation: 4520
Whenever you run bundler, it has to parse the Gemfile to actually figure out what gems need to be loaded, what has to be added to $LOAD_PATH
and so on. As part of that, it has to parse gemspec
.
The Gemfile.lock contains info on all of the gems as well as the dependencies to save startup time, but it doesn't alleviate the need for it to parse the Gemfile.
There are various ways you could work around it. Two simple ones would be to use File.read
and some regex to pull out the version. Or require the gem_name.rb and gem_name/version.rb files.
Upvotes: 3