How does Rubygem require all gems? [duplicate]

2019-09-09 16:14发布

This question already has an answer here:

I got interested in Rubygem, and started to explore how does it works, and found out that after 1.9, Rubygem's require became THE require.

With the code below:

require 'debugger'
debugger
require 'thor'

I started to n and l and s, but got stuck at:

  # specification.rb:263
  def self._all # :nodoc:
    unless defined?(@@all) && @@all then
      specs = {}

      self.dirs.each { |dir|
        Dir[File.join(dir, "*.gemspec")].each { |path|
          spec = Gem::Specification.load path.untaint
          # #load returns nil if the spec is bad, so we just ignore
          # it at this stage
          specs[spec.full_name] ||= spec if spec
        }
      }

      @@all = specs.values

      _resort!
    end
    @@all
  end

It seems that before stepping into the method above, @@all has already be been prepared. Then I set break-points everywhere @@all =, but none of the break-points are reached.

What am i missing???


EDIT:

Look at my question again. See require 'debugger'? I feel like a fool.

Now the question is "How can I debug require"?


CLOSED:

Plz see this great answer:https://stackoverflow.com/a/16069229/342366

标签: ruby rubygems
1条回答
ゆ 、 Hurt°
2楼-- · 2019-09-09 17:07

Thx again for this greet answer:https://stackoverflow.com/a/16069229/342366, i did a little debugging myself.

For some one google to this question(and lazy to debug), i decide to post the answer to "How does Rubygem require all gems?"

There are the key-steps below:

  1. load all ".gemspec" in "Ruby193\lib\ruby\gems\1.9.1\specifications"

    Dir[File.join(dir, "*.gemspec")].each { |path|
      spec = Gem::Specification.load path.untaint
      # #load returns nil if the spec is bad, so we just ignore
      # it at this stage
      specs[spec.full_name] ||= spec if spec
    }
    
  2. sort the gems by version desc

    @@all.sort! { |a, b|
      names = a.name <=> b.name
      next names if names.nonzero?
      b.version <=> a.version
    }
    
  3. got the first gem (the higher version)

    self.find { |spec|
      spec.contains_requirable_file? path
    }
    
  4. activate the gem and all dependencies~ Everyone's happy.

查看更多
登录 后发表回答