2011-11-16 2 views
34

я получаю это предупреждение, когда я бег RSpec:предупреждения Iconv неодобрения с рубином 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.0, 3.1.1, 3.1.2.rc2 версии. Кажется, это связано с камнем sqlite3, но я не уверен. Предупреждений с рубином нет. 1.9.2

Любые предложения, как с этим бороться?

ответ

17

Если вы видите это, это, вероятно, не Рельсы. Если вы посмотрите на методе вокруг напорной линии идет речь в сообщении об ошибке вы в курсе, вы увидите следующее:

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

Просто добавив «р вызывающему» на линии до load_dependency линии и смотрит через стек следы становится довольно легко перетасовать через Gemfile и зафиксировать УСТАРЕВШИМИ драгоценные камни. –

+0

Я думаю, что самый простой способ - просто добавить 'puts '>>>> # {file.inspect}" 'прямо перед' load_dependency', тогда вы можете увидеть, какая загрузка файла вызвала сообщение. –

8

Добавить это в начале вашей программы:

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

и проклинать людей, которые думают, что это профессиональный способ справиться с устаревания.

+3

Я не понимаю, почему это так сильно опущено. Это один из способов заставить его замолчать, если вы уже знаете, но не хотите его обновлять. Если вы поместите это перед другим 'require', который может втянуть 'iconv' в какую-то глубоко вложенную цепочку require, сообщение не появится снова. – Kelvin

+0

Отличный ответ. Это помогло мне избавиться от этого бесполезного предупреждения в системе, где я абсолютно не контролирую установленные драгоценные камни или что-то еще. –

7

Вы можете определить точное местоположение предупреждения, создав исключения для ActiveSupport :: Устаревшие, вместо того, чтобы просто печатать в журнале. В верхней части application.rb:

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

После того, как вы выяснили, где предупреждение исходит от (путем проверки полной трассировки), удалите это снова.

+0

Я получаю 'неопределенное поведение метода = для ActiveSupport :: Устаревание: модуль (NoMethodError)' - Rails 3.2.3, Ruby 1.9.3-p125 –

+3

, очевидно, он использует американское правописание - «поведение». – XP84

+1

@ XP84, спасибо за указание, что вне :) – d11wtq

68

Вы получаете это уведомление об изнашивании, потому что библиотека где-то требует iconv.

iconv - это драгоценный камень, созданный Matz, который может быть использован для преобразования строк из одного формата в другой.

Например, это часто используется:

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

Открывает /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 и должен был использовать: 'p caller, если file.to_s = ~/iconv /' (файл теперь [Pathname] (http://www.ruby-doc.org/stdlib-1.9. 3/libdoc/pathname/rdoc/Pathname.html) вместо String.) –

+1

Это отличный ответ! Я последовал за шагами и обнаружил, какой жемчуг вызывает проблемы в моем приложении. Стыдно, что оригинальный плакат не принял этот ответ ... или любые другие, если на то пошло. – jacklin

+0

Это фантастический ответ и образец того, как должен быть написан ответ SO. Четкое, краткое объяснение и простые шаги для отладки проблемы. –

0

Чтобы удалить это предупреждение ...

пойти ваш каталог .rvm и найти iconv.c (шахта была в ~/.rvm/src/ruby-1.9.3-p125/ext/iconv/iconv.c)

редактировать этот файл, которые удалить или закомментировать вызов warn_deprecated() (должен быть в нижней части)

из каталога этого файла, запустите ruby extconf.rb затем make затем make install

Если сделать трюк

Смежные вопросы