一般我们在使用Gem的过程中不会遇到什么问题,但如果一旦遇到问题解决问题起来可能会比较麻烦。
如果我们知道Gem怎么工作的话,将会帮助我们解决使用Gem中遇到的问题。
gem install 做了什么
gem就是压缩的代码包。你可以通过gem unpack
命令看到:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ gem unpack resque_unit
Fetching: resque_unit-0.4.8.gem ( 100%)
Unpacked gem: '/Users/grant/projects/grant/resque_unit-0.4.8'
$ cd resque_unit-0.4.8
$ find .
.
./lib
./lib/resque_unit
./lib/resque_unit/assertions.rb
./lib/resque_unit/errors.rb
./lib/resque_unit/helpers.rb
./lib/resque_unit/plugin.rb
./lib/resque_unit/resque.rb
./lib/resque_unit/scheduler.rb
./lib/resque_unit/scheduler_assertions.rb
./lib/resque_unit.rb
./lib/resque_unit_scheduler.rb
./README.md
./test
./test/resque_test.rb
./test/resque_unit_scheduler_test.rb
./test/resque_unit_test.rb
./test/sample_jobs.rb
./test/test_helper.rb
gem install
其实就是做类似这样的事情,取下gem压缩包文件,解压到某个特定目录。
这个特定目录位置可以通过gem environment
命令查看INSTALLATION DIRECTORY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
RubyGems Environment :
- RUBYGEMS VERSION : 2 . 0 . 14
- RUBY VERSION : 2 . 0 . 0 ( 2014 - 11 - 13 patchlevel 598 ) [ x86_64 - darwin14 . 0 . 0 ]
- INSTALLATION DIRECTORY : /Users/ grant /. rbenv / versions / 2 . 0 . 0 - p598 / lib / ruby / gems / 2 . 0 . 0
- RUBY EXECUTABLE : /Users/ grant /. rbenv / versions / 2 . 0 . 0 - p598 / bin / ruby
- EXECUTABLE DIRECTORY : /Users/ grant /. rbenv / versions / 2 . 0 . 0 - p598 / bin
- RUBYGEMS PLATFORMS :
- ruby
- x86_64 - darwin - 14
- GEM PATHS :
- /Users/ grant /. rbenv / versions / 2 . 0 . 0 - p598 / lib / ruby / gems / 2 . 0 . 0
- /Users/ grant /. gem / ruby / 2 . 0 . 0
- GEM CONFIGURATION :
- :update_sources => true
- :verbose => true
- :backtrace => false
- :bulk_threshold => 1000
- "gem" => "--no-ri --no-rdoc"
- REMOTE SOURCES :
- https : // rubygems . org /
gem就在INSTALLATION DIRECTORY
的gems目录下面:
1
2
3
$ cd /Users/grant/.rbenv/versions/2.0.0-p598/lib/ruby/gems/2.0.0
$ ls
bin build_info bundler cache doc gems specifications
这个path在不同环境下面的路径是不一样的。所以gem environment
将会非常方便让你
知道gem的代码在哪里。
gem 代码怎么require的呢?
rubygems覆盖了ruby的require方法来实现加载gem的功能。看下面的注释就知道他怎么工作了。
1
2
3
4
5
6
7
8
9
10
11
12
core_ext / kernel_require . rb
##
# When RubyGems is required, Kernel#require is replaced with our own which
# is capable of loading gems on demand.
#
# When you call <tt>require 'x'</tt>, this is what happens:
# * If the file can be loaded from the existing Ruby loadpath, it
# is.
# * Otherwise, installed gems are searched for a file that matches.
# If it's found in gem 'y', that gem is activated (added to the
# loadpath).
#
如果你想加载active_support
,RubyGems首先使用Ruby的require方法从loadpath里去找,
这个将会出现一个错误。
1
2
3
4
LoadError : cannot load such file -- active_support
from ( irb ): 17 :in `require'
from (irb):17
from /usr/local/bin/irb:11:in ` < main > '
通过require找不到的话,rubygems会从Gems文件里面找active_support.rb
。
1
2
irb ( main ): 001 : 0 > spec = Gem :: Specification . find_by_path ( 'active_support' )
=> #<Gem::Specification:0x3fe52159e714 activesupport-4.1.8>
如果找到的话,将会激活这个gem,然后把这个gem加到load path里面去。
1
2
3
4
5
6
irb ( main ): 004 : 0 * $LOAD_PATH
=> [ "/Users/grant/.rbenv/plugins/rbenv-gem-rehash" , "/Users/grant/.rbenv/rbenv.d/exec/gem-rehash" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/site_ruby/2.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/site_ruby/2.0.0/x86_64-darwin14.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/site_ruby" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/vendor_ruby/2.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin14.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/vendor_ruby" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/2.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/2.0.0/x86_64-darwin14.0.0" ]
irb ( main ): 005 : 0 > spec . activate
=> true
irb ( main ): 006 : 0 > $LOAD_PATH
=> [ "/Users/grant/.rbenv/plugins/rbenv-gem-rehash" , "/Users/grant/.rbenv/rbenv.d/exec/gem-rehash" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/gems/2.0.0/gems/i18n-0.6.11/lib" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/gems/2.0.0/gems/thread_safe-0.3.4/lib" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/gems/2.0.0/gems/activesupport-4.1.8/lib" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/site_ruby/2.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/site_ruby/2.0.0/x86_64-darwin14.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/site_ruby" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/vendor_ruby/2.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin14.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/vendor_ruby" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/2.0.0" , "/Users/grant/.rbenv/versions/2.0.0-p481/lib/ruby/2.0.0/x86_64-darwin14.0.0" ]
这时候active_support
就在加载路径里面,你可以在任何地方使用它了。
总结
通过上面基本知道rubygems是怎么工作的,这样遇到相关的问题的时候,你可以根据上面的一些信息挖掘出更深层次的原因。