4

bundler用来处理 ruby​​ gems 依赖项。我需要以bundler编程方式使用宝石。

当我尝试以knife编程方式调用时,它的依赖项在Gemfile我得到错误中指定。我执行knife如下:

Chef::Knife.run ["-v"] #invoking knife

它返回以下错误:

/var/lib/gems/2.0.0/gems/chef-11.6.2/lib/chef/knife/edit.rb:5:in `<class:Knife>': superclass mismatch for class Edit (TypeError)

我熟悉Ruby on Rails 3:“类的超类不匹配......”以及发生这种情况的原因。但是我没有做任何与上述stackoverflow帖子中的解释一致的事情。

有人可以阐明这个问题并解决它吗?

4

2 回答 2

5

你是对的,这是相关的错误。

class Edit已经在其他地方定义了与现在尝试使用的超类不同的超类。

irb/pry 的简单测试

[56] pry(main)> class Comida; end

[57] pry(main)> class Comida < Integer; end

TypeError: superclass mismatch for class Comida
from (pry):53:in `__pry__'

因此,您应该以编程方式发布/检查您对 bundler 的确切要求以及方式。为什么不使用Gemfileand thenbundle exec来运行你的脚本呢?让捆绑器为您处理依赖关系,如果您以编程方式执行此操作,因为您担心需要添加的 gem 的方式和时间,required: false以避免自动行为并在需要时自己执行要求,即

改变这个Gemfile

gem 'chef-solo'
gem 'knife-solo'

对此:

gem 'chef-solo', require: false
gem 'knife-solo', require: false

然后在您的代码中手动执行您需要的需求并收回您需要的控制:

# ... code ....
require 'chef-solo'

# ... more code ...
require 'knife-solo'

至少有 3 种调试方法:

1)普通的旧红宝石调试

调试它,您可以在该违规行设置断点:

$ ruby -r debug your_program.rb

# Set a breakpoint where problem arises
break /var/lib/gems/2.0.0/gems/chef-11.6.2/lib/chef/knife/edit.rb:5

# Set a poor-man debug `puts` to find out where is a class defined
class Object
  def self.inherited(klass)
    targets = %w(Edit Chef::Knife::Edit)
    puts "#{klass.name} defined at #{__FILE__}:#{__LINE__}" if targets.include?(klass.name)
  end
end

# Now run until program ends or hits that breakpoint
cont

# Once it hits the breakpoing program will pause there and you can play around but the previus `puts` should already have showed where the `Edit` class is first defined.

#=> Chef::Knife::Edit defined at /some/pissing/file:432

2) 用宝石撬

您还可以使用pry.binding在该行停止程序并通过临时编辑环顾四周以查看正在发生的事情edit.rb

$ vim /var/lib/gems/2.0.0/gems/chef-11.6.2/lib/chef/knife/edit.rb + 5

# Add this code before the offending line:
require 'pry'
binding.pry

还需要包含gem "pry"在您Gemfile的文件中以使其正常工作并运行程序,bundle exec不要忘记。

程序将在继续之前停止(在该行binding.pry),然后您可以使用 pry goodness 找出该类已定义的位置

[1] pry(main)> ? Bundler
#=> From: .../gems/bundler-1.3.5/lib/bundler.rb @ line 9

[2] pry(main)> ? Chef::Knife::Edit
#=> From: xxxxxxx.rb @ line xx

3) 使用宝石撬-救援

还有一个pry-rescue gem,它会“在出现问题时启动一个 pry session”

$ gem install pry-rescue pry-stack_explorer
$ rescue your_program.rb

或者,如果通过bundle exec将其添加到您的程序来运行您的程序Gemfile

group :development do
  gem 'pry-rescue'
  gem 'pry-stack_explorer'
end

每当引发异常时,程序将进入一个撬动会话!

抱歉给了这么多选择,希望有帮助!

于 2013-12-09T11:47:51.220 回答
2

我认为这个Edit 课程正在制造问题,而uninstallingknife-essentials gem 将解决您的问题。

尝试一次:

gem uninstall knife-essentials
于 2013-12-10T09:44:59.747 回答