[quickjs-devel] Re: JS_CFUNC_DEF doesn't make properties enumerable

  • From: Saúl Ibarra Corretgé <s@xxxxxxxxxx>
  • To: quickjs-devel@xxxxxxxxxxxxx
  • Date: Tue, 6 Aug 2019 22:49:49 +0200

On 06/08/2019 22:21, Charlie Gordon wrote:

On 6 Aug 2019, at 21:38, Saúl Ibarra Corretgé <s@xxxxxxxxxx> wrote:
On 06/08/2019 10:05, Charlie Gordon wrote:
On 6 Aug 2019, at 09:28, Saúl Ibarra Corretgé <s@xxxxxxxxxx> wrote:
On 04/08/2019 20:13, Charlie Gordon wrote:
Hence there was no need for a more general macro to define these methods 
in the static JSCFunctionListEntry tables.

But doesn't it make sense to have them when defining prototype functions
lists? Those should be enumerable, shouldn't they? At least so tab-tab
works on the REPL :-) Am I missing something?

In fact it does not, because it would make the class methods appear when 
enumerating object properties in `for (x in obj)`. Imagine if you had to 
distinguish between elements and methods when enumerating an Array?

Completion in the REPL does not rely on the “enumerable” property 
attribute, but uses Object.getOwnPropertyNames and Object.getPrototypeOf to 
enumerate object properties along the prototype chain, including methods. 
See function get_completion() in repl.js for details. Given the choice made 
in the ECMA Standard, we had to do it this way and it is actually quite 
simple.

You can write your own macros to define your own C based object 
properties, but the implementation of these macros and the 
JSCFunctionListEntry structure might change in the future so might need 
to change your macros to work with newer versions of quickjs.

Yeah, I've done that, but indeed it looks "fragile". An "official" way
to do it would be most welcome.

Object.getOwnPropertyNames and Object.getPrototypeOf are not “fragile”, 
they are one of the official ways to perform introspection. Enumerating 
properties with `for (x in obj)` is considered obsolete, and `for (x of 
obj)` does not follow the prototype chain, which is a relief considering 
the complexity of the specification of `for (x in obj)`.

There seems to be little use for enumerable object methods. You can 
always enumerate an object properties and its prototypes’ with Object 
methods.

Is the prototype methods for an object not a valid use case?

That’s arguable, but an explicit approach seems preferable over some form 
of enumeration that mixes properties of different prototype objects in a 
single list.

The ECMAScript specification is complex and convoluted enough already.  
Consistency and simplicity should be sought whenever possible.


You're right! Thanks for taking the time to explain. I think what threw
me off is (maybe?) some REPL bug: I have a custom object for which I
expose a constructor but completion doesn't seem to work on it. It
doesn't matter what flags I set in the props. Same seems to go if you do:

const e = new std.Error();
e.<tab tab>

Nothing comes up.

This is indeed a REPL bug!

Objects defined with const and let are mishandled by the completion mechanism 
in REPL because they are not properties of the global object.
If you use `var` or simply type `e = new std.Error();`, e.<tab><tab> will 
show the prototype methods.

Attached is a patch to fix this problem.

Thanks for the feedback

Chqrlie.


Oh wow, that was fast! And it worked too! Thanks a lot.


Cheers,

-- 
Saúl

Other related posts: