[streams] Allow object with methods to be passed as (writeable) sink (#256)

Sorry if something similar was already discussed, I searched in the issues and couldn't find anything.

One pattern node uses[1] is to attach internal fields (e.g. pointers to native structures) to objects. When methods are called on instances later on, their native implementations can access these internal fields. The problem is now that these constructs only work if the methods are actually called on the instances, e.g.:

```js
var TTYSink = getNativeBinding('TTY'); // returns a class created via a FunctionTemplate
var sink = new TTYSink(1); // tty stream for stdout
sink.write("Hello World").then(() => { /* written */ }); // will directly call the native implementation of `write`
```

It would be great if it would be possible to pass such an object into the `Writeable` constructor. But unfortunately right now this will fail because `Writeable` will try to call `write` as a function instead of as a method, which forces ugly hacks like binding all methods explicitly:

```js
var stdout = new Writeable({
  /* ... */
  close: sink.close.bind(sink),
  write: sink.write.bind(sink)
});
```

By preserving the this-context, the following would "just work":

```js
var stdout = new Writeable(new TTYSink(1));
```

I'm not sure if this is a V8-specific concern or if there's a better way of solving this when implementing the sink (e.g. if V8 already has an option to attach user data to all methods of an object). Still wanted to bring it up for discussion. :)

[1] According to v8-dev, this is a common pattern: https://groups.google.com/d/msg/v8-users/Axf4hF_RfZo/hA6Mvo78AqAJ

---
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/issues/256

Received on Friday, 19 December 2014 19:50:17 UTC