Ruby/Rails 的神秘“未定义常量”问题

Posted

技术标签:

【中文标题】Ruby/Rails 的神秘“未定义常量”问题【英文标题】:Mystifying "undefined constant" issue with Ruby/Rails 【发布时间】:2011-10-06 22:24:51 【问题描述】:

我有一个 Rails 项目,其中一个常量在服务请求时的某个时间点被核弹。

我正在使用 mime/typesrestclient 宝石。 restclient 模块定义了对 MIME 的扩展,其中包含方法 type_for_extension

module RestClient
    ...
    def stringify_headers headers
      result[key] = target_values.map  |ext| MIME::Types.type_for_extension(ext.to_s.strip) .join(', ')
      ...
    end
  end
end

module MIME
  class Types
    def type_for_extension ext
      candidates = @extension_index[ext]
      candidates.empty? ? ext : candidates[0].content_type
    end
    class << self
      def type_for_extension ext
        @__types__.type_for_extension ext
      end
    end
  end
end

我可以在给定控制器操作的第一次调用时访问MIME::Types.type_for_extension。在第二次调用时,它消失了。

我仍然可以使用MIME::Types.type_for,但是添加的方法已经消失了,所以当我尝试使用 RestClient 模块时,它会在stringify_headers 中显示的行中引发异常:

NoMethodError, message: undefined method `type_for_extension' for MIME::Types:Class

**这怎么可能? type_for_extensionstringify_headers相同的文件 中定义;后者怎么会被核爆,而前者却不能?


编辑:已修复!

在我的配置中:

config.gem "aws-s3", :version => ">= 0.6.2", :lib => "aws/s3"  
config.gem 'mime-types', :lib => 'mime/types'

aws-s3 正在通过require_library_or_gem 加载mime-types,最终调用了ActiveSupport::Dependencies.autoload_module!,该ActiveSupport::Dependencies.autoload_module! 维护了一个名为autoloaded_constants 的表,当ActionController.close 调用Dispatcher.cleanup_application 时,该表被nuked

修复是先加载mime-types,所以它不会自动加载。

*呼*

【问题讨论】:

我想说您的编辑有资格作为答案。你可以回答自己的问题,我怀疑有人会反对回答这样棘手的问题。 @Mud 很高兴你能解决这个问题。 同意亩。请将您的解决方案添加为您的问题的答案,并将其标记为最佳答案。绝对允许回答您自己的问题:) 【参考方案1】:

应要求回答我自己的问题。

在我的配置中:

config.gem "aws-s3", :version => ">= 0.6.2", :lib => "aws/s3"  
config.gem 'mime-types', :lib => 'mime/types'

aws-s3 库正在通过require_library_or_gem 加载mime-types,最终调用ActiveSupport::Dependencies.autoload_module!,该表维护一个名为autoloaded_constants 的表,当ActionController.close 调用Dispatcher.cleanup_application. 时,该表被销毁

修复是先加载 mime-types,所以它不会自动加载。

【讨论】:

以上是关于Ruby/Rails 的神秘“未定义常量”问题的主要内容,如果未能解决你的问题,请参考以下文章

Ruby/Rails:生成脚手架的代码在哪里

Eloquent Tinker - 未定义常量

未定义常量 http/2

Laravel 有来自 tinker 的未定义常量 App\User

markdown [rails:devise] Ruby on Rails的身份验证gem。 #ruby #rails

使用 ruby​​/rails 将文件上传到网站