NAME
Module::Generic::JSON - A thin and reliable wrapper around JSON
SYNOPSIS
use Module::Generic::JSON;
my $j = Module::Generic::JSON->new(
utf8 => 1,
pretty => 1,
canonical => 1,
relaxed => 1,
allow_nonref => 1,
) || die( Module::Generic::JSON->error );
$j->encode( $some_ref ) || die( $j->error );
Or
my $j = Module::Generic::JSON->new;
$j->utf8->pretty->canonical->relaxed->allow_nonref->encode( $some_ref ) ||
die( $j->error );
Or, even simpler:
use Module::Generic::JSON qw( new_json );
my $j = new_json(
utf8 => 1,
pretty => 1,
canonical => 1,
relaxed => 1,
allow_nonref => 1,
) || die( Module::Generic::JSON->error );
$j->encode( $some_ref ) || die( $j->error );
VERSION
v0.2.2
DESCRIPTION
This is a thin and reliable wrapper around the otherwise excellent JSON class. Its added value is:
Allow the setting of all the JSON properties upon object instantiation
As mentioned in the synopsis, you can do:
my $j = Module::Generic::JSON->new( utf8 => 1, pretty => 1, canonical => 1, relaxed => 1, allow_nonref => 1, ) || die( Module::Generic::JSON->error );
instead of:
my $j = Module::Generic::JSON->new; $j = $j->utf8->pretty->canonical->relaxed->allow_nonref;
No fatal exception that would kill your process inadvertently.
This is important in a web application where you do not want some module killing your process, but rather you want the exception to be handled gracefully.
Thus, instead of having to do:
local $@; my $ref = eval{ $j->decode( $payload ) }; if( $@ ) { # Like returning a 500 or maybe 400 HTTP error bailout_gracefully( $@ ); }
you can simply do:
my $ref = $j->decode( $payload ) || bailout_gracefully( $j->error );
Upon error, it returns an exception object
All methods calls are passed through to JSON, and any exception is caught, and handled properly for you.
For class functions too, you can execute them safely and catch error, if any, by calling Module::Generic::JSON->error
, so for example:
decode_json( $some_data ) || die( Module::Generic::JSON->error );
CONSTRUCTOR
new
This takes an hash or hash reference of options and returns a new Module::Generic::JSON object. The options must be supported by JSON. On error, sets an error object and returns undef
in scalar context or an empty list in list context:
my $j = Module::Generic::JSON->new( utf8 => 1, pretty => 1 ) ||
die( Module::Generic::JSON->error );
METHODS
See the documentation for the module JSON for more information, but below are the known methods supported by JSON
allow_blessed
allow_nonref
allow_tags
allow_unknown
ascii
backend
boolean
boolean_values
canonical
convert_blessed
decode
Decodes a JSON string and returns the resulting Perl data structure. On error, sets an error object and returns undef
in scalar context or an empty list in list context:
my $data = $j->decode( '{"a":1}' ) || die( $j->error );
decode_prefix
encode
Encodes a Perl data structure into a JSON string. On error, sets an error object and returns undef
in scalar context or an empty list in list context:
my $json_str = $j->encode( { a => 1 } ) || die( $j->error );
filter_json_object
filter_json_single_key_object
indent
is_pp
is_xs
latin1
max_depth
max_size
pretty
property
relaxed
space_after
space_before
utf8
CLASS FUNCTIONS
decode_json
Decodes a JSON
string and returns the resulting Perl data structure. On error, sets an error object and returns undef
in scalar context or an empty list in list context:
my $data = decode_json( '{"a":1}' ) || die( Module::Generic::JSON->error );
encode_json
Encodes a Perl data structure into a JSON
string. On error, sets an error object and returns undef
in scalar context or an empty list in list context:
my $json_str = encode_json( { a => 1 } ) || die( Module::Generic::JSON->error );
from_json
Decodes a JSON
string with optional configuration options. Takes a JSON
string and an optional hash reference of options (passed to "new"). On error, sets an error object and returns undef
in scalar context or an empty list in list context:
my $data = from_json( '{"a":1}', { utf8 => 1 } ) || die( Module::Generic::JSON->error );
to_json
Encodes a Perl data structure with optional configuration options. Takes a Perl data structure and an optional hash reference of options (passed to "new"). On error, sets an error object and returns undef
in scalar context or an empty list in list context:
my $json_str = to_json( { a => 1 }, { pretty => 1 } ) || die( Module::Generic::JSON->error );
SERIALISATION
Module::Generic::JSON inherits serialisation methods from Module::Generic. The following subroutines are implemented: FREEZE
, THAW
, STORABLE_freeze
, and STORABLE_thaw
. See Module::Generic for details.
THREAD-SAFETY
Module::Generic::JSON is thread-safe for all operations, as it operates on per-object state and avoids the thread-safety issues present in the underlying JSON module.
Key considerations for thread-safety:
Shared Variables
There are no shared variables that are modified at runtime in Module::Generic::JSON. The global
$DEBUG
variable (inherited from Module::Generic) is typically set before threads are created, and it is the user's responsibility to ensure thread-safety if modified at runtime:use threads; local $Module::Generic::JSON::DEBUG = 0; # Set before threads my @threads = map { threads->create(sub { my $json = Module::Generic::JSON->new( utf8 => 1 ); $json->encode( { a => 1 } ); # Thread-safe }); } 1..5; $_->join for( @threads );
Note that the JSON module uses a global
$JSON
variable for functions likeencode_json
anddecode_json
, which can lead to thread-safety issues if modified at runtime. Module::Generic::JSON avoids this by creating a new object instance for each call to "decode_json" and "encode_json", ensuring thread isolation.Object State
The underlying JSON object is stored per-object, ensuring thread isolation:
use threads; my @threads = map { threads->create(sub { my $json = Module::Generic::JSON->new( utf8 => 1 ); $json->encode( { tid => threads->tid } ); # Thread-safe }); } 1..5; $_->join for( @threads );
Class Functions
Class functions like "decode_json" and "encode_json" create a new object per call, ensuring thread isolation:
use threads; my @threads = map { threads->create(sub { my $data = decode_json( '{"a":1}' ); # Thread-safe }); } 1..5; $_->join for( @threads );
External Libraries
The underlying JSON module (both JSON::XS and JSON::PP) is thread-safe for object methods, as it operates on per-object state. However, its class functions (e.g.,
encode_json
,decode_json
) are not thread-safe due to the use of a global$JSON
variable. Module::Generic::JSON mitigates this by always creating a new instance for such calls.Serialisation
Serialisation methods ("FREEZE", "THAW") operate on per-object state, making them thread-safe.
For debugging in threaded environments (depending on your Operating System):
ls -l /proc/$$/fd # List open file descriptors
AUTHOR
Jacques Deguest <jack@deguest.jp>
SEE ALSO
JSON, Module::Generic::Exception
COPYRIGHT & LICENSE
Copyright(c) 2025 DEGUEST Pte. Ltd.
All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.