Printing out structures that contain functions

17 views
Skip to first unread message

Aaron Gray

unread,
Jan 28, 2019, 8:05:27 PM1/28/19
to nod...@googlegroups.com
Hi,

I need to print out objects with embedded functions ideally both to the command line and as files.

    const test = {
        name: "test",
        get: function() { return "test"; }
    };

I need to print out a structure like the above with the function definition to the console and also as a text file.

Regards,
Aaron


--
Aaron Gray

Independent Open Source Software Engineer, Computer Language Researcher, Information Theorist, and amateur computer scientist.

Forrest Norvell

unread,
Jan 28, 2019, 8:19:48 PM1/28/19
to nod...@googlegroups.com

You’re going to need to write a custom serializer similar to util.inspect to get this. Be forewarned, though, there’s a reason functions aren’t displayed as their source by default: calling .toString() on a function doesn’t include the closure environment for the function, so any lexically defined values that are in scope when the function was defined won’t be available later:

function mildCurry (a) {
  return (b) => a + b;
}

const oneOff = { add2: mildCurry(2) }
// > oneOff.add2.toString()
// '(b) => a + b'

If you’re careful about how you define functions on objects (and also figure out whether you want to include prototype methods as part of this serialization) you can probably stay out of trouble, but this isn’t as generally useful as you might hope.


--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/CANkmNDecj0Mac9mXyh0-hpDdubMxZvT2Rdmp-4DK-KiOAZ-E-w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Aaron Gray

unread,
Jan 28, 2019, 8:32:56 PM1/28/19
to nod...@googlegroups.com
On Mon, 28 Jan 2019 at 20:19, Forrest Norvell <othi...@gmail.com> wrote:

You’re going to need to write a custom serializer similar to util.inspect to get this. Be forewarned, though, there’s a reason functions aren’t displayed as their source by default: calling .toString() on a function doesn’t include the closure environment for the function, so any lexically defined values that are in scope when the function was defined won’t be available later:

function mildCurry (a) {
  return (b) => a + b;
}

const oneOff = { add2: mildCurry(2) }
// > oneOff.add2.toString()
// '(b) => a + b'

If you’re careful about how you define functions on objects (and also figure out whether you want to include prototype methods as part of this serialization) you can probably stay out of trouble, but this isn’t as generally useful as you might hope.

Hopefully I am not worried about closures though I will have to check my usecase's code out as its a third party library.

I have found Function.toString() works for functions so will just write a serialized as you suggest.

Many thanks,

Aaron

 

For more options, visit https://groups.google.com/d/optout.

Aaron Gray

unread,
Jan 28, 2019, 10:56:44 PM1/28/19
to nod...@googlegroups.com
Oh this closure issue is really annoying !

Is there any way it can be fixed ?

Shall I raise an issue ?

Aaron







Forrest Norvell

unread,
Jan 29, 2019, 12:27:29 AM1/29/19
to nod...@googlegroups.com
I'm not sure that raising an issue can help you (and who would it be with? Node's maintainers? the V8 team? TC39?), because you're running up against a property of all languages with closures and lexical environments. This isn't a JavaScript-specific problem; all dynamic languages that support first-class functions and lexical scope (Ruby, Python, Scheme, and Perl, among others) have no reliable way to serialize functions independent of their defining context.

If you think about it a bit, how would an attempt to serialize the function be able to annotate the written-out version with all of the context necessary to allow it to be reconstituted into the same function? Some of those references are to dynamic bindings (as in the case where you've got a name that refers to a function defined in an outer scope, but not globally), and some may be shadowing global variables (as in the case where you have a variable named `global` in the enclosing scope shadowing the predefined Node `global` object).

As I said in my previous message, with care, you can avoid these problems. If you control all the code that will be attached to these serialized objects, or are dealing with methods, where all dynamic references are through `this`, then you can get most of what you need (keeping in mind that methods are generally attached to prototypes, rather than being own properties of objects). In general, though, this isn't something that can be worked around.

F

Reply all
Reply to author
Forward
0 new messages