在Rails中使用gems时,"无法删除Object :: ClassMethods"的内容源于什么?

Mat*_*hew 11 rake logging rubygems ruby-on-rails

在安装提供类似问题的宝石时,我经常遇到问题:

有谁知道这源于什么?我已经看到了几个不同的案例,但仍然没有学到究竟是什么导致它.

$ 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
Run Code Online (Sandbox Code Playgroud)

小智 16

我相信我找到了一种实用的非侵入式方法来解决问题的根源.它适用于我(Rails 2.3):

碰巧发生异常#blame_file!尽管它会失败并导致新的错误,但在某些时候调用它,从而屏蔽原始错误.

所以,打开你的FIRST初始化程序并添加,

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

您将获得有罪的文件和原始错误消息.这应该足以确定您的问题.

不要忘记删除Exception初始化程序代码段.


gtd*_*gtd 15

此错误的原因是双重例外.通常代码中的某些内容会崩溃,从而引发初始异常.然后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
Run Code Online (Sandbox Code Playgroud)

评论一下这些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
Run Code Online (Sandbox Code Playgroud)

然后你会马上看到你的错误.