2012-03-03 9 views
12

Sto usando Thor e sto provando a produrre YAML su un file. In irb, ottengo quello che mi aspetto. Testo normale in formato YAML. Ma quando parte di un metodo in Thor, la sua uscita è diversa ...Thor e YAML escono come binari?

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 

Qualche idea?

+1

Ho appena eseguito il vostro esempio e mi ha dato in uscita perfettamente bene. Ho eseguito thor 0.14.6. – Maran

+0

Grazie per aver dedicato del tempo per controllare. Sono a corto di cosa fare a questo punto. Sto usando Ruby 1.9.3p125 se questo non fa differenza. :) – cp3

+1

Ho installato 1.9.3 e lo ha eseguito di nuovo, e in effetti l'output binario. Ho notato che YAML è stato aggiornato durante l'installazione. Probabilmente ha qualcosa a che fare con quella versione aggiornata. – Maran

risposta

14

Tutte le stringhe di Ruby 1.9 hanno una codifica ad esse collegata.

YAML codifica alcune stringhe non UTF8 come binari, anche se sembrano innocenti, senza caratteri di bit alti. Si potrebbe pensare che il proprio codice utilizzi sempre UTF8, ma i builtin possono restituire stringhe non UTF8 (ex routine del percorso file).

Per evitare la codifica binaria, assicurarsi che tutte le codifiche delle stringhe siano UTF-8 prima di chiamare a_ambr. Cambia la codifica con il metodo force_encoding ("UTF-8").

Ad esempio, questo è il modo ho codificare le mie opzioni hash in 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 

Ecco un esempio di codifica YAML semplici stringhe come binario

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

Dopo la versione 1.9.3p125, rubino il motore YAML integrato tratterà tutte le codifiche BINARY in modo diverso rispetto a prima. Tutto quello che devi fare è impostare la codifica non BINARIA corretta prima di String.to_yaml.

in Ruby 1.9, All oggetto String hanno attribuito un oggetto Encoding e come seguendo blog (da James Edward Grey II) menzionato, rubino hanno costruire in tre tipi di codifica quando viene generato String: http://blog.grayproductions.net/articles/ruby_19s_three_default_encodings.

Uno di codifica può risolvere il tuo problema => Il codice sorgente di codifica

Questa è la codifica del codice sorgente, e può essere specificato con l'aggiunta di stringa di codifica magia alla prima linea o seconda linea (se si dispone di un stringa la prima riga di codice sorgente sha-bang) il codice di codifica magia potrebbe essere uno dei seguenti:

  • # encoding: utf-8
  • # codifica: utf-8
  • # - - Codifica: UTF-8- -

così nel tuo caso, se si utilizza rubino 1.9.3p125 o poi, questo dovrebbe essere risolto con l'aggiunta di uno dei codifica magia all'inizio del codice.

# 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

ho lottato con questo utilizzando 1.9.3p545 su Windows - solo con un semplice hash contenente le stringhe - e nessun Thor.

La gemma ZAML risolve il problema molto semplicemente:

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