Here is the code that is working as I expect:
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
use feature qw(say);
use constant MY_CONSTANT => 42;
use JSON::XS;
say encode_json { value => MY_CONSTANT };
This code output:
{"value":42}
But if the constant is used in string concatenation, then instated of a number in json I get string:
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
use feature qw(say);
use constant MY_CONSTANT => 42;
use JSON::XS;
say encode_json { value => MY_CONSTANT };
my $smth = 'asdf' . MY_CONSTANT;
Here is the output:
{"value":"42"}
For me it was very unexpected that the "constant" changes it behaviour depending of how it it used.
Is there a way to define a constant with number in perl that will be converted to number value in json even it is used in concatenation.
Ideally, Perl considers fourty-two to be fourty two, whether you initialized the variable using "42"
or 42
. JSON::XS breaks that model, which causes results like the ones you saw.
You could use a sub (rather than a constant) to return a fresh scalar every time.
sub MY_CONSTANT() { return 42 }
The return
is important as it prevents the conversion of the sub to a constant.
But a better solution might be to switch to Cpanel::JSON::XS and use Cpanel::JSON::XS::Type to tell the encoder how to serialize the field.