当我运行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.0
,3.1.1
,3.1.2.rc2
版本收到相同的警告。似乎它与sqlite3
gem有关,但我不确定。 ruby 1.9.2
有任何建议如何处理吗?
答案 0 :(得分:69)
您收到此弃用通知会导致某处某个库需要iconv
。
iconv是由Matz创建的gem,可用于将字符串从一种格式转换为另一种格式。
例如,经常使用它:
Iconv.iconv('UTF-8//IGNORE', 'UTF-8', content)
这一点魔法会使用一个UTF-8字符串,该字符串可能包含无效字符并将其转换为正确的UTF-8字符串。
已经决定在Ruby 1.9.3中我们不应再使用iconv而是使用内置的String#encode。 encode
功能更强大,可让您更灵活。
理论上,上述例子可以替换为:
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
应该做的伎俩