In this answer I found a recommendation for a simple TO_JSON method, which is needed for serializing blessed objects to JSON.
sub TO_JSON { return { %{ shift() } }; }
Could anybody please explain in detail how it works?
I changed it to:
sub TO_JSON {
        my $self = shift;         # the object itself – blessed ref
        print STDERR Dumper $self;
        my %h = %{ $self };       # Somehow unblesses $self. WHY???
        print STDERR Dumper \%h;  # same as $self, only unblessed
        return { %h };    # Returns a hashref that contains a hash.
        #return \%h;      # Why not this? Works too…
}
Many questions… :( Simply, I’m unable to understand 3-liner Perl code. ;(
I need the TO_JSON but it will filter out:
- unwanted attributes and
- unset attributes too (e.g. for those the has_${attr}predicate returns false)
This is my code – it works but I really don't understand why the unblessing works…
use 5.010;
use warnings;
use Data::Dumper;
package Some;
use Moo;
has $_ => ( is => 'rw', predicate => 1,) for (qw(a1 a2 nn xx));
sub TO_JSON {
    my $self = shift;
    my $href;
    $href->{$_} = $self->$_ for( grep {!/xx/} keys %$self );
    # Same mysterious unblessing. The `keys` automagically filters out
    # “unset” attributes without the need of call of the has_${attr}
    # predicate… WHY?
    return $href;
}
package main;
use JSON;
use Data::Dumper;
my @objs = map { Some->new(a1 => "a1-$_", a2 => "a2-$_", xx=>"xx-$_") } (1..2);
my $data = {arr => \@objs};
#say Dumper $data;
say JSON->new->allow_blessed->convert_blessed->utf8->pretty->encode($data);
EDIT: To clarify the questions:
- The %{ $hRef }derefences the$hRef(getting the hash pointed to by the reference), but why get a plain hash from a blessed object reference$self?
- In other words, why the $selfis a hashref?
- I tried to make a hash slice like- @{$self}{ grep {!/xx/} keys %$self}but it didn't work. Therefore I created that horrible- TO_JSON.
- If the $selfis a hashref, why thekeys %$selfreturns only attributes having a value, and not all declared attributes (e.g. thenntoo – see thehas)?
 
                        
In your
TO_JSON()function{ %h }returns a shallow hash copy, while\%hreturns a reference to%h(no copying).