35

I'm getting this warning when I run 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.

I get the same warning with rails 3.1.0, 3.1.1, 3.1.2.rc2 versions. Seems it's related to sqlite3 gem, but I'm not sure. There are no warnings with ruby 1.9.2

Any suggestions how to deal with it?

John Bachir
  • 22,495
  • 29
  • 154
  • 227
NARKOZ
  • 27,203
  • 7
  • 68
  • 90

5 Answers5

69

You are getting this deprecation notice cause a library somewhere is requiring iconv.

iconv is a gem created by Matz that can be used to convert strings from one format to another.

For example this is often used:

Iconv.iconv('UTF-8//IGNORE', 'UTF-8', content) this little bit of magic takes a UTF-8 string that may have invalid chars and converts it to a proper UTF-8 string.

It has been decided that in Ruby 1.9.3 we should not be using iconv any more and instead use the built-in String#encode. encode is more powerful and allows you more flexibility.

The theory is that the above example could be replaced with:

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

In practice it seems this is imperfect.

This also leads to a less than easy story for gem creators who wish to support 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 => '')

So, you have a gem somewhere that is requiring iconv, to find it:

Assuming your error message is: /gems/activesupport-3.1.0/lib/active_support/dependencies.rb:240

Open up /gems/activesupport-3.1.0/lib/active_support/dependencies.rb on line 240:

Add the line:

p caller if file =~ /iconv/

(just after: load_dependency(file) { result = super })

You will get a big fat stack trace:

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

This tells me it is the calais gem. Looking through pull requests, I am not the first. The pull has not been yanked in.


Depending on the gem, there may be an upgraded version that does not have this error, so I would recommend you upgrade your gems first. If you are unlucky you may be stuck with the unfortunate task of forking a gem to get rid of this (if for example your pull request to fix it languishes)

Community
  • 1
  • 1
Sam Saffron
  • 128,308
  • 78
  • 326
  • 506
  • 1
    Thanks, this helped me. I was on ActiveSupport 3.2.9 and had to use: `p caller if file.to_s =~ /iconv/` (file is now a [Pathname](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/pathname/rdoc/Pathname.html) instead of a String.) – Anthony Panozzo Dec 13 '12 at 12:41
  • 1
    This is a great answer! I followed the steps and found what gem was causing the problems in my app. Its a shame the original poster hasn't accepted this answer... or any other ones for that matter. – jacklin Feb 18 '13 at 14:47
  • This is a fantastic answer and a model for how a SO answer should be written. Clear, concise explanation and easy to follow steps to debug the issue. – David Tuite Jun 26 '13 at 10:35
17

If you're seeing this, it's very probably not Rails. If you look at the method surrounding the line being referred to in the error you posted, you'll see the following:

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

I'm not saying it's your code, necessarily, but I'm certain that it's not actually the line in question where iconv is being called. In my case, I found that my project's code actually contained a reference to iconv.

If you want to check your code for such a reference, try grep -ir iconv ./ in your project directory.

When iconv is actually in a library it can be harder to find. By temporarily changing the above method to:

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

You can then easily run your code and grep out the relevant lines of the backtrace to find the root cause of the warning.

ruby your/code.rb 2>&1 | grep -B 5 iconv
Kyle Heironimus
  • 7,741
  • 7
  • 39
  • 51
Ryan Long
  • 662
  • 1
  • 6
  • 18
  • By simply adding "p caller" on a line before the load_dependency line and looking through the stack traces it becomes quite easy to shuffle through your Gemfile and fix the out of date gems. – Alexander Kellett Apr 06 '12 at 10:24
  • I think the easiest way is to simply add `puts ">>>> #{file.inspect}"` right before `load_dependency`, then you can see which file loading caused the message. – John Bachir Aug 17 '12 at 21:35
8

Add this to the start of your program:

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

and curse the people who think this is a professional way to handle deprecation.

cabo
  • 987
  • 8
  • 9
  • 3
    I don't see why this is downvoted so much. This is one way to silence it if you are already aware but are unwilling to upgrade. If you put this before the other `require`s that could possibly pull in `iconv` in some deeply nested `require` chain, then the message won't appear again. – Kelvin Jul 26 '13 at 16:11
  • Perfect answer. This helped me in getting rid of this useless warning on a system where I have absolutely no control over the installed gems or anything. – marc.guenther Apr 18 '16 at 20:35
7

You can pin down the exact location of the warning by generating exceptions for ActiveSupport::Deprecation, instead of just printing to the log. At the top of application.rb:

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

Once you've figured out where the warning is coming from (by inspecting the full backtrace), remove this again.

d11wtq
  • 34,788
  • 19
  • 120
  • 195
0

To remove this warning...

go to your .rvm directory and find iconv.c (mine was at ~/.rvm/src/ruby-1.9.3-p125/ext/iconv/iconv.c)

edit that file are remove or comment out the call to warn_deprecated() (should be near the bottom)

from that file's directory, run ruby extconf.rb then make then make install

Should do the trick

WebDev
  • 384
  • 1
  • 2
  • 12