2014-01-30 8 views
9

ich folgende .yaml Datei mit diesem Stück CodePerl YAML-Modul erkennt nicht Typen Skalare

foo : bar 
s : 1 
hx: 0x34 

laden:

use YAML qw(LoadFile Dump); 
use Data::Dumper; 
my $d=LoadFile("test.yaml"); 
print Dumper($d); 
print "x  =", $d->{hx},"\n"; 
print "x/2  =", $d->{hx}/2,"\n"; 
print "hex(x)/2 =", hex($d->{hx})/2,"\n"; 

und der Ausgang ist

Output: 
> ./yaml.pl 
$VAR1 = { 
      'foo' => 'bar', 
      'hx' => '0x34', 
      's' => '1' 
     }; 
x  =0x34 
x/2  =0 
hex(x)/2 =26 

Das bedeutet, dass alle Skalare als Strings behandelt werden, was ich nicht erwartet habe. Aus der YAML-Dokumentation unter CPAN http://metacpan.org/pod/YAML ging ich davon aus, dass dies durch implizites Tagging gehandhabt wird und dass das Modul die Hex-Nummer erkennt.

Weiß jemand, wie man das macht?

+4

Dies ist wohl ein Fehler, abhängig davon, welches [Schema] (http://www.yaml.org/spec/1.2/spec.html#Schema) der YAML-Prozessor verwendet (das Verhalten Ihres Programms ist konsistent mit Failsafe oder JSON, aber nicht mit Core). Sie könnten die [Probleme] dieses Moduls (https://rt.cpan.org/Public/Dist/Display.html?Name=YAML) durchsehen und sehen, ob diese Diskrepanz zuvor gemeldet wurde, oder dort ein neues Problem eröffnen. – amon

+0

Sind Sie in der Lage, YAML :: XS zu installieren und zu testen? Wenn ich Ihre Yaml-Eingabe mit der XS-Version getestet habe, wurde die 1 nicht zitiert. Der hx-Wert wurde jedoch weiterhin als Zeichenfolge behandelt. – user3183018

+0

Wie ich getestet habe?/Usr/bin/perl -MYAML :: Any = LoadFile -MData :: Dumper -e $ y = LoadFile ($ ARGV [0]); Dumper drucken ($ y). "\ n" '$ YAMLFILE' – user3183018

Antwort

2

Wenn Sie die Loader-Klasse untersuchen, werden Sie feststellen, dass die _parse_inline-Unterklasse einige Verzweigungen für Sequenzen, Mappings, Strings in einfachen und doppelten Anführungszeichen und einige andere Fälle enthält. Sie müssen lediglich einen Zweig für Werte hinzufügen, die mit 0x beginnen. Ich schrieb diesen Zweig und eine Untergruppe für den Umgang mit Hex-Werten für . Ich habe es mit ein paar grundlegenden Eingaben versucht, und es scheint zu tun, was Sie wollten. Wenn es auch für Sie funktioniert, können Sie den Patch einreichen.

dump.pl

use YAML qw(LoadFile Dump); 
use Data::Dumper; 
my $d=LoadFile("test.yaml"); 
$d=LoadFile("test.yaml"); 
print Dumper($d); 
print "x  =", $d->{hx},"\n"; 
print "x/2  =", $d->{hx}/2,"\n"; 
print "hex(x)/2 =", hex($d->{hx})/2,"\n"; 



$d=LoadFile("sym1.yaml"); 
print Dumper($d); 

print "dodo[4] =", $d->{dodo}->{doto}[4], "\n"; 
print "dodo[3] =", $d->{dodo}->{doto}[3], "\n"; 

sym1.yaml

"symfony 1.0": 
    PHP: 5.0 
    Propel: 1.2 
"symfony 1.2": 
    PHP: 5.2 
    Propel: 1.3 

dodo: 
    doto: [1,23,4, 0x34, 0x16 ] 
    dozo: [1,23,4, 0x12, 0x11 ] 
    dofo: { a: 2, 358: 0x166, 255: 0xff, 255: 0xFF} 
ffa: 0xFfA 

perl $ dump.pl

$VAR1 = { 
      'foo' => 'bar', 
      'hx' => 52, 
      's' => '1' 
     }; 
x  =52 
x/2  =26 
hex(x)/2 =41 
$VAR1 = { 
      'ffa' => 4090, 
      'symfony 1.2' => { 
          'PHP' => '5.2', 
          'Propel' => '1.3' 
         }, 
      'dodo' => { 
        'dofo' => { 
           'a' => '2', 
           '255' => 255, 
           '358' => 358 
          }, 
        'dozo' => [ '1','23', '4', 18, 17 ], 
        'doto' => [ '1', '23', '4', 52, 22 ] 
        }, 
      'symfony 1.0' => { 
          'PHP' => '5.0', 
          'Propel' => '1.2' 
         } 
     }; 

doto[4] =22 
doto[3] =52 

Patch für YAML 0.900.0

diff --git a/Loader.pm b/Loader.pm 
index 3bf20c7..d7096df 100644 
--- a/Loader.pm 
+++ b/Loader.pm 
@@ -437,6 +437,10 @@ sub _parse_inline { 
     $node = $self->_parse_inline_single_quoted(); 
     $node = $self->_parse_implicit($node) if $implicit; 
    } 
+ elsif ($self->inline =~ /^0x/) { 
+  $node = $self->_parse_inline_single_hex(); 
+  # do something if implicit? 
+ } 
    else { 
     if ($top) { 
      $node = $self->inline; 
@@ -541,6 +545,21 @@ sub _parse_inline_single_quoted { 
    return $node; 
} 

+# Parse the inline hex value 
+sub _parse_inline_single_hex { 
+ my $self = shift; 
+ my $node; 
+ if ($self->inline =~ /^0x([A-Fa-f0-9]+)(,?.*)?$/) { 
+  $node = hex($1); 
+  $self->inline($2); 
+  $node =~ s/''/'/g; 
+ } 
+ else { 
+  $self->die('YAML_PARSE_ERR_BAD_HEX'); 
+ } 
+ return $node; 
+} 
+ 
# Parse the inline unquoted string and do implicit typing. 
sub _parse_inline_simple { 
    my $self = shift;