I have been driving myself crazy trying to find a module that I can use with nested objects specifically classes. There are a few modules that are pretty close however I do not want to set the properties to null to skip the values I do not want.
It would be great if I could write a TO_JSON method or so to that returns a structure that will be marshaled by a module. Or, just use "json-skip" on attributes we don't want included in the final JSON document.
Something like:
class Something {
has Str $.foo;
has Str $.bar is json-skip;
}
or
class Something {
has Str $.foo;
has Str $.bar;
method TO_JSON {
return {
foo => $.foo
}
}
}
JSON::Tiny, JSON::Fast, JSON::Marshal, etc... all work great with individual structures and some even with nested instances however excluding properties is eluding me at the moment.
At the end I would like to do something like:
my $json-document = to-json(@nestedInstances);
The sub to-json
from JSON::Tiny
is multi. So you can redefine the behavior for you class.
multi sub to-json ( Something $_ ) {
to-json 'foo' => .foo
}
Thus following example probably works as you want.
use JSON::Tiny;
class Something {
has Str $.foo;
has Str $.bar;
method TO_JSON {
return {
foo => $.foo
}
}
}
multi sub to-json ( $_ where *.can('TO_JSON') ) {
to-json .TO_JSON
}
my Something $sth .= new: :foo<interest>, :bar<no_interest>;
say to-json [$sth,2, :$sth];
Output:
[ { "foo" : "interest" }, 2, { "sth" : { "foo" : "interest" } } ]
The above answer is the accepted answer and I have made it an issue in the JSON::Tiny github repo. The code below is just to clarify what is happening for those of us that are new to perl6:
use JSON::Tiny;
# The JSON::Tiny module has a bunch of multi to-json subs.
# Here we are creating/adding one that takes an instance that can do "TO_JSON", i.e. has a TO_JSON method
multi to-json ( $_ where *.can('TO_JSON') ) {
# Execute the method TO_JSON on the passed instance and use one of
# the other to-json subs in the JSON::Tiny module that supports the
# returned structure
to-json $_.TO_JSON
}
class Something {
has Str $.foo;
has Str $.bar;
method TO_JSON {
return {
foo => $.foo
}
}
}
my Something $sth = Something.new( foo => 'Interested', bar => 'Not interested' );
# The lexically scoped to-json sub above is used because it takes an argument that implements the TO_JSON method
say to-json $sth;
output:
{ "foo" : "Interested" }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With