YAML is a great format for configuration files and for data serialization. There are several Perl modules implementing the function that convert a YAML string into a Perl data structure (deserialize) and that can convert a Perl data structure into a YAML string (serialize).
YAML::Tiny clearly states that it only implements a subset of features, but as far as I understand YAML and YAML::XS are supposed to be drop-in replacements of each other. YAML::Any is a wrapper around several YAML processors, though at one point YAML itself will be promoted to do that job.
Yet, when I tried to switch from YAML to YAML::XS I've encountered two cases of incompatibility. Probably in both cases the YAML file wasn't according to the specs, but in both cases YAML was forgiving and parsed the files as I expected them and in both cases YAML::XS threw exception. I've created minimal examples for both cases and I have tried to parse them with the following:
Space required after :
The YAML file:
examples/files/space_required.yml
x:
'a': 'a'
'b':'b'
perl yaml.pl files/space_required.yml
parsed and created
$VAR1 = {
'x' => {
'a' => 'a',
'b' => 'b'
}
};
perl yaml_xs.pl files/space_required.yml
YAML::XS::Load Error: The problem:
could not find expected ':'
was found at document: 1, line: 4, column: 1
while scanning a simple key at line: 3, column: 3
perl yaml_tiny.pl files/space_required.yml
threw exception:
YAML::Tiny failed to classify line ' 'b':'b'' at yaml_tiny.pl line 11.
perl yaml_syck.pl files/space_required.yml
threw exception:
Syck parser (line 4, column -1): syntax error
The solution here is to put a space after the :
in the line of 'b' as in the following:
examples/files/space_required_solved.yml
x:
'a': 'a'
'b': 'b'
I am not sure if this is something that needs to be fixed in the YAML module, or just documented, but I've opened a ticket.
Value with : needs to be quoted
The YAML file:
examples/files/quote_colon.yml
a:
- b: c:
perl yaml.pl files/quote_colon.yml
properly parses the YAML file and generates this data structure:
$VAR1 = {
'a' => [
{
'b' => 'c:'
}
]
};
perl yaml_xs.pl files/quote_colon.yml
throws exception:
YAML::XS::Load Error: The problem:
mapping values are not allowed in this context
was found at document: 1, line: 2, column: 9
perl yaml_tiny.pl files/quote_colon.yml
throws exception:
YAML::Tiny found illegal characters in plain scalar: 'c:' at yaml_tiny.pl line 11.
perl yaml_syck.pl files/quote_colon.yml
throws exception:
Syck parser (line 2, column 9): syntax error
The solution here is to put the value with the :
in it between single-quote marks:
examples/files/quote_colon_solved.yml
a:
- b: 'c:'
Here too I've opened a ticket for consideration.
The scripts I used
use 5.010;
use strict;
use warnings;
use Data::Dumper qw(Dumper);
use YAML;
my $file = shift or die "Usage: $0 YAML_FILE\n";
say $YAML::VERSION;
my $x = YAML::LoadFile($file);
say Dumper $x;
use 5.010;
use strict;
use warnings;
use Data::Dumper qw(Dumper);
use YAML::XS;
my $file = shift or die "Usage: $0 YAML_FILE\n";
say $YAML::XS::VERSION;
my $x = YAML::XS::LoadFile($file);
say Dumper $x;
use 5.010;
use strict;
use warnings;
use Data::Dumper qw(Dumper);
use YAML::Tiny;
my $file = shift or die "Usage: $0 YAML_FILE\n";
say $YAML::Tiny::VERSION;
my $x = YAML::Tiny::LoadFile($file);
say Dumper $x;
use 5.010;
use strict;
use warnings;
use Data::Dumper qw(Dumper);
use YAML::Syck;
my $file = shift or die "Usage: $0 YAML_FILE\n";
say $YAML::Syck::VERSION;
my $x = YAML::Syck::LoadFile($file);
say Dumper $x;