ошибка шеф-повара/ножа (ruby): несоответствие суперкласса для класса Edit (TypeError)

я использую 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.

может кто-нибудь пролить свет на проблему и решение для него?


person Mr.    schedule 09.12.2013    source источник
comment
попробуйте gem uninstall knife-essentials и дайте мне знать, если проблема не исчезнет.   -  person Gopal S Rathore    schedule 09.12.2013
comment
@Gopalrathore действительно решает проблему. как вы узнали, какой рубиновый драгоценный камень вызывает конфликт? (как мне отметить это как решенное?)   -  person Mr.    schedule 10.12.2013
comment
когда я искал эту проблему, я получил исправление этой проблемы от разработчиков этого драгоценного камня в техническом разговоре. Я добавлю его в качестве ответа, если он решит вашу проблему.   -  person Gopal S Rathore    schedule 10.12.2013


Ответы (2)


Я думаю, что это Редактировать класс создает проблему, и uninstalling драгоценный камень основ ножа решит вашу проблему.

Попробуйте один раз:

gem uninstall knife-essentials
person Gopal S Rathore    schedule 10.12.2013

Вы правы, это связанная ошибка.

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__'

Таким образом, вы должны опубликовать/проверить, что именно вам требуется с помощью упаковщика программно и как. Почему бы не использовать Gemfile, а затем bundle exec для запуска скрипта? Позвольте сборщику обрабатывать зависимости для вас, если вы сделали это программно, потому что вас беспокоит, как и когда требуются драгоценные камни, вы можете добавить 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), прежде чем продолжить, а затем вы можете использовать подглядывание, чтобы узнать, где этот класс уже был определен.

[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 install pry-rescue pry-stack_explorer
$ rescue your_program.rb

Или, если вы запускаете свою программу через bundle exec, добавьте это в свой Gemfile

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

И программа будет входить в сеанс прослушивания всякий раз, когда возникает исключение!

Извините, что дал так много вариантов, надеюсь, один поможет!

person Leo Gallucci    schedule 09.12.2013
comment
Нет, вот такие ответы: развернутые и грамотно оформленные - именно такими и должны быть. +1 - person Draco Ater; 09.12.2013
comment
Вау! спасибо, что потратили свое время и поделились своими знаниями. он не решает описанную выше проблему, но показывает, почему она возникает. и еще раз спасибо. - person Mr.; 10.12.2013