gpt4 book ai didi

ruby-on-rails - 在 Rails 中跟踪依赖加载

转载 作者:数据小太阳 更新时间:2023-10-29 07:50:52 25 4
gpt4 key购买 nike

我们的团队正在开发一个新的应用程序,我们从 Rails 3.1 和 Ruby 1.9.2 开始 - 昨晚我把它带到了 Ruby 1.9.3。

我们在依赖链 (css_parser) 中使用的一个 gem 最终在其中有一个 require 'iconv',触发了 a deprecation warning在 1.9.3 中看起来像这样:

.../gems/activesupport-3.1.1/lib/active_support/dependencies.rb:240:in `block in require': iconv will be deprecated in the future, use String#encode instead.

起初我天真地把它归咎于 rails 没有更好的跟踪,直到我在任何地方都找不到 require 'iconv'。

我找到这个的唯一方法是我开始在我的 Gemfile 中注释掉一些东西,然后我终于想到加载 irb 并开始依次需要每个库的好主意。我也可以在 gems 目录中执行文件系统 grep,但我不确定“require 'iconv'”是触发错误的原因。

多么棒的 PITA。必须有一个更好的方法 - 只是在 rake 任务中做一个 --trace 加载 rails 并没有削减它。是否有某种方式/任何方式触发对此的跟踪,以显示相对较长的库依赖项列表中的哪一行触发了弃用?

最佳答案

所以,这可能有点没有实际意义,因为我不太可能再次遇到这个问题(css_parser gem 是我当前的 Rails 3.1/Ruby 1.9.3 项目中唯一需要 iconv 的 gem)。

但它一个谜题,所以我想找到解决它的方法。

在这种情况下,问题是非常特定于 iconv 的。还有其他 ruby​​ 弃用,但在大多数情况下,它们似乎通过 Kernel#warn(如果是 ruby​​)或 rb_warn()(如果是 C)——但是 warning in iconv.c is a little different比其他人 - 无论如何它是 rb_stderr 的看跌期权。

所以也许我可以做以下事情

  1. 覆盖内核#require 以捕获标准错误
  2. 在调用原始 Kernel#require 后检查 iconv 消息
  3. 如果找到消息则引发异常,从而获得跟踪
  4. 尽可能在 bundler 运行之前执行此操作。

事实证明我不能做 #4 - 因为 Bundler 直接调用 Kernel.require - 但我可以使用 Bundler 来解析 Gemfile 来给我一个需要我自己的东西的列表。

这就是我得到的 - 感谢 this stack overflow post有关捕获标准错误的指针 - 以及 aliasing the original Kernel#require 上想法的 ruby​​gems 来源

# override Kernel#require to intercept stderr messages on require
# and raise a custom error if we find one mentioning 'iconv'
require "stringio"

class RequireError < StandardError
end

module Kernel

alias :the_original_require require
private :the_original_require

def capture_stderr
# The output stream must be an IO-like object. In this case we capture it in
# an in-memory IO object so we can return the string value. You can assign any
# IO object here.
previous_stderr, $stderr = $stderr, StringIO.new
yield
$stderr.string
ensure
# Restore the previous value of stderr (typically equal to STDERR).
$stderr = previous_stderr
end

def require(name)
captured_output = capture_stderr do
the_original_require(name)
end

if(captured_output =~ %r{iconv})
raise RequireError, 'iconv requirement found'
end
end
end

require 'bundler'

# load the list of Bundler requirements from the Gemfile
required_libraries = Bundler.definition.dependencies.map(&:name)

# loop through and require each, ignoring all errors other than
# our custom error

required_libraries.each do |requirement|
begin
require(requirement)
rescue Exception => e
if(e.class == RequireError)
raise e
end
end
end

瞧!帮助追踪 iconv 要求所在位置的跟踪消息。

最后,可能只是搜索“require 'iconv'”仍然是最好的(一旦明确这是导致错误的原因)。

但是,就像在生活中一样。 Some Yaks Must Be Shaved.

关于ruby-on-rails - 在 Rails 中跟踪依赖加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7957888/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com