当需要特定的Ruby gem时如何调试停止执行?

时间:2015-02-12 19:38:34

标签: ruby gem bundler

我正在写一个宝石。我依赖的一个宝石是停止执行需要它的文件。这是一个例子:

# main.rb
require 'bundler'
Bundler.require
puts 'Going to do something now...'
Mygem::Nested::Thing.do_something

# Gemfile
source 'https://rubygems.org'
gem 'mygem', path: './mygem'

# mygem.gemspec
...
spec.add_dependency 'mygem-dependency'
...

# mygem.rb
puts 'Loading mygem.rb'
require_relative 'mygem/nested/thing'
puts 'Finished loading my gem.rb'

# mygem/nested/thing.rb
puts 'Loading mygem/nested/thing.rb'
require 'mygem-dependency'
module Mygem
  module Nested
    class Thing
      def self.do_something
        MygemDependency.do_something
      end
    end
  end
end
puts 'Finished loading mygem/nested/thing.rb'

当我运行脚本时,当我尝试加载依赖gem时加载停止:

$ bundle exec ruby main.rb
Loading mygem.rb
Loading mygem/nested/thing.rb
Going to do something now...
main.rb:4:in `<main>': uninitialized constant Mygem::Nested (NameError)

它永远不会完成加载我宝石的其余部分。但是,似乎在Bundler.require之后继续执行所有操作。如果我注释掉需要依赖gem的行,除了依赖于其他gem的行之外,一切都按预期工作。

$ bundle exec ruby main.rb
Loading mygem.rb
Loading mygem/nested/thing.rb
Finished loading mygem/nested/thing.rb
Finished loading my gem.rb
Going to do something now...
mygem/nested/thing.rb:7:in `<main>': uninitialized constant Mygem::Nested::Thing::MygemDependency (NameError)

如果我将require语句移动到方法体中,我会收到一个加载错误:

module Mygem
  module Nested
    class Thing
      def self.do_something
        require 'mygem-dependency'
        MygemDependency.do_something
      end
    end
  end
end

$ bundle exec ruby main.rb
Loading mygem.rb
Loading mygem/nested/thing.rb
Finished loading mygem/nested/thing.rb
Finished loading my gem.rb
Going to do something now...
mygem/nested/thing.rb:7:in `require': cannot load such file -- mygem-dependency (LoadError)

宝石没有问题因为我可以直接使用它。出于某种原因,我在尝试在我的宝石中使用它时遇到了问题。我怎样才能找出问题并解决它?

2 个答案:

答案 0 :(得分:0)

  

如何在需要特定Ruby gem时调试正在停止执行

选择任何错误,并尝试解决问题。重复,直到您不再收到任何错误。获得的经验越多,您就越能够知道从哪里开始。当你收到这样的错误时:

main.rb:4:in `<main>': uninitialized constant Mygem::Nested (NameError)

我会检查:

  1. 您是否确实定义了以Mygem::Nested开头的内容?

  2. 您是否在一份要求声明中拼错了名字?它应该是MyGem::Nested吗?

  3. 您的require语句是否使用正确的语法?换句话说,您是否需要使用完整路径,相对路径或文件名?

  4. 您的代码实际上适合我:

    $ tree .
    .
    ├── Gemfile
    ├── Gemfile.lock
    ├── main.rb
    ├── mygem
    │   ├── lib
    │   │   ├── mygem
    │   │   │   └── nested
    │   │   │       └── thing.rb
    │   │   └── mygem.rb
    │   └── mygem.gemspec
    └── your_main.rb
    

    main.rb的:

    require 'bundler'
    Bundler.require
    
    #Bundler.setup(:default)
    #require 'mygem'
    
    Mygem::Nested::Thing.do_something
    

    mygem.gemspec:

    Gem::Specification.new do |s|
      s.name        = 'mygem'
      s.version     = '0.0.0'
      s.date        = '2015-02-12'
      s.summary     = "A new internet!"
      s.description = "Creates a new internet that is completely secure."
      s.authors     = ["7stud"]
      s.email       = '7@new.i.com'
      s.files       = [
        "lib/mygem.rb",
        "lib/mygem/nested/thing.rb",
      ]
      s.homepage    = 'http://rubygems.org/gems/mygem'
      s.license     = 'GNU Public'
    
      s.add_dependency 'nokogiri' 
    end
    

    LIB / mygem.rb:

    puts 'Loading mygem.rb'
    require_relative 'mygem/nested/thing'
    puts 'Finished loading my gem.rb'
    

    LIB / mygem /嵌套/ thing.rb:

    puts 'Loading mygem/nested/thing.rb'
    
    require 'nokogiri'  #Your gem's dependency, which is added to .gemspec file
    
    module Mygem
      module Nested
        class Thing
          def self.do_something
            doc = Nokogiri::HTML('<div>hello</div>')
            puts doc.at_xpath('//div/text()')
          end
        end
      end
    end
    
    puts 'Finished loading mygem/nested/thing.rb'
    

    的Gemfile:

    source 'https://rubygems.org'
    
    gem 'mygem', path: './mygem'
    

    结果:

    $ ruby --version
    ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin10.0]
    
    $ ruby main.rb 
    Loading mygem.rb
    Loading mygem/nested/thing.rb
    Finished loading mygem/nested/thing.rb
    Finished loading my gem.rb
    hello
    

答案 1 :(得分:0)

问题证明是&#34;扩展&#34;我正在使用的gem(mygem-dependency)未在其mygem-dependency.rb目录中提供名为lib的文件。因此,我不需要mygem-dependency,而是需要mygem/dependency

另一个问题是Bundler正在为Gemfile中指定的gem中的依赖关系加载错误。 https://github.com/bundler/bundler/blob/master/lib/bundler/runtime.rb#L49