使用ruby 1.9.3的iconv弃用警告

时间:2011-11-16 08:36:03

标签: ruby-on-rails ruby rspec

当我运行rspec时,我收到此警告:

/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.

我通过rails 3.1.03.1.13.1.2.rc2版本收到相同的警告。似乎它与sqlite3 gem有关,但我不确定。 ruby 1.9.2

没有警告

有任何建议如何处理吗?

5 个答案:

答案 0 :(得分:69)

您收到此弃用通知会导致某处某个库需要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

在第240行打开/gems/activesupport-3.1.0/lib/active_support/dependencies.rb

添加以下行:

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 :(得分: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

然后,您可以轻松运行代码并查看回溯的相关行,以找出警告的根本原因。

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

答案 2 :(得分:8)

将其添加到程序的开头:

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

并诅咒那些认为这是处理弃用的专业方法的人。

答案 3 :(得分:7)

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

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

一旦你弄清楚警告的来源(通过检查完整的回溯),再次删除它。

答案 4 :(得分:0)

删除此警告......

转到.rvm目录并找到iconv.c(我的~/.rvm/src/ruby-1.9.3-p125/ext/iconv/iconv.c}

编辑该文件,删除或注释掉warn_deprecated()的呼叫(应该在底部附近)

从该文件的目录

运行ruby extconf.rb 然后make 然后make install

应该做的伎俩