in reply to Outputting JSON with function () {...} values

As the others have said, that's not JSON, and it's unclear what Perl structure you would want to translate to a JS function. Could you show an example of such a Perl data structure, and the equivalent JavaScript that you expect to get?

Anyway, for WebPerl, I also looked into exactly this question and found that at least Cpanel::JSON::XS, and it seems the other JSON modules too, do not provide a good way to hook into the serialization to accomplish this. I ended up writing my own simple serializer. Something like this:

use warnings; use strict; use Cpanel::JSON::XS; our $JSON = Cpanel::JSON::XS->new->allow_nonref; sub to_js { my $what = shift; if (my $r = ref $what) { if ($r eq 'HASH') { return '{' . join(',', map { $JSON->encode("$_").':'.to_js($$what{$_}) } sort keys %$what ) . '}'; } elsif ($r eq 'ARRAY') { return '[' . join(',', map { to_js($_) } @$what) . ']'; } elsif ($r eq 'CODE') { return 'function () { /* some JS here? */ }'; } else { die "can't encode ref $r to JS" } } else { return $JSON->encode($what) } } print to_js( { foo => [ "bar", "quz" ], baz => sub {}, } ), "\n"; __END__ {"baz":function () { /* some JS here? */ },"foo":["bar","quz"]}

Replies are listed 'Best First'.
Re^2: Outputting JSON with function () {...} values
by Aldebaran (Curate) on Oct 25, 2018 at 06:23 UTC

    I've been looking at JSON "things" if only to be able to figure out a taxonomy for them. I get the same output as haukex does from the preceding script, but I would think they this should be decodable as JSON. Instead, I get an error:

    $ $ ./1.js.pl {"baz":function () { /* some JS here? */ },"foo":["bar","quz"]} $ ./1.json.pl 'false' expected, at character offset 7 (before "function () { /* som. +..") at ./1.json.pl line 7, <DATA> line 1. $ cat 1.json.pl #!/usr/bin/perl -w use 5.011; use Data::Dumper; use JSON; my $json = <DATA>; my $perl = decode_json $json; print Dumper $perl; __DATA__ {"baz":function () { /* some JS here? */ },"foo":["bar","quz"]} $
      this should be decodable as JSON

      Note that JSON is only a subset of JavaScript, you can see the grammar e.g. here - it doesn't even allow comments. That's why Perl's most common JSON modules, or browsers, won't handle it. Although the example code can be parsed with JavaScript's eval, of course that's a huge security hole because it allows for arbitrary code execution, which is one of the reasons why JSON was invented in the first place.

      > should be decodable as JSON

      The OP didn't ask for real JSON but a nested JS data structure, which is an upper set.

      This can't be decoded, Perl doesn't have a builtin JS parser (yet).

      The only way I see is to serialize objects like this function as string - hence lethal JSON - and to have a conversion filter on the JS side before using it (here with eval)

      Though I'm not sure about the best way to mark such objects to be distinguished from normal strings.

      See also point 3

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice