При работе с гемами в Rails, что не может удалить ствол Object :: ClassMethods? - PullRequest
11 голосов
/ 13 февраля 2010

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

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

$ 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

Ответы [ 6 ]

16 голосов
/ 20 октября 2011

Мне кажется, я нашел практичный ненавязчивый метод, чтобы найти корень проблемы. У меня это работает (Rails 2.3):

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

Итак, откройте свой ПЕРВЫЙ инициализатор и добавьте,

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

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

Не забудьте удалить фрагмент инициализатора Exception.

15 голосов
/ 02 августа 2010

Причиной этой ошибки является двойное исключение. Обычно что-то в вашем коде дает сбой, что вызывает первоначальное исключение. Затем пользовательские 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 голосов
/ 02 июня 2010

Я только что столкнулся с этой проблемой снова. После некоторой отладки я пришел к такому выводу: эта странная ошибка означает, что у 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

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

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

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

0 голосов
/ 24 июня 2011

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

0 голосов
/ 04 ноября 2010

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

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

0 голосов
/ 02 апреля 2010

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

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

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

...