-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add use of prototype._clone() if found to clone an object. + test #93
Conversation
…only in the prototype. This allows a user to customise a Specific object to behave differently to the prototype method.
I dislike the idea of having cloned objects define a prototype function. It seems to me that this should be part of it's own library, that you could use if clone doesn't work with an object. |
the problem is that the clone library is used by another project (Node-Red), which uses it to clone generic messages; so we would prefer not to change the library for another. We want to send objects down these messages, and have no control over the cloning process (i.e. we can;t choose to clone in a different way). We have spent days over a period of months looking at mechanisms to make clone work for us, but all attempts have failed. |
clone is used by almost 2000 other projects. I can't make sure that this change won't be breaking other people's code. Native objects always have been problematic. Why don't you just wrap your call to clone and invoke the |
Hi Paul, the root object being cloned is a message structure, which users would expect to be able to place a native object at any level in the structure, and the project (Node-Red) is also risk-averse. The mod is low risk, except for the name of the function (_clone()), so could we compromise on a more complex name; less risk of conflict? eg ___cloneObject() (3 underscores)? thoughts? s |
Hi Paul, I am contributing together with Simon on Node-Red, so thank you very much for having this discussion with us!!!! Some contextIn Node-Red messages are send between blocks, that are wired together: In the first block we create an OpenCv image (i.e. Javascript wrapper around native memory), which is send to the next blocks in the payload field of a message object. The original message object is send to the first wire (1), but a clone of the message is send to the next wire (2). To clone the message, Node-Red calls your module and we have NO way to work around it ;-( RequirementThe only way to create a valid clone of the Javascript wrapper, is by using the API of the OpenCv wrapper: So we try to find some way to customize the cloning process, by calling this code snippet ... Failed experimentsWe are aware that your project is very popular, so we tried to find a way to call that code snippet (without pull-request) but all our experiments have failed:
But perhaps you have better ideas to allow us to customize the cloning. I.e. some way that doesn't break other projects, and could be helpfull for other users also. Thanks in advance, |
Thank you, Simon and Bart, for providing some context. Can you detect whether you are cloning such a wrapper object around an OpenCV image/object or is it deeply nested in an object structure that you clone all at once? Can you give me a link to the code we're talking about? Probably I can think of a solution when I have a specific example. |
Dear Paul, I have prepared a Simple repo (based on an example from the guy who make opencv4nodejs) here: https://github.com/btsimonh/node-addon-tutorial Pull it down, This reproduces our issue in the simplest form. The native Vector object seems to clone, but as soon as you try to use 'add', you either get 'TypeError: Illegal invocation' (if you try to run the add function from the clone), or 'Vector::Add - expected argument to be instance of Vector' (if you try to pass a clone into .add on a real Vector). Additional info on the Actual objects we are trying to clone: Note that Node-Red already has one issue where 'req' and 'res' in the root of the message need to be referenced, not copied (these are http request and results). Our data would normally be called 'payload' and be in the root of message, but could be msg.payload.img, etc. and there could be multiple in one message. At the end of the index.js in the Simple Repo above, I've made an example Node-Red message as illustration. thanks for your consideration, |
Added to the end of the Simple Repo a http response clone test - the thing that Node-Red manually avoids. |
Hi Paul, what are your thoughts? Simon |
Sorry, was a bit overwhelmed by that header file and regretted that I asked in the first place. So, if I try to run
|
hi paul, hmm... some time since I did this. s |
Hi Paul, I still believe this idea may help in a number of your outstanding issues; e.g. it would enable user workarounds for many of the issues in your issue list, giving them the choice of customising the clone method for chosen objects, even if they have no control over the code where clone is called... best regards, Simon |
replacing with a simpler modification. Watch this space :). |
This commit adds a feature by which if an object has a prototype method _clone(), this method is used to clone that object and all descendants.
Rational:
Currently cloning of an object is done with Object.create().
This does not work for certain objects (specifically node-opencv mat and opencv4nodejs cv.Mat objects).
For any object which does not clone correctly, a user can add a _clone() function and node-clone will then clone to the user's required specification.
Other examples where this is useful:
The _clone() function can do anything the user wants with an object. For example, it could mearly return the original object, or return the original object with a reference count incremented. Or as in the test, the clone could be marked as a clone...
questions: is _clone() as the function name sufficiently 'conflict free'?