Skip to content
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

Support shorthand getter setters ~5 #56

Closed
justinbmeyer opened this issue Aug 31, 2016 · 8 comments
Closed

Support shorthand getter setters ~5 #56

justinbmeyer opened this issue Aug 31, 2016 · 8 comments
Assignees

Comments

@justinbmeyer
Copy link
Contributor

justinbmeyer commented Aug 31, 2016

Example:

Todo.List = can.DefineList.extend({
    "*": Todo,
    get complete(){
            return this.filter({complete: true});
    },
    get active(){
            return this.filter({complete: false});
    },
    get allComplete(){
            return this.length === this.complete.length;
    },
    updateCompleteTo: function(value){
        this.forEach(function(todo){
            todo.complete = value;
            todo.save();
        });
    },
    get saving(){
            return this.filter(function(todo){
                return todo.isSaving();
            });
    }
});
@justinbmeyer justinbmeyer self-assigned this Aug 31, 2016
@justinbmeyer justinbmeyer changed the title Support shorthand getter setters Support shorthand getter setters - P(1) ~5 Aug 31, 2016
@justinbmeyer
Copy link
Contributor Author

justinbmeyer commented Aug 31, 2016

The problem here is that getters in this fashion can't be defined with arguments and setters can only accept one argument.

An alternative would be supporting something like:

Todo.List = can.DefineList.extend({
    "*": Todo,
    "complete get": function(){
            return this.filter({complete: true});
    },
    "active get": function(){
            return this.filter({complete: false});
    },
    "allComplete get": function(){
            return this.length === this.complete.length;
    },
    updateCompleteTo: function(value){
        this.forEach(function(todo){
            todo.complete = value;
            todo.save();
        });
    },
    "saving get": function(){
            return this.filter(function(todo){
                return todo.isSaving();
            });
    }
});

@justinbmeyer justinbmeyer changed the title Support shorthand getter setters - P(1) ~5 Support shorthand getter setters - P(2) ~5 Sep 1, 2016
@justinbmeyer justinbmeyer added the p2 label Sep 1, 2016
@justinbmeyer justinbmeyer changed the title Support shorthand getter setters - P(2) ~5 Support shorthand getter setters ~5 Sep 1, 2016
@justinbmeyer
Copy link
Contributor Author

QUnit.test("getter setters work (#56)", 2, function(){
    var MyMap = define.Constructor({
        first: "string",
        last: "string",
        get fullName() {
            return this.first +" "+ this.last;
        },
        set fullName(newVal) {
            QUnit.ok(true, "setter called");
            var parts = newVal.split(" ");
            this.first = parts[0];
            this.last = parts[1];
        }
    });



    var p = new MyMap({first: "J", last: "M"});


    p.on("fullName", function(ev, newVal){
        QUnit.equal(newVal, "B M");
    });

    p.fullName = "B M";



});

@gsmeets
Copy link

gsmeets commented Sep 2, 2016

The shorthand doesn't add that much value imo.

@justinbmeyer
Copy link
Contributor Author

@gsmeets IMO, it feels awfully repetitive to write:

Todo.List = can.DefineList.extend({
    "*": Todo,
    complete: {
        get: function(){
            return this.filter({complete: true});
        }
    },
    active: {
        get: function(){
            return this.filter({complete: false});
        }
    },
    allComplete: {
        get: function(){
            return this.length === this.complete.length;
        }
    },
    updateCompleteTo: function(value){
        this.forEach(function(todo){
            todo.complete = value;
            todo.save();
        });
    },
    saving: {
        get: function(){
            return this.filter(function(todo){
                return todo.isSaving();
            });
        }
    }
});

2 extra lines (and indentation) per getter. 10 characters saved in the ES5 getter/setter version.

The string version ("something get") could also make defining initial values a bit easier:

{
  "count value": 0
}

@gsmeets
Copy link

gsmeets commented Sep 2, 2016

I think saving a few lines doesn't add up against the possibility of introducing bugs and reducing readability when you can combine the same property on multiple indexers on your viewModel. (Like in your get/set fullName example, but the same applies if you use strings for it.)

If you want to go forward with this I'd at least not allow or warn when you detect multiple uses for the same name. In that case you should be using the full version and not the shorthand imo. Just merging those properties is debugging disasters waiting to happen. But that's just my 2 cts.

If this lands I'd prefer it landing as a plugin. But I can see how that might not be trivial, as it hits a bit on the core of can define.

@justinbmeyer
Copy link
Contributor Author

btw, the compiled formal definitions are always on the Constructor._define in case you need debugging for something like this.

@gsmeets
Copy link

gsmeets commented Sep 2, 2016

I'm just thinking more about my juniors here and the weird issues they can run across. They're full well able to get stuck and wait an hour before asking help. ;)

@justinbmeyer
Copy link
Contributor Author

@gsmeets I appreciate the concern, but after discussing this in the DoneJS Contributors meeting, we felt that the ES5 getter / setter approach was worth it. It's possible someone tries this syntax anyway, and it would be great to support it. As an advanced user, I will use it all the time.

The docs for this will be out soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants