Proxies: get+fn vs. invoke

Tom Van Cutsem tomvc.be at gmail.com
Mon Oct 11 07:18:23 PDT 2010


This is odd, I didn't see the original message you were replying to.

To respond to the question you posed in the "syntax for efficient
traits"-thread:

Yes, I do. The latest is "magic methods" directly on objects (possibly you
> saw -- http://gist.github.com/617338; I don't know what again with
> es-archive server, but it doesn't display the lettter which I send about
> "get+fn vs. invoke" --
> https://mail.mozilla.org/pipermail/es-discuss/2010-October/thread.html --
> there only answer on the letter with correcting the typo).


Hmm, your API defines all the handler methods directly on the object, thus
explicitly ignoring the stratification afforded by the original API.
Granted, your implementation filters out magic properties in appropriate
places, so they won't show up in e.g. for-in loops, but the magic methods
are still easily accessible directly from the object. I understand that
people just want to write:

myObject.__get__ = function() { ... }

instead of:

var handler = Proxy.noopHandler(myOriginalObject);
handler.get = function() { ... }
myObject = Proxy.create(handler, Object.getPrototypeOf(myOriginalObject));

I agree that the current API is too bulky if all you want is
__noSuchMethod__, but I'd much rather see a wrapper library that allows me
to write something like this:

var [myObject, handler] = wrap(myOriginalObject);
handler.get = function() { ... }

or just:

var myObject = wrap(myOriginalObject, { get: function() { ... } })

This still keeps all the meta-functionality of an object in a separate
object. Code that only has access to "myObject" can't mess around with its
meta-level behavior. 'magic' methods don't prevent a client from
inadvertently overriding an object's traps.


Maybe you can answer on this question regarding proxies? How can we handler
> in one get of a proxy handler both cases of a call-site:


foo.bar


> and


> foo.bar()


> ?


Having invoke, we handler foo.bar(). However, the case when the get returns
> should look (unfortunatelly?) like (foo.bar)(). Also of course foo.bar does
> not extracted as a functional object (including invariants
> foo.bar.call/apply). But I think, is it the case that user wants to used
> them exactly as funargs or he wants more to handle just access
> (exactly calling of) to non-existing methods? P.S.: to avoid off-topic
> regarding this topic devoted to traits/mixins, it's better to answer to that
> trhead -- "get+fn vs. invoke".


In short: the 'get' trap can't distinguish the above two cases. This is a
pity, and I agree it would be useful for 'get' to have that information
sometimes. There has previously been talk on this list of parameterizing
'get' with an additional flag to detect get+call vs invoke, but it turned
out that not all implementations would be able to support it: <
https://mail.mozilla.org/pipermail/es-discuss/2010-May/011062.html>

In retrospect it may not be so bad that this feature isn't supported. I can
imagine it could lead people to write code like:

get: function(receiver, name, args) {
  // suppose that args === undefined implies that the property was only
queried, not invoked
  if (args === undefined || args.length === 0) {
    return 'a';
  } else {
    ...
  }
}

So that obj.name and obj.name() would both return 'a'. This could lead to a
lot of confusion, since it's hard to quantify what "obj.name" denotes. If
it's supposed to be a method, then obj.name should return a function. If
it's supposed to be a getter, then obj.name() should call the thing returned
by the getter (which, in this case, should raise a type error since strings
are not callable)

Cheers,
Tom

2010/10/9 Dmitry A. Soshnikov <dmitry.soshnikov at gmail.com>

>  On 10.10.2010 0:44, Dmitry A. Soshnikov wrote:
>
>
>
> Yes, there are some cons: a non-existing method can be extracted as a
> funarg for later use. It also do not break invariant with call/apply methods
> applied for the method:
>
>
> Sorry, typo, not cons, but pros of course.
>
> Dmitry.
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20101011/17701496/attachment-0001.html>


More information about the es-discuss mailing list