Private Variables Mutators for Class

Wednesday, January 21st, 2009 @ 12:01 pm | filed under: Code Releases, MooTools

A while back Nathan White posted a Class Mutator for private variables that let you do this sort of thing:

var Secret = new Class({
	Privates : {
		secret : 'hidden message',
		myFunc : function(){  return this.getSecret(); }
	},

	getSecret : function(){
		return secret;
	},

	get : function(){
		return myFunc();
	}
});

var msg = new Secret();
msg.get(); // returns "hidden message"
msg.Privates.secret; // returns undefined

Yesterday Sean McArthur posted a follow up that addresses some concerns he had. Here’s an example of it’s usage:

var Secret = new Class({
	Implements: [Options, Events],
	Privates: {
		secret: 'shhhh'
	},
	open: null,
	initialize: function(word) {
		this.secret = word;
		this.open = 'not a secret';
	},
	getSecret: function() {
		return this.secret;
	},
	setSecret: function(newWord) {
		this.secret = newWord;
		this.notSecret = 'im a new prop in this';
	},
	getOpen: function() {
		return this.open;
	}
});

I haven’t really dug into either solution so I can’t say which one I prefer, but it’s nice work regardless.

10 Responses to “Private Variables Mutators for Class”

  1. Nick Carter Says:

    I only read Crockford’s ideas on private properties/accessors within the past year, but they’re definitely a cool idea for large projects. Haven’t used em so far, though I might start for JazzRecord as I don’t consider my internal code “safe” for external use since it’s not tested for that.

    Not sure I understand how the second example uses true private variables, it looks like it has getters/setters but they just muck with this.prop which is not a private variable of course.

    I’d say optimally we wouldn’t have to write getters/setters manually but would be able to optionally.

  2. Sean McArthur Says:

    In the second example, the Privates mutator has allowed you access the “private” variables from the this object only inside functions. Outside, you could never access the “private” variables.

    getters/setters are a standard practice in programming in an OO language. Automatic getter/setters would remove the purpose of making them private. By writing your own, you determine what values can be “gotten”, and if you make a setter, you could add some logic that will make sure only values you approve get set to the private variable. You can easily have private variables you don’t want to make a getter for, and/or not want a setter to exist so the private variable doesn’t get changed from outside.

  3. Nick Carter Says:

    Hi, Sean. I’m afraid I didn’t follow the actual link to your blog, and so didn’t get to see any context with the example earlier. The Privates code, while far more complicated than some of the ways of implementing privates outside of Moo classes, seems pretty darn cool for doing what it does. And, of course, implementing Privates in a Moo class is actually simpler (or at least more pleasing to the eye) than the non-Moo way of doing it.

    It’s a shame there’s not a way of setting of private vars naturally (via keyword or similar) and that cycles have to be wasted in the constructor, but unless you’re setting up loads of data/code I guess it’s a non-issue.

    I s’pose the auto getters/setters wouldn’t make much sense.

  4. thomasd Says:

    “It’s a shame there’s not a way of setting of private vars naturally (via keyword or similar) and that cycles have to be wasted in the constructor, but unless you’re setting up loads of data/code I guess it’s a non-issue.”
    What’s really a shame is that ‘private’ is a reserved keyword in javascript, but not used. (Like many others, I know).

    Based on the ideas of Sean McArthur, Nathan White and Douglas Crockford, I coded my own solution to the problem.

  5. Balazs Endresz Says:

    Hi, I’ve just started using Mootools but that first example looks really wrong for me. There’s no way you can reference a variable in another object like that unless it’s defined in an outer function or in the global scope. Or am I missing something?

    And why don’t you just use a closure? Really, I’m curious.

    var Secret = new Class( (function(){
    var secret = 'hidden message';
    return {
    getSecret : function(){
    return secret;
    }
    }
    })() );
    var msg = new Secret();
    msg.getSecret();

  6. Aaron N. Says:

    Perhaps Nathan or Sean could answer this question, as I haven’t really dug into their code. You might also post this to their blogs if you want an answer for sure.

  7. Sean McArthur Says:

    @Balazs

    That’s exactly why I wrote my version. That example works because secret was being attached to the global object, just like you said.

    About the closure, that’s what I used to accomplish it. That, and some fun binding inside the closure function.

  8. Balazs Endresz Says:

    @Sean: I’ve just noticed your comment on Nathan White’s blog calling it a “slight bug” but then it’s apparently a very serious one, isn’t it?

    And I just don’t know why should I use a mutator if I can get the same effect more efficiently with plain javascript? Is there anything that makes it more useful over using a single closure as in my exemple above?

    Anyway, it’s a very interesting implementation, one can rarely see such trickery in other languages :)

  9. Sean McArthur Says:

    The efficiency difference is negligible in all but extreme cases. But what the Mutator gives you:

    It lets you write a class in Mootools normally, following the pattern of Mootools Classes, and only have to write a Privates obj as one of its properties, and therefore have private variables.

    Your way, which would work, looks very different than most Mootools classes, and so loses some of the style. Sure, someone well versed in Javascript would understand it. But using the Mutator keeps the style of all the other classes you would write using Mootools. And style matters.

  10. Balazs Endresz Says:

    In that respect I can agree with you, I didn’t even think about that, I’ve got used to writing such constructs too much.