in reply to How to encode/decode a class inside a class in JSON

Below comments are on target, I believe. Basically, you:

  1. enable allow_tags.
  2. implement FREEZE and THAW in your class(es) that are being encoded in the JSON
  3. set type in FREEZE with __PACKAGE__ (or something you know)
  4. in __PACKAGE__ implement THAW method that allows you to "inflate" the decoded reference resulting from the JSON

There are a few blind spots in my mind, but they're mostly due to me not trying this out to see what the resulting JSON looks like when FREEZE is invoked and to see how THAW might handle it. Note, these methods are called implicitly when you allow_tags.

Replies are listed 'Best First'.
Re^2: How to encode/decode a class inside a class in JSON
by tobyink (Canon) on Aug 20, 2020 at 20:51 UTC

    When you enable allow_tags, the resulting serialization is no longer valid JSON though.

      Thanks, that is where I was confused. In that case, you may just be left with adding an internal field _type that tracks the intended __PACKAGE__. Seems like anything that is done will require some custom coordination between what gets dumped via TO_JSON and whatever is used to inflate the instance after an initial decode. As I mentioned earlier, I've solved this in the past with a _type field that tracked the __PACKAGE__ name, but the instances were not nested - which in this case complicates it during the decode step.

      Here's what I suggest:

      • leverage TO_JSON during encode for all member references; for all include a known internal field that signifies what __PACKAGE__ it is meant to inflate (e.g., _type or _package
      • decode JSON (this will give you a reference with no blessed members initially)
      • then use a custom inflator to walk the reference and inflate known members using their section of JSON (you'll either have to assume the package based on key/arraypos or it will carried as an internal field in the JSON)

      The spirit of this can be described as having the JSON moduling knowing when to call a FROM_JSON from the specified package when it sees a special internal field that contains which package to inflate. Since symmetry of this capability is not provided by the JSON module itself, you'll have to implement it yourself as part of the decode step.