From: Ian Jackson Date: Mon, 4 May 2020 00:19:49 +0000 (+0100) Subject: TOML::Tiny: Try to be more faithful for small decimals X-Git-Tag: nailing-cargo/1.0.0~233^2~6 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=0f492f56ab1195f078e6c82dda4b55edccf2f66a;p=nailing-cargo.git TOML::Tiny: Try to be more faithful for small decimals Ideally, if we read a TOML file and write it back out again, we get a semantically equivalent TOML file. Here we improve the situation for smallish deciaml integers. We check for values that round trip from string through a perl integer and back to the same string; if they do, return that integer rather than the string. The main point of this check is to avoid losing information if the value is too large to fit into a Perl integer, which might be only 32-bit. This technique is not perfect: it can't cope with hex, octal or binary, or with larger values that would need bignums. But it is an improvement and probably the best that can be done without unreasonable effort. --- diff --git a/README.pod b/README.pod index 4b0d40c..78a96b9 100644 --- a/README.pod +++ b/README.pod @@ -134,8 +134,9 @@ If you wish to override this, you can provide your own routine to generate value =item inflate_integer TOML integers are 64 bit and may not match the size of the compiled perl's -internal integer type. By default, integers are left as-is as perl strings -which may be upgraded as needed by the caller. +internal integer type. By default, integers other than smallish +decimal integers are left as-is as perl strings which may be upgraded +as needed by the caller. my $parser = TOML::Tiny->new( inflate_integer => sub{ diff --git a/lib/TOML/Tiny.pm b/lib/TOML/Tiny.pm index 4597fe8..e68f548 100644 --- a/lib/TOML/Tiny.pm +++ b/lib/TOML/Tiny.pm @@ -191,8 +191,9 @@ If you wish to override this, you can provide your own routine to generate value =item inflate_integer TOML integers are 64 bit and may not match the size of the compiled perl's -internal integer type. By default, integers are left as-is as perl strings -which may be upgraded as needed by the caller. +internal integer type. By default, integers other than smallish +decimal integers are left as-is as perl strings which may be upgraded +as needed by the caller. my $parser = TOML::Tiny->new( inflate_integer => sub{ diff --git a/lib/TOML/Tiny/Tokenizer.pm b/lib/TOML/Tiny/Tokenizer.pm index e2deb91..b9b3ee4 100644 --- a/lib/TOML/Tiny/Tokenizer.pm +++ b/lib/TOML/Tiny/Tokenizer.pm @@ -178,7 +178,7 @@ sub tokenize_float { sub tokenize_integer { $_[1] =~ tr/_+//d; - $_[1]; + $_[1] !~ m/^0[xob]/ && $_[1] + 0 eq $_[0] ? $_[1] + 0 : "$_[1]" } sub tokenize_string {