Подтвердить что ты не робот

Когда вы работаете с драгоценными камнями в Rails, из чего следует "не удается удалить Object:: ClassMethods"?

Часто я столкнулся с проблемой при установке gems, которая создает проблему, например:

Кто-нибудь знает, от чего это происходит? Я видел в нем несколько разных случаев, но до сих пор не понял, что именно вызывает его.

$ sudo rake gems:install --trace
(in /u/app/releases/20100213003957)
** Invoke gems:install (first_time)
** Invoke gems:base (first_time)
** Execute gems:base
** Invoke environment (first_time)
** Execute environment
rake aborted!
cannot remove Object::ClassMethods
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:603:in `remove_const'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:603:in `remove_constant'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:603:in `instance_eval'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:603:in `remove_constant'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:549:in `new_constants_in'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:549:in `each'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:549:in `new_constants_in'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
/u/app/releases/20100213003957/vendor/rails/railties/lib/tasks/misc.rake:4
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:in `call'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:in `execute'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:in `each'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:in `execute'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:578:in `invoke_with_call_chain'
/usr/lib64/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:571:in `invoke_with_call_chain'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:564:in `invoke'
/u/app/releases/20100213003957/vendor/rails/railties/lib/tasks/gems.rake:17
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:in `call'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:in `execute'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:in `each'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:in `execute'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:578:in `invoke_with_call_chain'
/usr/lib64/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:571:in `invoke_with_call_chain'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:588:in `invoke_prerequisites'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:585:in `each'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:585:in `invoke_prerequisites'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:577:in `invoke_with_call_chain'
/usr/lib64/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:571:in `invoke_with_call_chain'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:564:in `invoke'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2027:in `invoke_task'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2005:in `top_level'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2005:in `each'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2005:in `top_level'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2044:in `standard_exception_handling'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:1999:in `top_level'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:1977:in `run'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2044:in `standard_exception_handling'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:1974:in `run'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/bin/rake:31
/usr/bin/rake:19:in `load'
/usr/bin/rake:19
4b9b3361

Ответ 1

Причиной этой ошибки является двойное исключение. Обычно что-то в вашем коде сбой, что вызывает первоначальное исключение. Затем пользовательский интерфейс Rails требует попыток сохранить пространство имен в чистоте, удалив частично определенные константы, что является целью метода new_constants_in. Проблема в том, что new_constants_in неправильно обрабатывает какую-то конкретную конструкцию где-то внутри кода, я подозреваю, из-за неправильного обращения к пространствам имен модулей или чего-то еще (потому что ClassMethods, вероятно, находится внутри некоторого модуля, кроме Object). В любом случае, я не отслеживал ошибку в компоненте Rails или что-то еще, потому что, честно говоря, это не стоит усилий.

Решение (не предлагая что-то менее инвазивное для ядра Rails) - это быстрый хак, чтобы выяснить, что подняло первоначальное исключение. Все, что вам нужно сделать, это перейти туда, где вызывается Dependencies.new_constants_in и комментировать его (есть несколько мест, где это может быть). Так, например:

def require(file, *extras) #:nodoc:
  if Dependencies.load?
    Dependencies.new_constants_in(Object) { super }
  else
    super
  end
rescue Exception => exception  # errors from required file
  exception.blame_file! file
  raise
end

Прокомментируйте материал new_constants_in:

def require(file, *extras) #:nodoc:
#  if Dependencies.load?
#    Dependencies.new_constants_in(Object) { super }
#  else
    super
#  end
#rescue Exception => exception  # errors from required file
#  exception.blame_file! file
#  raise
end

Затем вы сразу увидите свою ошибку.

Ответ 2

Я считаю, что нашел практический неинтрузивный метод, чтобы получить корень проблемы. Это работает для меня (Rails 2.3):

Как это происходит Exception # blame_file! вызывается в какой-то момент, несмотря на то, что он потерпит неудачу и вызовет новую ошибку, тем самым маскируя исходную ошибку.

Итак, откройте свой первый инициализатор FIRST и добавьте

class Exception
  def blame_file!( file )
    puts "CULPRIT >> '#{file.to_s}' # #{self.to_s}"
  end
end

Вы получите как инкриминируемый файл, так и исходное сообщение об ошибке. Этого должно быть достаточно, чтобы точно определить вашу проблему.

Не забудьте удалить фрагмент инициализатора исключений.

Ответ 3

Я снова столкнулся с этой проблемой. После некоторой отладки я пришел к такому выводу: эта странная ошибка означает, что Rails имеет некоторые проблемы с требованием определенной библиотеки. Проблема в том, что Rails не сообщает нам, какая библиотека вызывает проблему. Итак, первый шаг, который вам нужно сделать, это следующее:

Откройте этот файл (или соответствующий файл в вашей установке): /u/app/releases/ 20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb

и отредактируйте метод load_with_new_constant_marking, чтобы он выглядел так:

def load_with_new_constant_marking(file, *extras) #:nodoc:
  if Dependencies.load?
    Dependencies.new_constants_in(Object) { load_without_new_constant_marking(file, *extras) }
  else
    load_without_new_constant_marking(file, *extras)
  end
rescue Exception => exception  # errors from loading file
    puts "FAILS HERE: " + file
    exception.blame_file! file
    raise
end

С этого момента, когда вы запускаете приложение или задание на рейк, вместо того, чтобы просто сказать вам, что он "не может удалить Object:: ClassMethods", Rails сообщит вам, какой файл вызывает проблему (просто найдите инструкцию "FAILS HERE" ). (Кстати, я полагаю, что это то, что должен делать метод exception.blame_file!, но, очевидно, это не работает).

После того, как вы обнаружили файл, который вызывает проблему, вы можете выкопать этот конкретный фрагмент и использовать некоторые блоки исключений, чтобы добраться до сути проблемы.

Надеюсь, что это поможет.

Ответ 4

Я также начал ловить эту странную ошибку сегодня - проследил ее до устаревшего драгоценного камня mysql.

Я только что переключился с использования пакета Mac MySQL (тот, который поставляется с PrefPane), на скомпилированную версию в стиле Homebrew, а старый /usr/local/mysql задерживался в моем PATH

Удаление этого каталога (и других следов старого MySQL), а затем повторное связывание моего приложения решило его!

Ответ 5

Я столкнулся с этой проблемой и попробовал каждое из вышеупомянутых решений, но безрезультатно.

В моем случае проблема заключалась в том, что я случайно включил ActionView::Helpers::TextHelper и ActionView::Helpers::NumberHelper в начало файла (тем самым включив их в корневой класс Object), это работало нормально в Rails 3.0.0.rc, но поднял "невозможно удалить Object:: ClassMethods" в Rails 3.0.1, и после того, как он был поднят, приложение осталось застрявшим до перезагрузки сервера.

Ответ 6

Это началось со мной, но только после того, как я включил драгоценный камень delayed_job в свой пакет. Как и Eric выше, я включил ActionView:: Helpers:: TextHelper и ActionView:: Helpers:: NumberHelper в верхней части контроллера, но самое забавное, что у меня не было никаких проблем, пока я не начал использовать delayed_job. Я понятия не имею, что происходит, я просто удалил включения, и проблема, похоже, исчезла.