Ruby on rails ruby 1.9.3中的iconv弃用警告

Ruby on rails ruby 1.9.3中的iconv弃用警告,ruby-on-rails,ruby,rspec,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. /gems/activesupport-3.1.0/lib/active\u support/dependencies.rb:240:在“请求中的块”:i

我在运行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. /gems/activesupport-3.1.0/lib/active\u support/dependencies.rb:240:在“请求中的块”:iconv将在将来被弃用,请改用字符串#编码。 我在rails的
3.1.0
3.1.1
3.1.2.rc2
版本中得到了同样的警告。似乎它与
sqlite3
gem有关,但我不确定。ruby 1.9.2没有警告


有什么建议吗?

如果你看到这一点,很可能是而不是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

将以下内容添加到程序的开头:

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

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

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

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

一旦您确定警告来自何处(通过检查完整回溯),请再次删除此警告。

您收到此弃用通知,因为某个库需要
iconv

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

例如,这通常用于:

Iconv.Iconv('UTF-8//IGNORE','UTF-8',content)
这一小魔术将可能具有无效字符的UTF-8字符串转换为正确的UTF-8字符串

已经决定,在Ruby 1.9.3中,我们不应该再使用iconv,而应该使用内置的<代码>编码功能更强大,让您更灵活

理论上,上述示例可以替换为:

string.encode(“UTF-8”,:无效=>:replace,:未定义=>:replace,:replace=>“?”)

实际上,这似乎是正确的

这也为希望支持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 => '')
(紧接着:
load_依赖项(文件){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 .. rake——任务 /home/sam/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.6/lib/active\u support/dependencies.rb:251:在“请求中的块”中:iconv将来将被弃用,请改用字符串编码。 [“/home/sam/.rvm/gems/ruby-1.9.3-p125/gems/calais-0.0.13/lib/calais.rb:5:in`'”, …更多省略。。 这告诉我这是宝石。通过查看拉取请求,我知道。拉取没有被拉入



根据gem的不同,可能会有一个升级版本没有此错误,因此我建议您首先升级gem。如果您运气不好,您可能会遇到一个不幸的任务,即分叉gem以消除此错误(例如,如果您修复它的pull请求失败)

删除此警告

转到你的.rvm目录,找到
iconv.c
(我的地址是
~/.rvm/src/ruby-1.9.3-p125/ext/iconv/iconv.c

编辑该文件,删除或注释掉对
warn\u deprecated()
的调用(应该在底部附近)

从该文件的目录中,运行
rubyextconf.rb
然后
make
然后
makeinstall


通过简单地在load_依赖项行之前的一行添加“p caller”并查看堆栈跟踪,就可以很容易地在Gemfile中移动并修复过时的gems。我认为最简单的方法是简单地添加
put“>>>”{file.inspect}”
在加载依赖项之前,您可以看到是哪个文件加载导致了该消息。我得到了
未定义的方法behavior=for ActiveSupport::Deprecation:Module(NoMethodError)
--Rails 3.2.3,Ruby 1.9.3-p125显然它使用了美式拼写--“behavior”嗯..似乎没有引发异常。我是在
要求'rails/all'
之后得到它的。谢谢,这对我有帮助。我使用的是ActiveSupport 3.2.9,必须使用:
p caller if file.to_s=~/iconv/
(文件现在是一个而不是一个字符串。)这是一个很好的答案!我按照步骤进行了操作,发现了gem在我的应用程序中造成问题的原因。很遗憾,原始海报没有接受这个答案…或者其他任何答案。这是一个非常棒的答案,也是一个如何编写SO答案的模型。清晰、简洁的解释以及调试问题的简单步骤。我我不明白为什么这被否决了这么多。如果你已经意识到但不愿意升级,这是一种让它安静下来的方法。如果你把它放在另一个
require
s之前,它可能会在一些深度嵌套的
require
链中拉入
iconv
,那么消息就不会再次出现。完美的答案。这帮了我的忙在一个我完全无法控制已安装的gems或任何东西的系统上,摆脱这个无用的警告。 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 ..