2011-11-16 11 views
34

estoy recibiendo esta advertencia cuando corro rspec:advertencia iconv desaprobación con el rubí 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. 

me da la misma advertencia con rieles 3.1.0, 3.1.1, 3.1.2.rc2 versiones. Parece que está relacionado con la gema sqlite3, pero no estoy seguro. No hay advertencias con ruby ​​1.9.2

¿Alguna sugerencia de cómo manejarlo?

Respuesta

17

Si está viendo esto, es muy probable que no Rails. Si nos fijamos en el método que rodea la línea que se hace referencia en el error informados, verá lo siguiente:

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

No estoy diciendo que es su código, necesariamente, pero estoy seguro de que es no es realmente la línea en cuestión donde se llama a iconv. En mi caso, descubrí que el código de mi proyecto en realidad contenía una referencia a iconv.

Si desea verificar su código para dicha referencia, intente grep -ir iconv ./ en su directorio de proyectos.

Cuando iconv está realmente en una biblioteca puede ser más difícil de encontrar. Al cambiar temporalmente el método anterior para:

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

A continuación, puede ejecutar fácilmente su código y grep las líneas relevantes de la traza inversa para encontrar la causa de la advertencia.

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

Simplemente añadiendo "que llama p" en una línea antes de la línea load_dependency y mirando a través de la pila de traza se hace muy fácil de mezclar a través de su Gemfile y fijar el fuera de fecha gemas. –

+0

Creo que la manera más fácil es simplemente agregar 'puts" >>>> # {file.inspect} "' justo antes de 'load_dependency', luego puede ver qué carga de archivo causó el mensaje. –

8

Añadir esto al comienzo de su programa:

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

y la maldición de las personas que piensan que esta es una manera profesional para manejar desaprobación.

+3

No veo por qué esto es downvoted tanto. Esta es una manera de silenciarlo si ya lo sabe pero no desea actualizarlo. Si pones esto antes que el otro 'require's que posiblemente pueda insertar' iconv' en alguna cadena 'require' profundamente anidada, entonces el mensaje no volverá a aparecer. – Kelvin

+0

Respuesta perfecta. Esto me ayudó a deshacerme de esta advertencia inútil en un sistema donde no tengo absolutamente ningún control sobre las gemas instaladas ni nada. –

7

Puede determinar la ubicación exacta de la advertencia generando excepciones para ActiveSupport :: Deprecation, en lugar de simplemente imprimir en el registro. En la parte superior de application.rb:

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

Una vez que haya descubierto que la advertencia está viniendo (mediante la inspección de la traza completa), quite esto de nuevo.

+0

Obtengo el comportamiento del método 'undefined = para ActiveSupport :: Deprecation: Module (NoMethodError)' - Rails 3.2.3, Ruby 1.9.3-p125 –

+3

aparentemente usa la ortografía estadounidense: "comportamiento". – XP84

+1

@ XP84, gracias por señalar eso :) – d11wtq

68

Recibirá este aviso de desacato porque una biblioteca en algún lugar requiere iconv.

iconv es una gema creada por Matz que se puede utilizar para convertir cadenas de un formato a otro.

Por ejemplo, esto se utiliza a menudo:

Iconv.iconv('UTF-8//IGNORE', 'UTF-8', content) este poco de magia toma una cadena UTF-8 que puede tener caracteres no válidos y la convierte en una cadena adecuada UTF-8.

Se ha decidido que en Ruby 1.9.3 no deberíamos usar iconv más y en su lugar usar el String#encode incorporado. encode es más poderoso y le permite más flexibilidad.

La teoría es que el ejemplo anterior se podría sustituir por:

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

En la práctica parece que esto es imperfect.

Esto también conduce a una historia menos fácil para los creadores de la gema que deseen apoyar a 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 => '') 

tanto, usted tiene una joya en alguna parte que está requiriendo iconv, para encontrarlo:

Asumiendo que su mensaje de error es: /gems/activesupport-3.1.0/lib/active_support/dependencies.rb:240

Abre /gems/activesupport-3.1.0/lib/active_support/dependencies.rb en la línea 240:

Añadir la línea:

p caller if file =~ /iconv/ 

(justo después: load_dependency(file) { result = super })

obtendrá un gran seguimiento de la pila de grasa:

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

Esto me dice que es el calais joya. Revisando las solicitudes de extracción, I am not the first. La atracción no se ha arrancado en.


Dependiendo de la gema, puede haber una versión mejorada que no tiene este error, por lo que recomiendo actualizar sus gemas en primer lugar. Si tienes la mala suerte puede ser atrapado con la desafortunada tarea de bifurcar una joya para deshacerse de esto (si por ejemplo, su solicitud de extracción solucionarlo languidece)

+1

Gracias, esto me ayudó. Estaba en ActiveSupport 3.2.9 y tuve que usar: 'p invocador if file.to_s = ~/iconv /' (el archivo es ahora [Pathname] (http://www.ruby-doc.org/stdlib-1.9. 3/libdoc/pathname/rdoc/Pathname.html) en lugar de String.) –

+1

¡Esta es una excelente respuesta! Seguí los pasos y descubrí qué gema estaba causando los problemas en mi aplicación. Es una pena que el póster original no haya aceptado esta respuesta ... o cualquier otra para el caso. – jacklin

+0

Esta es una respuesta fantástica y un modelo de cómo debe escribirse una respuesta SO. Explicación clara y concisa y pasos fáciles de seguir para solucionar el problema. –

0

Para eliminar esta advertencia ...

ir a su directorio .rvm y encontrar iconv.c (la mía estaba en ~/.rvm/src/ruby-1.9.3-p125/ext/iconv/iconv.c)

editar ese archivo se elimine o comente la llamada a warn_deprecated() (debería estar cerca de la parte inferior)

desde el directorio de ese archivo, ejecute ruby extconf.rb continuación make continuación make install

debe hacer el truco

Cuestiones relacionadas