2011-11-16 99 views
34

当我运行RSpec的我得到这样的警告:的iconv弃用警告使用Ruby 1.9.3

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

我与轨道3.1.03.1.13.1.2.rc2版本相同的警告。似乎它与sqlite3宝石有关,但我不确定。有没有警告与红宝石1.9.2

任何建议如何处理它?

回答

17

如果你看到这个,很可能是而不是 Rails。如果你看看周围的线在您发布的错误被提到的方法,你会看到以下内容:

def require(file, *) 
    result = false 
    load_dependency(file) { result = super } 
    result 
end 

我不是说这是你的代码,不一定,但我敢肯定,这是而不是实际上调用iconv的那条线。就我而言,我发现我的项目代码实际上包含对iconv的引用。

如果您想检查您的代码以获取此类参考,请在您的项目目录中尝试grep -ir iconv ./

iconv实际上在库中时,它可能很难找到。通过临时改变上述方法:

def require(file, *) 
    result = false 
    puts 
    puts caller.reverse 
    load_dependency(file) { result = super } 
    result 
end 

此后可以轻松地运行您的代码和grep出来的回溯相关行找到警告的根本原因。

ruby your/code.rb 2>&1 | grep -B 5 iconv 
+0

通过简单地添加“P呼叫者”上线load_dependency前行,并通过堆栈跟踪它变得很容易通过你的Gemfile洗牌和修复过时的期待宝石。 –

+0

我认为最简单的方法就是在'load_dependency'之前简单地添加'puts'>>>>#{file.inspect}'',然后就可以看到哪个文件加载导致了这个消息。 –

8

添加到您的程序的启动:

oldverb = $VERBOSE; $VERBOSE = nil 
require 'iconv' 
$VERBOSE = oldverb 

和诅咒谁认为这是处理弃用专业的方式的人。

+3

我不明白为什么这么低估了。如果您已经意识到但不愿意升级,这是一种沉默它的方法。如果你把它放在另一个'require's之前,它可能会在一些深层嵌套的require链中拉入'iconv',那么这个消息就不会再出现。 – Kelvin

+0

完美答案。这帮助我摆脱了这个无用的警告,因为我完全无法控制安装的宝石或任何东西。 –

7

您可以通过为ActiveSupport :: Deprecation生成异常而不是仅打印到日志来锁定警告的确切位置。在application.rb中的顶部:

ActiveSupport::Deprecation.behavior = Proc.new do |message, backtrace| 
    raise message 
end 

一旦你想通了其中的警告是来自(通过检查全面回溯),再删除此。

+0

我得到'未定义的方法行为= ActiveSupport :: Deprecation:Module(NoMethodError)' - Rails 3.2.3,Ruby 1.9.3-p125 –

+3

显然它使用美国拼写 - “行为”。 – XP84

+1

@ XP84,谢谢指出:) – d11wtq

68

您正在收到此弃用通知,导致图书馆某处要求iconv

iconv是由Matz创建的一个gem,可用于将字符串从一种格式转换为另一种格式。

例如,这通常用于:

Iconv.iconv('UTF-8//IGNORE', 'UTF-8', content)的魔力这一点点花费,可能有无效字符,并将其转换为适当的UTF-8字符串中的UTF-8字符串。

已经决定在Ruby 1.9.3中我们不应该再使用iconv而是使用内置的String#encodeencode更强大,可以让你更灵活。

的理论是,上面的例子可以替换为:

string.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => "?")

在实践中看来这是imperfect

这也导致了不到轻松的故事谁愿意支持1.8创业板的创作者:

content = RUBY_VERSION.to_f < 1.9 ? 
    Iconv.iconv('UTF-8//IGNORE', 'UTF-8', "content") : 
    "#{content}".encode(Encoding::UTF_8, :invalid => :replace, :undef => :replace, :replace => '') 

所以,你有一个宝石的地方,是需要的iconv,找到它:

假设你的错误信息是:/gems/activesupport-3.1.0/lib/active_support/dependencies.rb:240

打开向上/gems/activesupport-3.1.0/lib/active_support/dependencies.rb上线240:

添加一行:

p caller if file =~ /iconv/ 

(刚过:load_dependency(file) { result = super }

你会得到一个大胖子的堆栈跟踪:

 
rake --tasks 
/home/sam/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:251:in `block in require': iconv will be deprecated in the future, use String#encode instead. 
["/home/sam/.rvm/gems/ruby-1.9.3-p125/gems/calais-0.0.13/lib/calais.rb:5:in `'", 
.. more omitted .. 

这告诉我这是calais宝石。通过拉请求,我am not the first。拉并没有被猛拉英寸


根据不同的宝石,也有可能是没有这个错误的升级版,所以我建议你首先升级你的宝石。如果你运气不好,你可以与派生宝石的任务,不幸被卡住,以摆脱这种(例如,如果你拉的请求来解决它颓丧)

+1

谢谢,这对我有帮助。我在ActiveSupport 3.2.9上,并且必须使用:'如果file.to_s =〜/ iconv /'是'p调用者'(文件现在是[Pathname](http://www.ruby-doc.org/stdlib-1.9)。 3/libdoc/pathname/rdoc/Pathname.html)而不是字符串。) –

+1

这是一个很好的答案!我按照步骤找到了什么宝石导致我的应用程序出现问题。令人遗憾的是,原始的海报并未接受这个答案......或者任何其他的问题。 – jacklin

+0

这是一个梦幻般的答案,以及如何编写答案的模型。清晰,简洁的解释和易于遵循的步骤来调试问题。 –

0

要消除此警告...

去您.rvm目录,找到iconv.c(我的是在~/.rvm/src/ruby-1.9.3-p125/ext/iconv/iconv.c

编辑该文件被删除或注释掉调用warn_deprecated()(应该是接近底部)

从该文件所在的目录,运行ruby extconf.rb 然后make 然后make install

应该做的伎俩