神秘的“未定义常数” Ruby/Rails 的问题
我有一个 Rails 项目,在处理请求时,常量在某个时刻被破坏。
我正在使用 mime/types
和 restclient
gem。 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
中的 showin 行上抛出异常代码>:
NoMethodError, message: undefined method `type_for_extension' for MIME::Types:Class
**这怎么可能? type_for_extension
与 stringify_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::Dependency.autoload_module!
,它维护一个名为 autoloaded_constants
的表,当ActionController.close
调用 Dispatcher.cleanup_application
。
修复方法是首先加载 mime-types
,因此它不会自动加载。
*哇*
I've got a Rails project where a constant is being nuked at some point while serving a request.
I'm using the mime/types
and restclient
gems. The restclient
module defines an extension to MIME
which contains the method 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
I can access MIME::Types.type_for_extension
on my first invocation of a given controller action. On the second invocation, it's gone.
I can still use MIME::Types.type_for
, but the added method is simply gone, so when I try to use the RestClient module it throws an exception on the line showin in stringify_headers
:
NoMethodError, message: undefined method `type_for_extension' for MIME::Types:Class
**How is this possible? type_for_extension
defined in the same file as stringify_headers
; how could the latter get nuked but not the former?
EDIT: FIXED IT!
In my config:
config.gem "aws-s3", :version => ">= 0.6.2", :lib => "aws/s3"
config.gem 'mime-types', :lib => 'mime/types'
aws-s3
was loading mime-types
via require_library_or_gem
, which ultimate invoked ActiveSupport::Dependencies.autoload_module!
which maintains a table called autoloaded_constants
which are nuked when ActionController.close
calls Dispatcher.cleanup_application
.
Fix was to load mime-types
first, so it's not autoloaded.
*whew*
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
按请求回答我自己的问题。
在我的配置中:
aws-s3
库正在通过require_library_or_gem
加载mime-types
,它最终调用了ActiveSupport::Dependency.autoload_module!
,它维护了一个名为autoloaded_constants
的表,当ActionController.close
调用Dispatcher.cleanup_application。
修复方法是首先加载 mime 类型,因此不会自动加载。
Answering my own question by request.
In my config:
aws-s3
library was loadingmime-types
viarequire_library_or_gem
, which ultimately invokedActiveSupport::Dependencies.autoload_module!
which maintains a table calledautoloaded_constants
which are nuked whenActionController.close
callsDispatcher.cleanup_application.
Fix was to load mime-types first, so it's not autoloaded.