2012-03-03 25 views
12

Używam Thora i próbuję wyprowadzić YAML do pliku. W irb dostaję to, czego się spodziewam. Zwykły tekst w formacie YAML. Ale gdy część metody w Thor, jego produkcja jest inna ...Wyjście Thor & YAML jako binarne?

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 

Jakieś pomysły?

+1

Właśnie prowadził swój przykład i to dało mi perfekcyjnie wyjście. Uruchomiłem thor 0.14.6. – Maran

+0

Dzięki za poświęcenie czasu na sprawdzenie. Nie wiem, co robić w tym momencie. Używam Ruby 1.9.3p125, jeśli robi to jakąkolwiek różnicę. :) – cp3

+1

Zainstalowałem 1.9.3 i uruchomił go ponownie, a nawet wyjście binarne. Zauważyłem, że YAML został uaktualniony podczas instalacji. Prawdopodobnie ma to coś wspólnego z tą ulepszoną wersją. – Maran

Odpowiedz

14

Wszystkie ciągi Ruby 1.9 mają dołączone kodowanie.

YAML koduje niektóre ciągi inne niż UTF8 jako binarne, nawet jeśli wyglądają niewinnie, bez żadnych znaków bitowych. Można by pomyśleć, że twój kod zawsze używa UTF8, ale wbudowane mogą zwracać łańcuchy inne niż UTF8 (ex Ścieżki ścieżek plików).

Aby uniknąć kodowania binarnego, przed wywołaniem to_yaml upewnij się, że wszystkie kodowania są kodowane w UTF-8. Zmień kodowanie za pomocą metody force_encoding ("UTF-8").

Na przykład, to jak mogę zakodować moje opcje mieszania w 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 

Oto przykład kodowania yaml prostych ciągów jako binarne

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

Po wersji 1.9.3p125, rubin wbudowany silnik YAML traktuje wszystkie kodowanie BINARNE inaczej niż poprzednio. Wszystko, co musisz zrobić, to ustawić poprawne kodowanie inne niż BINARY przed String.to_yaml.

w Ruby 1.9, All obiekt String dołączony obiekt Kodowanie i jak po blogu (James Edward Grey II) wspomniano, rubin mają zbudować w trzech typ kodowania jest generowany gdy String: http://blog.grayproductions.net/articles/ruby_19s_three_default_encodings.

Jednym z kodowaniem mogą rozwiązać swój problem => kod źródłowy Kodowanie

To kodowanie kodu źródłowego, a może określić, dodając magicznego kodowania znaków w pierwszym wierszu lub drugiej linii (jeśli masz ciąg na pierwszej linii kodu źródłowego sha-Bang) magia kod kodowanie może być jedną z następujących czynności:

  • # kodowanie: UTF-8
  • # kodowanie: UTF-8
  • # - - Kodowanie: UTF-8 - -

więc w Twoim przypadku, jeśli używasz rubin 1.9.3p125 lub nowszej, to powinien być rozwiązany poprzez dodanie jednego magicznego kodowania na początku kodu.

# 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

mam zmaga się z tym, stosując 1.9.3p545 na Windows - tylko z prostym hash zawierających ciągi - i Thor.

Klejnot ZAML rozwiązuje problem po prostu:

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