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
$self
is a hashref? I tried to make a hash slice like@{$self}{ grep {!/xx/} keys %$self}
but it didn't work. Therefore I created that horribleTO_JSON
.- If the
$self
is a hashref, why thekeys %$self
returns only attributes having a value, and not all declared attributes (e.g. thenn
too – see thehas
)?
my %h = map { $_ => $self->{$_} } grep { !/xx/ } keys %$self
ormy %h = %$self; delete @h{ grep /xx/, keys %$self }
– Anachronousreturn { %{$self}{ grep { !/xx/ } keys %$self } };
- and it finally works :) (key/value hash slice). The problem was in the 1st sigil@
. in that form it returns really a values. :) Good to have you. ;) :) – Armoury