YAML communication issues between Perl and Ruby

I'm having problems exchanging data between Perl and Ruby through YAML. I have some values ​​that look like a number: a number, for example 1:16.

The Perl YAML libraries (Tiny and XS) code this as 1:16without quotes. The Ruby YAML library (Psych) does not interpret this as a string, but instead becomes somehow a Fixnum value 4560. I can’t figure out how to fix this problem on both sides.

Each value in YAML for my use case should be an object or a string. That way, I could tell the Perl YAML library to quote all the values ​​if such an option existed. Or is there a way to tell the Ruby YAML library to interpret all values ​​as strings? Any ideas?

Changing the language on both sides is not a logical option.

Perl:

use YAML::XS qw(DumpFile);
my $foo={'abc'=>'1:16'};
DumpFile('test.yaml',$foo);

Ruby:

require('yaml')
foo=YAML.load_file('test.yaml')
puts(foo['abc'])

Ruby code will print 4560. One of the comments found out how you get 4560from 1:16, it is 1 hour, 16 minutes, converted to seconds. Good good.

+5
source share
3 answers

According to the specification, Yaml 1.1 1:16 is an integer in the format sexagesimal (base 60).

See also http://yaml.org/type/int.html , which states:

Using ":" allows you to express integers in the base 60, which is convenient for the values ​​of time and angle.

Yaml, Ruby, Psych, (, 1:16 shoud be 71 - Psych , a:b:c, ). Perl ( , YAML:: XS, ) , . YAML:: XS , . YAML:: XS (, ), Psych.

(, Yaml 1.2 .)

Psych - YAML.load_file - .

parse Psych yaml, Ruby, ScalarScanner ( , Ruby):

require('yaml')

class MyScalarScanner < Psych::ScalarScanner
  def tokenize string
    #this is the same regexp as Psych uses to detect base 60 ints:
    return string if string =~ /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+$/
    super
  end
end

tree = YAML::parse_file 'test.yaml'
foo = Psych::Visitors::ToRuby.new(MyScalarScanner.new).accept tree

, YAML.load_file, , .

ScalarScanner tokenize . load_file, :

class Psych::ScalarScanner
  alias :orig_tokenize :tokenize
  def tokenize string
    return string if string =~ /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+$/
    orig_tokenize string
  end
end

foo = YAML.load_file 'test.yaml'

, 1:16. , Perl, . , , , , float floaceimal (, 1:16.44).

+5

. , 1:16 - - ( 4560 - 16 ), , .

, .

  • libyaml, YAML:: XS, Ruby.
  • libsyck, YAML:: Syck, Ruby.

YAML, (, , ).

YAML:: Syck .

$ perl -e'
   use YAML::Syck qw( Dump );
   local $YAML::Syck::SingleQuote = 1;
   print(Dump({abc=>"1:16"}));
'
--- 
"abc": '1:16'

( , !)

+1

Ruby YAML , . 1:16 , , Ruby .

Ruby . . YAML , :

abc: !str 1:16
abc: '1:16'

, Perl:

my $foo={'abc'=>'!str 1:16'};
my $foo={'abc'=>"'1:16'"};

Update: Perl Ruby, :

Perl:

use YAML::XS qw(DumpFile);
my $foo={'abc'=>'1:16'};
DumpFile('test.yaml',$foo);

Ruby:

require 'yaml'
foo=YAML.parse_file('test.yaml')
foo['abc'].value
=> "1:16"
foo['abc'].value.class
=> String

, , load_file, , , , .

-4

All Articles