json icon indicating copy to clipboard operation
json copied to clipboard

Use structure in TO_JSON method when available

Open dannymk opened this issue 7 years ago • 8 comments

Perhaphs add a sub that takes an instance that can actually return a structure that only includes items that we want in the output:

multi sub to-json ( $_ where *.can('TO_JSON') ) {
    to-json .TO_JSON
}

see: https://stackoverflow.com/questions/53110521/perl6-class-to-json-exclude-properties/53120677#53120677

dannymk avatar Nov 02 '18 15:11 dannymk

Is there any consensus among the various Perl 6 JSON modules as to calling such a method, and if yes, how to call it?

Personally, I'd prefer AS-JSON, as TO implies a mutation of the invocant.

moritz avatar Nov 03 '18 14:11 moritz

In some of the Perl5 modules the documentation reads: "If $enable is true (or missing), then encode, upon encountering a blessed object, will check for the availability of the TO_JSON method on the object's class. If found, it will be called in scalar context and the resulting scalar will be encoded instead of the object."

dannymk avatar Nov 03 '18 18:11 dannymk

@moritz are you planning on incorporating the above patch into the module?

dannymk avatar Dec 07 '18 15:12 dannymk

@dannymk not before there is any consensus with, or at least data from, other Perl 6 JSON modules

moritz avatar Dec 11 '18 15:12 moritz

Where are we supposed to get this consensus from?

dannymk avatar Dec 21 '18 20:12 dannymk

From the authors of the other JSON-related p6 modules

moritz avatar Dec 21 '18 21:12 moritz

Not speaking as an author of a JSON module here, but certainly of some other Perl 6 modules. Rather than hard-coding a method name, I'd suggest something like .to-json( $obj, :filter('method-name') ) or using a dynamic variable... $*JSON-FILTER-NAME='method-name'; $foo.to-json( $obj ); Both of those methods leave the choice of the filtering method to the user, and the dynamic variable means that you don't even need a 'multi method' variant.

drforr avatar Mar 20 '19 00:03 drforr

Another suggestion that feels even more Perl6ish to me would be something like this:

class MyObject {
  has $.attribute;
  method JSON returns JSONStr { # your package could create this JSONStr subtype, optional
    as-json( self, { #`{ Your filter code here } } );
  }
}
# code passes...
my $obj = MyObject.new( :attribute("hello") );
status_ok( $obj.JSON ); # Return JSONified output, just like you'd say $obj.Str to stringify it.

drforr avatar Mar 20 '19 01:03 drforr