The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

MooX::Tag::TO_JSON - Controlled translation of Moo objects into JSON appropriate Hashes

VERSION

version 0.05

SYNOPSIS

 package My::Farm;
 
 use Moo;
 with 'MooX::Tag::TO_JSON';
 
 has cow              => ( is => 'ro', to_json => 1 );
 has duck             => ( is => 'ro', to_json => 'goose,if_exists', );
 has horse            => ( is => 'ro', to_json => ',if_defined', );
 has hen              => ( is => 'ro', to_json => 1, );
 has barn_door_closed => ( is => 'ro', to_json => ',bool' );
 has secret_admirer   => ( is => 'ro', );
 
 # and somewhere else...
 
 use Data::Dumper;
 my $farm = My::Farm->new(
     cow              => 'Daisy',
     duck             => 'Frank',
     barn_door_closed => 0,
     secret_admirer   => 'Fluffy',
 );
 
 print Dumper $farm->TO_JSON;

# resulting in

 $VAR1 = {
           'hen' => undef,
           'cow' => 'Daisy',
           'goose' => 'Frank',
           'barn_door_closed' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' )
         };

DESCRIPTION

MooX::Tag::TO_JSON is a Moo::Role which provides a controlled method of converting your Moo based object into a hash appropriate for passing to a JSON encoder. It provides a TO_JSON method which is recognized by most (?) JSON encoders and used to serialize the object.

Simply mark each field that should be output with the special option to_json when declaring it:

    has field => ( is => 'ro', to_json => 1 );

and call the "TO_JSON" method on your instantiated object.

   my %hash = $obj->TO_JSON;

Fields inherited from superclasses or consumed from roles which use MooX::Tag::TO_JSON are automatically handled.

If a field's value is another object, "TO_JSON" will automatically turn that into a hash if it has its own TO_JSON method (you can also prevent that).

Modifying the generated JSON

[Originally, this module recommended using a method modifier to the TO_JSON method, this is no longer recommended. See discussion under "DEPRECATED BEHAVIOR" below.].

If the class provides a _modify_jsonr method (or, for backwards capability, modify_jsonr), it will be called as

    $self->_modify_jsonr( \%json );

and should modify the passed hash in place.

For compatibility with MooX::TO_JSON, if the class provides a modify_json method it will be called as

    %json = $self->modify_json( %json );

Usage

Add the to_json option to each field which should be included in the json. to_json can either take a value of 1, e.g.

    has field => ( is => 'ro', to_json => 1 );

or a string which looks like one of these:

   alternate_name
   alternate_name,option_flag,option_flag,...
   ,option_flag,option_flag,...

If alternate_name is specified, that'll be the key used in the output json.

option_flag may be one of the following:

bool

Force the value into a JSON Boolean context. Compatible with MooX::TO_JSON.

int

Force the value into a JSON numeric context. Compatible with MooX::TO_JSON.

str

Force the value into a JSON numeric context. Compatible with MooX::TO_JSON.

if_exists

Only output the field if it was set. This uses "Moo"'s attribute predicate (one will be added to the field if it not already specified).

It will be output if the field is set to undef.

A synonym for this is omit_if_empty, for compatibility with MooX::TO_JSON.

if_defined

Only output the field if it was set and its value is defined.

METHODS

TO_JSON

  %hash = $obj->TO_JSON

This method is added to the consuming class or role.

EXAMPLES

Modifying the generated json

 package My::Test::C4;
 
 use Moo;
 with 'MooX::Tag::TO_JSON';
 
 has cow              => ( is => 'ro', to_json => 1 );
 has duck             => ( is => 'ro', to_json => 'goose,if_exists', );
 has horse            => ( is => 'ro', to_json => ',if_defined', );
 has hen              => ( is => 'ro', to_json => 1, );
 has barn_door_closed => ( is => 'ro', to_json => ',bool' );
 has secret_admirer   => ( is => 'ro', );
 
 # upper case the json keys
 sub modify_jsonr {
     my ( $self, $jsonr ) = @_;
     $jsonr->{ uc $_ } = delete $jsonr->{$_} for keys %$jsonr;
 };
 
 # and elsewhere:
 use Data::Dumper;
 
 print Dumper(
     My::Test::C4->new(
         cow              => 'Daisy',
         hen              => 'Ruby',
         duck             => 'Donald',
         horse            => 'Ed',
         barn_door_closed => 1,
         secret_admirer   => 'Nemo'
     )->TO_JSON
 );

# resulting in

 $VAR1 = {
           'HEN' => 'Ruby',
           'COW' => 'Daisy',
           'BARN_DOOR_CLOSED' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
           'GOOSE' => 'Donald',
           'HORSE' => 'Ed'
         };

DEPRECATED BEHAVIOR

Using method modifiers to modify the results

Previously it was suggested that the before method modifier be used to modify the resultant hash. However, if both a child and parent class consume the MooX::Tag::TO_JSON role and the parent has modified TO_JSON, the parent's modified TO_HASH will not be run; instead the original TO_HASH will. For example,

 package Role {
     use Moo::Role;
     sub foo { print "Role\n" }
 }
 
 package Parent {
     use Moo;
     with 'Role';
     before 'foo' => sub { print "Parent\n" };
 }
 
 package Child {
     use Moo;
     extends 'Parent';
     with 'Role';
     before 'foo' => sub { print "Child\n" };
 }
 
 Child->new->foo;

results in

 Child
 Role

Note it does not output Parent.

SUPPORT

Bugs

Please report any bugs or feature requests to bug-moox-tag-to_hash@rt.cpan.org or through the web interface at: https://rt.cpan.org/Public/Dist/Display.html?Name=MooX-Tag-TO_HASH

Source

Source is available at

  https://gitlab.com/djerius/moox-tag-to_hash

and may be cloned from

  https://gitlab.com/djerius/moox-tag-to_hash.git

SEE ALSO

Please see those modules/websites for more information related to this module.

AUTHOR

Diab Jerius <djerius@cpan.org>

COPYRIGHT AND LICENSE

This software is Copyright (c) 2022 by Smithsonian Astrophysical Observatory.

This is free software, licensed under:

  The GNU General Public License, Version 3, June 2007