Brett's Blog
Edit     New

Saturday, February 21, 2009

Further Relator enhancements

Here are two other useful Relator methods:


constructor : function (that) {
this.set(that);
return this.get(that); // Assign to var _ = __.constructor(this);
},
method : function (that) { // Alias for get()
return this.get(that); // Assign to var _ = __.method(this);
},


Now we can just do this to get our private variables:

var Constructor = function () {var __ = Relator.$(); // We use two underscores here (doing it for brevity, as we may use this often)
function Constructor (doc) {var _ = __.constructor(this); // Set up and gets private access
// ...
}
Constructor.prototype = {
constructor : Constructor,
someMethod : function () {var _ = __.method(this); // Gets private access
// ...
}
};
return Constructor;
})();

Friday, February 20, 2009

Subobjects

While I'd guess that the following might be called private classes (though they seem different from those defined at Wikipedia), I don't know what the objects created to function inside of another object would be called. This is not mere namespacing because the subobject (I'm hesitant to call them child/parent objects in order to avoid confusion with subclasses) has access to the superobject as well as to its own methods and properties. If anyone can help with terminology, let me know.

But anyways, I just wanted to point out, if this wasn't already a readily familiar pattern, that there is a way to define private classes which can be instantiated within another class object, while having access to its own methods and properties (including instance ones, and private ones if we wish), as well as those of the object above it.


var Constructor = function () {
var _PrivateClass1Closure = function () {var top = this;
function PrivateClass1 () {
this.myProperty=4;
}
PrivateClass1.prototype.callTopMethod = function () {
alert('My own myProperty is '+this.myProperty+', while the object above me has someProperty equal to '+top.constructorMethod()); // We can also get the latter value by top.someProperty
};
return PrivateClass1;
}; // Don't instantiate this closure yet

function Constructor () {
var _PrivateClass1 = _PrivateClass1Closure.call(this); // Let the closure have access to this context when generating the private class, so that its objects (the subobject below) can call the instance methods and properties of this nesting Constructor
this.subObject = new _PrivateClass1();
this.someProperty = 5;
}
Constructor.prototype.constructorMethod = function () {return this.someProperty;};
return Constructor;
}();

var obj = new Constructor();
obj.subObject.callTopMethod(); // My own myProperty is 4, while the object above me has someProperty equal to 5
alert(obj.constructorMethod()); // 5

Thursday, February 19, 2009

Enhancing Relator and Extending Classes using Relator for private instance variables

One addition to my previous blog post...

These two methods on the Relator could be interesting:

getAll: function () { // Be able to read or manipulate ALL instances within any instance (kind of violates privacy, but offers what I call the "Borg" option)
return Array;
},
readonly : function (obj) { // Call, especially from an extending class, to get access to the original class' private/protected variables without fear of manipulating them
var newObj = {};
for (var i in Array[Stack.indexOf(obj)]) {
newObj[i] = Array[Stack.indexOf(obj)][i];
}
return newObj;
// ...OR...
// return function (value) {return Array[Stack.indexOf(obj)][value];} // copies of scalars, not references
},


Then your extending class could look something like this (the following also demonstrates protected variables and extending classes):


var ExtClass = (function (ParentClass) { // We pass in the parent class as an argument, so we can copy-paste the rest of the code, always using "ParentClass" in the closure.

// var _extendedPrivate = Relator.$(); // we could define our own set of private variables for this extended class to,

function ExtClass (){
ParentClass.call(this); // We have to call the parent constructor in order to extend the class in a way that its public methods operating on private variables there still work--if you still want a constructor in the base class with side effects not triggered by extending classes, put a conditional in the constructor and pass in (or don't pass in) a certain argument or type of argument to avoid the rest of the set-up besides the necessary line "_private.set(this);".
/* We could also define and use private variables for just inside this extending class
_extendedPrivate.set(this);var _ = _extendedPrivate.get(this);
_.extendedPrivateVar = 5;
*/
var _protect = _private.get(this); // Let's us use the "private" variables from the base class here too (note that "_private" must be accessible somehow for us to do this--either this extending class should be defined in the same closure as the base class (more like protected access since the extending class CAN access the variables if it wishes), or it could be passed in as an argument/a global (more like a public variable since public code could also access it)
_protect.privateInstanceVar = 7; // We can manipulate a private instance set up in the base class (the private become protected when we access them this way)
var _readonly = _private.readonly(this); // allows read-only protected access of the private variables in the base class
alert(_readonly.privateInstanceVar); // Gets base class' privateInstanceVar but won't be able to set it (except as a copy here)
// alert(_readonly('protectedInstanceVar')); // Or using the "return function" approach commented out in readonly() to do the same
}
ExtClass.prototype = new ParentClass; // ParentClass also gets called here (again, you can use a conditional in the parent class to avoid repeating any unnecessary set-up code)
ExtClass.prototype.constructor = ExtClass;

return ExtClass;

})(MyClass); // Just need to add specific base class here, then use the generic code above

True Private Instance Variables in JavaScript Without Any Public Properties

As a follow-up to my article on True Private Instance Variables, I've since discovered Andrea Giammarchi's fully private technique which also works across the constructor and prototype methods and has the benefits of not creating separate privileged functions on each instantiation, but which does not create any public properties at all.

His latest code is available here.

Here's my own slightly cleaned up version (basically just fixed/added some brackets, semi-colons, and usage notes):


// Used for giving privacy
var Relator = function () {
// Code from http://www.devpro.it/code/192.html
// Relator explained at http://webreflection.blogspot.com/2008/07/javascript-relator-object-aka.html
// Its use as privacy technique described at http://webreflection.blogspot.com/2008/10/new-relator-object-plus-unshared.html
// 1) At top of closure, put: var _private = Relator.$();
// 2) In constructor, put: _private.set(this);var _ = _private.get(this);
// 3) At top of each prototype method, put: var _ = _private.get(this);
// 4) Use like: _.privateVar = 5;
//
// ******************************************
// (c) Andrea Giammarchi - Mit Style License
// ******************************************
// Relator.set(123).description = "Number 123";
// Relator.get(123).description; // Number 123
// Relator.len(); // 1
// Relator.del(123).len(); // 0
// Relator.set("abc"); // object Object
// Relator.len(); // 1
// var anotherRelator = Relator.$();
// anotherRelator.len(); // 0
// Relator.get("abc"); // object Object
// anotherRelator.get("abc"); // undefined
// ******************************************
function indexOf (value) {
for (var i = 0, length=this.length; i < length; i++) {
if (this[i] === value) {
return i;
}
}
return -1;
}
function Relator () {
var Stack = [], Array = [];
if (!Stack.indexOf) {
Stack.indexOf = indexOf;
}
return {
// create a new relator
$ : function () {
return Relator();
},
// remove a referenced object
del: function (value) {
var i = Stack.indexOf(value);
if (~i) {
Stack.splice(i, 1);
Array.splice(i, 1);
}
return this;
},
// get a referenced object, if any, or undefined
get: function (value) {
return Array[Stack.indexOf(value)];
},
// return total number of referenced objects
len: function () {
return Stack.length;
},
// set a reference for a generic object, if it is not present
set: function (value) {
var i = Stack.indexOf(value);
return ~i ? Array[i] : Array[Stack.push(value) - 1] = {};
}
};
}
return Relator();
}();


What follows is an example of a closure creating a class and using the Relator for private variables. Note that if you don't even want to introduce the above Relator object/class into the global namespace (say if you are distributing your class as part of a library), you can just add it at within the closure creating your class at the very top of the closure (instead of just calling it, as I do below).

Note that in my example, I put the boring repetitive code at the very top of each function, right after the bracket, as I find this lets one focus on the main logic of one's class, without getting distracted by the private instance variable set-up code (and also makes it easy for me to find the code for pasting into other methods or classes).

I've also stuffed the code with comments to demonstrate where all of the other types of common variable and method types could go



var MyClass = (function () {

// Put Relator class here if you don't want it to be public (but it is VERY useful to have available without putting it inside of each class)

var _private = Relator.$(); // At top of each closure where private variables are needed, put this for set up (in combination with set() call at top of constructor below

// Note that you can also put private static variables and methods here, or private instance methods (which are really private static methods to which 'this' is passed in methods below; e.g., myPrivMethod.call(this, arg1, arg2);)

function Constructor () { var _ = _private.set(this); // At top of each constructor
_.privateInstanceVar = 3; // You can now define and use private variables in the constructor (just put the desired variable name after "_."
// _.privateInstanceMethod = function () {}; // You could even make private instance methods dynamically which could be available throughout the methods
// this.publicInstanceVar = ... ; // You can use public instance variables
// this.privilegedMethod = ... ; // If you actually want a privileged method
}
Constructor.prototype.somePublicMethod = function () {var _ = _private.get(this); // At top of each prototype method needing to use private variables, so you can define and use private variables here too
_.anotherPrivateVar = 5;
alert('My first private variable is '+_.privateInstanceVar+' and my new one is '+_.anotherPrivateVar);
};
// Constructor.prototype.someVariable = 5; // Default public variables (which can be overridden by instance or changed for all instances)
// Constructor.publicStaticMethod = function () {}; // You can put public static methods here
// Constructor.publicStaticVariable = 5; // You can put public static variables here
// var consts= {'myconst':5}; Constructor.getConstant = function (name) {return consts[name];}; // Define public static method to get public static constants; MyClass.getConstant('myconst');
// Constructor.__defineGetter__('myconst', function(){return 5;}); // or, to get Class constants in format MyClass.myconst (Mozilla only)
return Constructor;

})();

var myObj = new MyClass();
myObj.somePublicMethod(); // My first private variable is 3 and my new one is 5
alert(myObj.privateInstanceVar); // undefined


The only advantage my earlier version offers (if you can call it that), is that, you don't need the Relator class, and it doesn't involve function calls. However, the fact that you don't need ANY public variables (even just counter ones) to get private variables makes this approach highly worthwhile.

Finally, JavaScript now can have genuine private instance variables (at least a valid equivalent) without too much pain. [Additional note: With extending the class, you can do so if you're willing to call the parent constructor (you already have to do so at least once when creating the prototype for classical inheritance).]

Tuesday, February 17, 2009

Monopolism in viral licenses?

Expanding a little on my last post...

I'm just posing the following for the sake of argument...

If you believe that there should be no laws requiring code to be open source (except perhaps for government contracts, etc.)--i.e., that people should not be compelled to release source code--then, what about the ethics of a future (or even present-day) society in which virally licensed code like the GPL could effectively become the monopoly? I mean, if you consider it a freedom to be able to keep your code closed (even if you do not wish to exercise that right), then might it not also be an impingement on that freedom if the ubiquity of GPL code makes it non-competitive for you or others to compete against it with your own closed source code? Isn't that a monopoly, when one cannot effectively compete--the competition is too well established (and far along)? With permissive licenses, public domain, etc., you can at least build on them in a closed source way...

Anyhow, I'm certainly not against the GPL for those who choose to release their projects under it (I have myself), but I think it is worth asking... If compared in the light of a potential monopoly (whenever such code does take over the playing field in a given area), might the state ever seek--as they do in allowing copyright to expire or potentially appropriating (or is it expropriating?) patents--to revoke GPL code for the supposed "common good" (e.g., to force the code into the public domain--or, as with nationalization of former monopolies, expropriate its rights solely to itself)?

Thoughts?

Incidentally, there is a passage in the Bahá'í Writings which states:

"And among the teachings of Bahá'u'lláh is voluntary sharing of one's property with others among mankind. This voluntary sharing is greater than equality, and consists in this, that man should not prefer himself to others, but rather should sacrifice his life and property for others. But this should not be introduced by coercion so that it becomes a law and man is compelled to follow it. Nay, rather, man should voluntarily and of his own choice sacrifice his property and life for others, and spend willingly for the poor, just as is done in Persia among the Bahá'ís."

('Abdu'l-Bahá, Selections from the Writings of 'Abdu'l-Bahá)

(See also a similar quotation in the same work on page 115)

Clearly, our Writings advise against being fully compelled by the law of the government to equalize wealth completely (in other passages also), but the GPL is a license entered into voluntarily, as can be copyright--not a law mandated by the government (besides advising against it, the Baha'i Writings argued that communism could not work, though arguing that compulsory laws (progressive taxes) should be made for redistribution to remedy the extremes of wealth, and justified the non-compulsory, but spiritually obligatory religious laws mandating of the sharing of wealth in the Baha'i Faith (presumably 'Abdu'l-Baha is referring here to the Baha'i law of Huququ'llah). The issue I am raising is not whether GPL is ethical (because I think it can be), but whether it could become effectively monopolistic in certain areas, and thus within the domain of government to break it up. (By the way, I'm bringing in the above religious quotation for the sake of discussion and to indicate part of my own angle, not to impose the religious belief on others--the subject is inherently more tricky though when we talk about imposing the right to impose restrictions, and even more so when the restrictions are themselves meant to guarantee freedoms for all. Also, please note that I didn't use the quotation for justifying a specific position--only the Universal House of Justice can indicate the applicability of the Baha'i Writings in an official capacity.)

Timing the addition of permissive licensing

There has been a lot of debate on the ethics of copycenter (permissive like BSD, MIT, or Apache) vs. copyleft (e.g., viral licenses like the GPL).

Of course, it's a matter of choice, as well explained, I think, in this article. (The article raises another separate question for me as to there were a nearly completely permissive license which allowed inclusion in closed source works, but which virally prohibited Digital Rights Management or being used on hardware restricting access to code--not sure if that makes sense...I'm also unclear on whether GPL3 prohibits use on machines that use DRM at all or only if the GPL3 code itself (and its derivatives) must be accessible. And while I'm posing questions, I also need to find out whether GPL3 as opposed to GPL2 allows requiring attribution in the original or derivative works--I'm personally not a fan of attribution in truly open projects, as it can become cumbersome ("How many people do I have to list here??") or effectively non-free (if you're a company) to have to do so. And if one contributes to an open-source project, to retain the copyright on one's own contributions, is it really necessary to list "copyright 2009", etc.? Ok, on with the post, Brett...)

Anyhow, strictly from an altruistic point of view, my current thoughts are as follows. (p.s. IANAL--I am not a lawyer, so nothing here constitutes legal advice)

If the project is such that a vendor could end up hijacking it, or if you feel it really needs contributions from vendors, then a viral license (including the lesser GPL) might work. But... unless you are philosophically opposed to closed source (which is not necessarily what those who use copyleft licenses automatically are), you might arguably be helping the development of society along if you released under a more permissive license--once your own project reached sufficient maturity.

For example, I'm thinking that if the PHP.JS had been under a copyleft license originally (it is under MIT), once the PHP.JS project manages to implement the bulk of the functions, although no doubt the implementations can continue to improve, it would be less of a concern that the project could be hijacked, and if code improvements needed to be made to the library itself by a closed source project, they could still do so.

Granted, you might argue that society would be better served if companies lost all incentives to close the source, due to viral licenses taking over, so, according to such a position, viral licenses are more helpful to society even if it means a company cannot bring a cool idea into fruition, since they might feel forced to find closed source incentives elsewhere. I think there may be a difference here as to whether we are talking about code which can turn into a whole infrastructure (e.g., Apple proved they could run with BSD, and if they had or would become a monopoly, it could cause trouble for others), or whether it is just part of the infrastructure.

For example, if toll roads were ubiquitous, that could really impact our freedom (though, it may be arguable that allowing some such roads (perhaps with a time limit on their exclusive rights--like copyright expiration) ensures they are better maintained and provide useful access routes, etc., and also don't burden tax payers who do not use such roads). However, it may be less clear in certain cases. For example, a browser also provides a kind of infrastructure, even though it is not as fundamental as the operating system. In any case, I think that closed file formats are worse for interoperability, no matter how critical (though I guess some might argue closed file formats are themselves potential innovations).

One possibility which I'm not sure has been raised (no doubt somewhere it has), is the approach of starting out with a copyleft license, and explicitly informing would-be contributors that the code can be dual-licensed at some future point (assuming the contributors hand over copyright, so other developers' contributions can indeed escape GPL viral issues in the future) under a more permissive license, assuming certain conditions were first met (e.g., that all functions would have some agreeable implementation). Perhaps the original developer could write an agreement indicating that they would not use the code given to them under any license besides the current copyleft one, until such time as they might feel the conditions were met to publish under the permissive license--at which point the original developer would need to fully publish all such contributions in order to himself/herself begin to freely use the contents of the permissive license which were based on others' submissions (and of course others could then use the contents of the permissively-licensed code as well).

I would think that the above approach might invite more contributions--and even more fast-paced contributions, at least among those who were serious to contribute. The closed-source developers would at least have SOME incentive to help out, as they might not if the code were in the beginning under a permissive license or if there was no indication that the license could ever be made permissive.

In any case, I think it is helpful to distinguish between different incentives and different approaches, to consider idealistic ethics or practical concerns, rather than lumping them together. However, I also agree with Bruce Perens' point (in the article cited above), that having too many choices can also be a burden (for the developer). Although the arguments about GPL3 dealing with later legal issues are persuasive (I'm still unclear on the DRM issue however, as per the question I posed above), I am concerned that the GPL itself (whose licenses are mutually incompatible) can cause a proliferation of licenses (if there can be a GPL3, then there may well be a mutually incompatible GPL4).

Heck, maybe the FSF should just make a version of GPL which states that it is an auto-updating license which automatically subjects itself to future versions of the GPL as soon as publicly available! If we all do start using the GPL3, it really can be a pain not to have access to all of the work done by others in GPL2. What if some company writes their code in some manner, that when exposed to air (as might happen when trying to open an embedded device), it vanishes. While the GPL3 does insist on "durable physical medium" when releasing the code by conveying "the object code in, or embodied in, a physical product", maybe "durable" can be twisted by the right lawyers. Anyways, this is just an example, but I don't think we can guarantee that GPL3 is the last license from FSF forever (assuming you think theirs is the best viral license). [Update: I see that this eventuality of a changing license was, as I should have imagined, already anticipated. Suggestions are given at http://www.gnu.org/licenses/rms-why-gplv3.html for releasing under "GPL version 3 or any later version" or assigning a proxy to be able to make decisions about later versions.]


Google
 
Brett's Blog Web