The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


JSON::Typist - replace mushy strings and numbers with rigidly typed replacements


version 0.008


  my $content = q<{ "number": 5, "string": "5" }>;

  my $json = JSON->new->convert_blessed->canonical;

  my $payload = $json->decode( $content );
  my $typed   = JSON::Typist->new->apply_types( $payload );

  $typed->{string}->isa('JSON::Typist::String'); #true
  $typed->{number}->isa('JSON::Typist::Number'); # true

  say 0 + $payload->{string}; # prints 5
  say "$payload->{number}";   # prints 5

  say 0 + $typed->{string};   # prints 5
  say "$typed->{number}";     # prints 5

  say $json->encode($payload);
  say $json->encode($typed);


JSON is super useful and everybody loves it. Woo! Go JSON! Good job!

In Perl, though, it's a bit of a pain sometimes. In Perl, strings and numbers mush all together and you're often not sure which you have. Did the 5 in your $x come from {"x":5} or {"x":"5"}? By the time you're checking, you very well may not know.

Often, that's just fine, because it doesn't matter inside your Perl program, where numericality and stringicity are determined by operators, not values. Other times, you need to know. You might using JSON for interchange with a system that needs its types in its values. JSON::Typist is meant for this problem.

JSON (in its many variant forms) always returns numbers and strings in distinguishable forms, but the distinction can be lost as the variables are used. (That's just a weird-o Perl problem.) JSON::Typist is meant to take the result of JSON-decoding immediately before you use it for anything else. It replaces numbers and strings with objects. These objects can be used like numbers and strings, and JSON will convert them to the right type if convert_blessed is enabled.


This library should run on perls released even a long time ago. It should work on any version of perl released in the last five years.

Although it may work on older versions of perl, no guarantee is made that the minimum required version will not be increased. The version may be increased for any reason, and there is no promise that patches will be accepted to lower the minimum required perl.



  my $typist = JSON::Typist->new( \%arg );

This returns a new JSON::Typist. There are no valid arguments to new yet.


  my $typed = $json_typist->apply_types( $data );

This returns a new variables that deeply copies the input $data, replacing numbers and strings with objects. The logic used to test for number-or-string is subject to change, but is meant to track the logic used by and related JSON libraries. The behavior on weird-o scalars like globs is undefined.

Note that property names, which becomes hash keys, do not become objects. Hash keys are always strings.

Strings become JSON::Typist::String objects. Numbers becomes JSON::Typist::Number objects.


  my $untyped = $json_typist->strip_types;

This method deeply copies its input, replacing number and string objects with simple scalars that should become the proper JSON type. Using this method should not be needed if your JSON decoder has convert_blessed enabled.

Right now, boolean objects are left in place, because they will be there from JSON's behavior, not JSON::Typist. This may change in the future.



  my $jnum = $typist->number(123);
  my $jstr = $typist->string(123);

These methods returns the same sorts of objects that would be returned in a typed JSON structure from apply_types.


Ricardo Signes <>


  • Matthew Horsfall <>

  • Ricardo Signes <>


This software is copyright (c) 2016 by Ricardo Signes.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.