-
Notifications
You must be signed in to change notification settings - Fork 14
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
Move Observable, etc. in liaison and delite/Stateful to decor. #3
Conversation
I have some line-item comments I'll add tomorrow, but I want to discuss the API to Observable itself first. The API doc and test file use Observable as a base class, i.e. calling Relatedly, I think people will be confused that Observable is apparently a base class, yet it has lots of static methods like observe(), getNotifier(), deliverChangeRecords(). So, what I would suggest is one of two paths: (1) Just make Observable a base class, and give it (non-static) methods like getNotifier() used without any arguments i.e. instead of:
users would do:
This is a nice API to use but it won't work if you need to retrofit existing objects to be observable. (2) Match the harmony spec more closely, by removing the The one big deviation from the spec though is having to use |
liaison/Observable as well as the new decor/Observable took the route close to 2) above, which is aligning to standard where possible and makes sense. As @wkeese seems to have noticed, that’s one key reason why most of the key Observable methods are static. Another reason of static methods is enumeration; You may notice that the only non-static method, Observable’s key deviations stem from the nature that Observable is a “container object” (ref), whereas In case it’s not been made clear enough; The confusion @wkeese felt may (in part) stem from the fact that Stateful does not really inherit Observable. This is from my impression that DCL does not care about property descriptors which Observable heavily relies on, and it may be broken by creating inheritances by DCL. But if @uhop or somebody can ensure that it’s not true or provide a roadmap in DCL to support property descriptor we may reconsider here. |
Actually, I'm not confused. What I said was that the API is confusing. So:
|
In case I was not clear enough; Given the main purpose of Observable is for application's data model, instead of just for Also to elaborate on why |
Thanks for your updates. Can you push your updates as separate commits, rather than using push --force, and overwriting your original commit? What you are doing is tantamount to erasing all my (and cjolif's) comments. Turns out the comments are still saved in asudoh@88b88b2#commitcomment-6855378, but they are lost from the PR, and the only way to get to them is if you know the original commit hash. |
OK from now on I’ll squash after review completes. |
I see you're a big fan of making variables super-private, i.e. private to a specific function definition, by using IEF's. We don't generally do that in ibm-js, so I'm wondering what @cjolif etc. think about this. I see the reason you do it, but personally I don't think it's worth having the extra code and indentation. I'm seeing six IEF closures in your code that I think should be simplified: (1) var observableMarker = "_observable" You have a closure to define an
If you just hardcode _observable ( (2) For defining defineProperty(Observable.prototype, "set", { // Make set() not enumerable
value: (function () {
var areSameValues = has("object-is-api") ? Object.is : function (lhs, rhs) { ...
return function (name, value) {... };
})(), It could be written more simply as:
(3) In the main part of the code you have three level of IEF's. (function () {
var seq = 0, ...;
Observable.getNotifier = (function () {
function Notifier(target) { ... }
Notifier.prototype = {
notify: (function () {
function enqueue(changeRecord) { ... }
return function (changeRecord) { ... };
})(),
...
};
return function (observable) { ... };
})();
Observable.observe = (function () {
var DEFAULT_ACCEPT_CHANGETYPES = ...; // Observable#set() only supports the first two
return function (observable, callback, accept) { ... };
})();
...
})(); For the
instead of:
As for the other levels of nesting, they are just to hide variables within a certain section of the file, which I can see the merit of, but it doesn't seem very important, so my preference is to save a few bytes by just using comments in the code like:
or something like that. |
@cjolif I think it's your call here? |
Sorry, you go too fast for me guys to keep up ;) I guess I'm more or less in agreement with @wkeese here. In theory I do like the idea of scoping variables to the more limited scope and I understand why you are doing that, however, adding this piece of code is already none negligibly adding to the size of decore/delite and we also need to keep in mind we don't want to be "too big", so any effort we can do to reduce the code size while still keeping it correct is important I think. Also there is the consistency issue as indeed other part of the code are not heavily relying on those techniques and mixed style does not facilitated reading and maintaining the code. In summary I guess yes it would make sense to have some level of simplification here. |
OK made the change: asudoh@6ad17b3 |
This is looking good to me now. The only outstanding thing I see is the duplicated |
Thanks @wkeese for the thorough review. Introduced |
For ibm-js/delite#178.