2012-03-03 11 views
12

Estoy usando Thor y tratando de enviar YAML a un archivo. En irb obtengo lo que espero. Texto simple en formato YAML. Pero cuando parte de un método en Thor, su salida es diferente ...Thor y YAML sacando como binario?

class Foo < Thor 
    include Thor::Actions 

    desc "bar", "test" 
    def set 
    test = {"name" => "Xavier", "age" => 30} 
    puts test 
    # {"name"=>"Xavier", "age"=>30} 
    puts test.to_yaml 
    # !binary "bmFtZQ==": !binary |- 
    # WGF2aWVy 
    # !binary "YWdl": 30 
    File.open("data/config.yml", "w") {|f| f.write(test.to_yaml) } 
    end 
end 

¿Alguna idea?

+1

Me acabo de encontrar tu ejemplo y me dio la salida perfectamente bien. Corrí Thor 0.14.6. – Maran

+0

Gracias por tomarse el tiempo para verificar. No sé qué hacer en este punto. Estoy usando Ruby 1.9.3p125 si eso hace la diferencia. :) – cp3

+1

Instalé 1.9.3 y lo ejecutó de nuevo, y de hecho la salida binaria. Noté que YAML se actualizó durante la instalación. Probablemente tiene algo que ver con esa versión mejorada. – Maran

Respuesta

14

Todas las cadenas de Ruby 1.9 tienen una codificación adjunta.

YAML codifica algunas cadenas que no son UTF8 como binarias, incluso cuando parecen inocentes, sin ningún tipo de caracteres de bits altos. Puede pensar que su código siempre usa UTF8, pero los builtins pueden devolver cadenas que no sean UTF8 (por ejemplo, rutinas de ruta de archivo).

Para evitar la codificación binaria, asegúrese de que todas sus cadenas de codificación sean UTF-8 antes de llamar a_yaml. Cambia la codificación con el método force_encoding ("UTF-8").

Por ejemplo, esta es la forma en codificar mis opciones de comprobación aleatoria, yaml:

options = { 
    :port => 26000, 
    :rackup => File.expand_path(File.join(File.dirname(__FILE__), "../sveg.rb")) 
} 
utf8_options = {} 
options.each_pair { |k,v| utf8_options[k] = ((v.is_a? String) ? v.force_encoding("UTF-8") : v)} 
puts utf8_options.to_yaml 

Aquí es un ejemplo de yaml codificación binaria como cadenas simples

>> x = "test" 
=> "test" 
>> x.encoding 
=> #<Encoding:UTF-8> 
>> x.to_yaml 
=> "--- test\n...\n" 
>> x.force_encoding "ASCII-8BIT" 
=> "test" 
>> x.to_yaml 
=> "--- !binary |-\n dGVzdA==\n" 
7

Después de la versión 1.9.3p125, rubí el motor YAML incorporado tratará todas las codificaciones BINARIAS de forma diferente que antes. Todo lo que necesita hacer es establecer la codificación correcta no BINARIA antes de su String.to_yaml.

en Ruby 1,9, Todos objeto String ha adjuntado un objeto de codificación y como blog siguiente (por James Edward Grey II) mencionado, rubí han de construir en tres tipo de codificación cuando se genera la secuencia: http://blog.grayproductions.net/articles/ruby_19s_three_default_encodings.

Uno de codificación puede resolver su problema => Codificación El código fuente

Esta es la codificación del código fuente, y puede ser especifica mediante la adición de codificación de cadena mágica en la primera línea o de segunda línea (si tiene una cadena en la primera línea de su código fuente sha-bang) el código de codificación de la magia podría ser uno de los siguientes:

  • # codificación: UTF-8
  • # codificación: UTF-8
  • # - - Codificación: UTF-8 - -

por lo que en su caso, si se utiliza el rubí 1.9.3p125 o temprano, esto debe ser resuelto mediante la adición de uno de codificación de magia en el comienzo de su código.

# encoding: utf-8 
require 'thor' 
class Foo < Thor 
    include Thor::Actions 

    desc "bar", "test" 
    def bar 
    test = {"name" => "Xavier", "age" => 30} 
    puts test 
    #{"name"=>"Xavier", "age"=>30} 
    puts test["name"].encoding.name 
    #UTF-8 
    puts test.to_yaml 
    #--- 
    #name: Xavier 
    #age: 30 
    puts test.to_yaml.encoding.name 
    #UTF-8 
    end 
end 
0

He estado luchando con esto usando 1.9.3p545 en Windows, solo con un hash simple que contiene cadenas, y sin Thor.

La gema ZAML resuelve el problema simplemente:

require 'ZAML' 
yaml = ZAML.dump(some_hash) 
File.write(path_to_yaml_file, yaml)