in reply to Framework for making Moose-compatible object from json
G'day nataraj,
Would something like this suit your purposes:
package Local::MooseJson; use strict; use warnings; use Moose; use JSON; use namespace::autoclean; around BUILDARGS => sub { my ($orig, $class, @args) = @_; # Validate @args: 1 element only; JSON text my $json_to_perl = decode_json $args[0]; my $new_hashref = {}; for my $key ($class->meta->get_attribute_list()) { $new_hashref->{$key} = delete $json_to_perl->{$key}; } for my $extra_key (keys %$json_to_perl) { warn "IGNORED! Unknown JSON property: '$extra_key'\n"; } return $class->$orig($new_hashref); }; has body_raw => (is => 'ro', isa => 'Str', required => 1); has entry_id => (is => 'ro', isa => 'Int', required => 1); has icon => (is => 'ro', isa => 'HashRef', required => 1); __PACKAGE__->meta->make_immutable; 1;
Here's a test script:
#!/usr/bin/env perl use strict; use warnings; use FindBin qw($RealBin); use lib "$RealBin/../lib"; use Local::MooseJson; chomp(my $rest_json = <<'EOJ'); { "body_raw" : "This is <b>Entry 1</b>", "url" : "http://nataraj.nataraj.hack.dreamwidth.net/459.html", "datetime" : "2022-08-20 16:36:00", "Surprise!" : "You didn't expect this.", "entry_id" : 459, "subject_html" : "Entry 1", "poster" : { "display_name" : "nataraj", "username" : "nataraj" }, "icon" : { "url" : "http://www.nataraj.hack.dreamwidth.net/userpic/1/3", "comment" : "4", "picid" : 1, "keywords" : [ "3" ], "username" : "nataraj" }, "subject_raw" : "Entry 1", "body_html" : "This is <b>Entry 1</b>" } EOJ my $mj = Local::MooseJson::->new($rest_json); print 'Username: ', $mj->icon()->{username}, "\n";
Output:
ken@titan ~/tmp/pm_11146255_moose_json/bin $ ./moose_json.pl IGNORED! Unknown JSON property: 'subject_html' IGNORED! Unknown JSON property: 'url' IGNORED! Unknown JSON property: 'poster' IGNORED! Unknown JSON property: 'subject_raw' IGNORED! Unknown JSON property: 'Surprise!' IGNORED! Unknown JSON property: 'body_html' IGNORED! Unknown JSON property: 'datetime' Username: nataraj
When you add in the missing attributes, all but one of the "IGNORED" lines will disappear (i.e. you'll still get a Surprise!). You can then decide if you're getting bad data back from the API or if you need to update the module. This acts as a sanity check for both your module and the incoming data.
In case you were wondering how all of that fits together, here's the directory structure.
ken@titan ~/tmp $ ls -lR pm_11146255_moose_json pm_11146255_moose_json: total 0 drwxr-xr-x 1 ken None 0 Aug 21 07:43 bin drwxr-xr-x 1 ken None 0 Aug 21 07:04 lib pm_11146255_moose_json/bin: total 4 -rwxr-xr-x 1 ken None 846 Aug 21 07:43 moose_json.pl pm_11146255_moose_json/lib: total 0 drwxr-xr-x 1 ken None 0 Aug 21 07:40 Local pm_11146255_moose_json/lib/Local: total 4 -rw-r--r-- 1 ken None 788 Aug 21 07:40 MooseJson.pm
— Ken
In Section
Seekers of Perl Wisdom